Bullets no longer collide with wielder.

Added new Event "OnBulletCollide" use this event to handle bullet damage effects etc.
This commit is contained in:
Ethan Adams 2024-06-21 22:16:05 -04:00
parent 5b4816ec32
commit 6164458aa7
11 changed files with 65 additions and 23 deletions

View file

@ -6,13 +6,13 @@ find_package(SDL2 REQUIRED)
find_package(SDL2_IMAGE REQUIRED) find_package(SDL2_IMAGE REQUIRED)
include_directories(SYSTEM "c:/sdks/glad/include") include_directories(SYSTEM "c:/sdks/glad/include")
include_directories(SYSTEM "c:/sdks/tinyxml2-10.0.0/include") include_directories(SYSTEM "c:/sdks/tinyxml2-10.0.0/debug/include")
include_directories(SYSTEM "c:/sdks/glm") include_directories(SYSTEM "c:/sdks/glm")
include_directories(SYSTEM "C:/sdks/sol2-3.3.0/single/single/include") include_directories(SYSTEM "C:/sdks/sol2-3.3.0/single/single/include")
include_directories(SYSTEM "c:/sdks/lua-5.4.6/include") include_directories(SYSTEM "c:/sdks/lua-5.4.6/include")
include_directories(SYSTEM "C:/sdks/freetype-2.13.2/include") include_directories(SYSTEM "C:/sdks/freetype-2.13.2/include")
link_directories(SYSTEM "C:/sdks/freetype-2.13.2/objs") link_directories(SYSTEM "C:/sdks/freetype-2.13.2/objs")
link_directories(SYSTEM "c:/sdks/tinyxml2-10.0.0/lib") link_directories(SYSTEM "c:/sdks/tinyxml2-10.0.0/debug/lib")
link_directories(SYSTEM "c:/sdks/lua-5.4.6/lib") link_directories(SYSTEM "c:/sdks/lua-5.4.6/lib")
include_directories(${PROJECT_SOURCE_DIR}/YupplyMayham/gameplay) include_directories(${PROJECT_SOURCE_DIR}/YupplyMayham/gameplay)

View file

@ -9,6 +9,8 @@ class EventManager;
struct PhysicsComponent { struct PhysicsComponent {
bool isBullet = false; bool isBullet = false;
// This ID holds the ID of the gameactor that owns this object, that being themselves or a bullet.
unsigned int ID = 0; // If the ID stays 0 then that object has no owner and will be uncollidable
struct RigidBody { struct RigidBody {
glm::vec3 position; glm::vec3 position;
glm::vec3 velocity; glm::vec3 velocity;
@ -29,8 +31,9 @@ struct PhysicsComponent {
class PhysicsComponentFactory { class PhysicsComponentFactory {
public: public:
static PhysicsComponent makeBullet(const glm::vec3& pos, float mass, float radius) { static PhysicsComponent makeBullet(const unsigned int ID, const glm::vec3& pos, float mass, float radius) {
PhysicsComponent p; PhysicsComponent p;
p.ID = ID;
p.rigidBody.position = pos; p.rigidBody.position = pos;
p.rigidBody.mass = mass; p.rigidBody.mass = mass;
p.collider = { PhysicsComponent::Collider::Shape::Circle, glm::vec3(radius, radius, 0.f), glm::vec3(radius) }; p.collider = { PhysicsComponent::Collider::Shape::Circle, glm::vec3(radius, radius, 0.f), glm::vec3(radius) };
@ -43,9 +46,11 @@ class PhysicsEngine {
public: public:
PhysicsEngine() {} PhysicsEngine() {}
using CollisionPair = std::pair<PhysicsComponent*, PhysicsComponent*>;
void hookEventManager(const std::shared_ptr<EventManager>& eventManager); void hookEventManager(const std::shared_ptr<EventManager>& eventManager);
std::shared_ptr<PhysicsComponent> createObject(const glm::vec3& pos, float mass, PhysicsComponent::Collider::Shape shape, glm::vec3 dimensions, glm::vec3 offset = glm::vec3(0.f)); std::shared_ptr<PhysicsComponent> createObject(const unsigned int ID, const glm::vec3& pos, float mass, PhysicsComponent::Collider::Shape shape, glm::vec3 dimensions, glm::vec3 offset = glm::vec3(0.f));
void loadCollisionMap(const std::vector<std::vector<int>>&, float tileSize); void loadCollisionMap(const std::vector<std::vector<int>>&, float tileSize);
void addObject(const std::shared_ptr<PhysicsComponent>&); void addObject(const std::shared_ptr<PhysicsComponent>&);
void removeObject(const std::shared_ptr<PhysicsComponent>&); void removeObject(const std::shared_ptr<PhysicsComponent>&);
@ -56,7 +61,7 @@ private:
void getPossibleCollisions(); void getPossibleCollisions();
int getTileCollider(const glm::vec3& position); int getTileCollider(const glm::vec3& position);
std::vector<std::shared_ptr<PhysicsComponent>> objects; std::vector<std::shared_ptr<PhysicsComponent>> objects;
std::vector<std::pair<PhysicsComponent*, PhysicsComponent*>> objCollisions; std::vector<CollisionPair> objCollisions;
std::vector<std::vector<int>> collisionMap; std::vector<std::vector<int>> collisionMap;
float tileSize = 32.f; float tileSize = 32.f;
std::shared_ptr<EventManager> eventManager; std::shared_ptr<EventManager> eventManager;

View file

@ -10,15 +10,26 @@ class Camera;
class Bullet : public Entity class Bullet : public Entity
{ {
public: public:
Bullet(std::shared_ptr<Shader> shader, glm::vec3 fireFrom, glm::vec2 direction, float bulletSpeed, float bulletDrop, glm::vec2 bulletSize) : Bullet
(
const unsigned int owner,
std::shared_ptr<Shader> shader,
glm::vec3 fireFrom,
glm::vec2 direction,
float bulletSpeed,
float bulletDrop,
glm::vec2 bulletSize
) :
Entity(shader), Entity(shader),
origin(fireFrom), origin(fireFrom),
direction(direction), direction(direction),
bulletSpeed(bulletSpeed), bulletSpeed(bulletSpeed),
bulletDrop(bulletDrop), bulletDrop(bulletDrop),
bulletSize(bulletSize) { bulletSize(bulletSize)
{
this->setPosition(origin); this->setPosition(origin);
this->setScale(glm::vec3(bulletSize, 1.0f)); this->setScale(glm::vec3(bulletSize, 1.0f));
ownerid = owner;
}; };
void addComponent(std::shared_ptr<Component> component); void addComponent(std::shared_ptr<Component> component);
@ -32,6 +43,7 @@ public:
~Bullet(); ~Bullet();
private: private:
unsigned int ownerid;
glm::vec3 origin; glm::vec3 origin;
glm::vec2 direction; glm::vec2 direction;
float bulletSpeed; float bulletSpeed;

View file

@ -16,7 +16,8 @@ class BulletManager
{ {
public: public:
void addBullet(const std::shared_ptr<Bullet>& bullet); void addBullet(const std::shared_ptr<Bullet>& bullet);
void addBullet(const glm::vec3& fireFrom, void addBullet(const unsigned int owner,
const glm::vec3& fireFrom,
const glm::vec2& direction, const glm::vec2& direction,
float bulletSpeed, float bulletSpeed,
float bulletDrop, float bulletDrop,

View file

@ -18,6 +18,7 @@ class Camera;
class BulletManager; class BulletManager;
class EventManager; class EventManager;
class ResourceManager; class ResourceManager;
class GameActor;
struct WeaponData; struct WeaponData;
class Weapon : public Entity class Weapon : public Entity
@ -25,7 +26,7 @@ class Weapon : public Entity
public: public:
Weapon(const WeaponData* data, const std::shared_ptr<Shader>& weaponShader, const std::shared_ptr<Shader>& bulletShader, ResourceManager* resourceManager); Weapon(const WeaponData* data, const std::shared_ptr<Shader>& weaponShader, const std::shared_ptr<Shader>& bulletShader, ResourceManager* resourceManager);
void setWielder(Entity* wielder) { this->wielder = wielder; } void setWielder(const std::shared_ptr<GameActor>& wielder) { this->wielder = wielder; }
void addComponent(const std::shared_ptr<Component>& component); void addComponent(const std::shared_ptr<Component>& component);
void hookEventManager(const std::shared_ptr<EventManager>& eventManager); void hookEventManager(const std::shared_ptr<EventManager>& eventManager);
@ -49,7 +50,8 @@ private:
std::shared_ptr<UTIL::RandomGenerator> bulletSpread; std::shared_ptr<UTIL::RandomGenerator> bulletSpread;
std::shared_ptr<UTIL::RandomGenerator> bulletModifer; std::shared_ptr<UTIL::RandomGenerator> bulletModifer;
Entity* wielder = nullptr;
std::shared_ptr<GameActor> wielder;
int lastFireTime = 0; int lastFireTime = 0;
Direction lastDir; Direction lastDir;

View file

@ -23,7 +23,7 @@ void GameActor::equipWeapon(std::shared_ptr<Weapon> weapon)
{ {
currentWeapon = std::move(weapon); currentWeapon = std::move(weapon);
if (currentWeapon) if (currentWeapon)
currentWeapon->setWielder(this); currentWeapon->setWielder(std::shared_ptr<GameActor>(this));
} }
void GameActor::attachEventManager(std::shared_ptr<EventManager> eventManager) void GameActor::attachEventManager(std::shared_ptr<EventManager> eventManager)

View file

@ -17,9 +17,15 @@ void PhysicsEngine::hookEventManager(const std::shared_ptr<EventManager>& eventM
}); });
} }
std::shared_ptr<PhysicsComponent> PhysicsEngine::createObject(const glm::vec3& pos, float mass, PhysicsComponent::Collider::Shape shape, glm::vec3 dimensions, glm::vec3 offset) std::shared_ptr<PhysicsComponent> PhysicsEngine::createObject(const unsigned int ID,
const glm::vec3& pos,
float mass,
PhysicsComponent::Collider::Shape shape,
glm::vec3 dimensions,
glm::vec3 offset)
{ {
auto component = std::make_shared <PhysicsComponent>(); auto component = std::make_shared <PhysicsComponent>();
component->ID = ID;
component->rigidBody.position = pos; component->rigidBody.position = pos;
component->rigidBody.mass = mass; component->rigidBody.mass = mass;
component->collider.shape = shape; component->collider.shape = shape;
@ -69,7 +75,7 @@ void PhysicsEngine::getPossibleCollisions()
for (size_t j = i + 1; j < objects.size(); ++j) for (size_t j = i + 1; j < objects.size(); ++j)
{ {
auto& colliderObj = objects[j]; auto& colliderObj = objects[j];
if (obj.get() == colliderObj.get()) continue; if (obj.get() == colliderObj.get() || obj->ID == colliderObj->ID) continue;
float colliderRight = colliderObj->rigidBody.position.x + colliderObj->collider.dimensions.x; float colliderRight = colliderObj->rigidBody.position.x + colliderObj->collider.dimensions.x;
float colliderBottom = colliderObj->rigidBody.position.y + colliderObj->collider.dimensions.y; float colliderBottom = colliderObj->rigidBody.position.y + colliderObj->collider.dimensions.y;
float objectRight = obj->rigidBody.position.x + obj->collider.dimensions.x; float objectRight = obj->rigidBody.position.x + obj->collider.dimensions.x;
@ -78,7 +84,7 @@ void PhysicsEngine::getPossibleCollisions()
objectRight >= colliderObj->rigidBody.position.x) || objectRight >= colliderObj->rigidBody.position.x) ||
(obj->rigidBody.position.y <= colliderBottom && (obj->rigidBody.position.y <= colliderBottom &&
objectBottom >= colliderObj->rigidBody.position.y)) objectBottom >= colliderObj->rigidBody.position.y))
objCollisions.push_back(std::make_pair(obj.get(), colliderObj.get())); objCollisions.push_back(CollisionPair(obj.get(), colliderObj.get()));
} }
} }
} }
@ -95,6 +101,15 @@ void PhysicsEngine::resolvePossibleCollisions()
if (glm::length(distance) < sumOfRadius) if (glm::length(distance) < sumOfRadius)
{ {
// We got impact! // We got impact!
// That impact is a bullet hitting a gameactor!
if (objs.first->isBullet || objs.second->isBullet && !(objs.first->isBullet && objs.second->isBullet))
{
eventManager->notify(std::make_shared<BulletCollideEvent>(
(objs.first->isBullet) ? objs.first->ID : objs.second->ID,
(!objs.first->isBullet) ? objs.first->ID : objs.second->ID
));
}
// Apply impulse force
glm::vec3 normal = distance / glm::length(distance); glm::vec3 normal = distance / glm::length(distance);
float penetrationDepth = sumOfRadius - glm::length(distance); float penetrationDepth = sumOfRadius - glm::length(distance);
glm::vec3 correctionVector = normal * (penetrationDepth / ((1 / objs.first->rigidBody.mass) + (1 / objs.second->rigidBody.mass))); glm::vec3 correctionVector = normal * (penetrationDepth / ((1 / objs.first->rigidBody.mass) + (1 / objs.second->rigidBody.mass)));
@ -103,8 +118,6 @@ void PhysicsEngine::resolvePossibleCollisions()
float e = std::min(objs.first->rigidBody.elasticity, objs.second->rigidBody.elasticity); float e = std::min(objs.first->rigidBody.elasticity, objs.second->rigidBody.elasticity);
float impulseMag = (-(1 + e) * glm::dot(vrel, normal)) / ((1 / objs.first->rigidBody.mass) + (1 / objs.second->rigidBody.mass)); float impulseMag = (-(1 + e) * glm::dot(vrel, normal)) / ((1 / objs.first->rigidBody.mass) + (1 / objs.second->rigidBody.mass));
//objs.first->rigidBody.applyForce(normal, impulseMag);
//objs.second->rigidBody.applyForce(normal, -impulseMag);
objs.first->rigidBody.position += (correctionVector / objs.first->rigidBody.mass); objs.first->rigidBody.position += (correctionVector / objs.first->rigidBody.mass);
objs.second->rigidBody.position -= (correctionVector / objs.second->rigidBody.mass); objs.second->rigidBody.position -= (correctionVector / objs.second->rigidBody.mass);
objs.first->rigidBody.velocity += impulseMag * normal / objs.first->rigidBody.mass; objs.first->rigidBody.velocity += impulseMag * normal / objs.first->rigidBody.mass;

View file

@ -76,7 +76,9 @@ void Scene::loadDebugShooterScene()
entity->setScale(glm::vec3(mapData.tileSize, mapData.tileSize, 1.f)); entity->setScale(glm::vec3(mapData.tileSize, mapData.tileSize, 1.f));
entity->addPhysicsComponent( entity->addPhysicsComponent(
physicsEngine->createObject(entity->getPosition(), 49.0, physicsEngine->createObject(entity->getActorID(),
entity->getPosition(),
49.0,
PhysicsComponent::Collider::Shape::Circle, PhysicsComponent::Collider::Shape::Circle,
glm::vec3(mapData.tileSize / 2), glm::vec3(mapData.tileSize / 2),
glm::abs(entity->getCenter() - entity->getPosition())) glm::abs(entity->getCenter() - entity->getPosition()))

View file

@ -24,7 +24,7 @@ void BulletManager::addBullet(const std::shared_ptr<Bullet>& bullet)
bullets.emplace_back(bullet); bullets.emplace_back(bullet);
} }
void BulletManager::addBullet(const glm::vec3& fireFrom, void BulletManager::addBullet(const unsigned int owner, const glm::vec3& fireFrom,
const glm::vec2& direction, const glm::vec2& direction,
float bulletSpeed, float bulletSpeed,
float bulletDrop, float bulletDrop,
@ -32,7 +32,7 @@ void BulletManager::addBullet(const glm::vec3& fireFrom,
const std::shared_ptr<Shader>& shader, const std::shared_ptr<Shader>& shader,
const std::shared_ptr<Component>& sprite) const std::shared_ptr<Component>& sprite)
{ {
auto bullet = std::make_shared<Bullet>(shader, fireFrom, direction, bulletSpeed, bulletDrop, bulletSize); auto bullet = std::make_shared<Bullet>(owner, shader, fireFrom, direction, bulletSpeed, bulletDrop, bulletSize);
bullet->addComponent(sprite); bullet->addComponent(sprite);
//bullet->addPhysicsComponent(phy) //bullet->addPhysicsComponent(phy)
bullets.emplace_back(bullet); bullets.emplace_back(bullet);

View file

@ -2,7 +2,7 @@
#include "../../../utility/resourcemanager.h" #include "../../../utility/resourcemanager.h"
#include "../../../gameplay/weapons/bulletmanager.h" #include "../../../gameplay/weapons/bulletmanager.h"
#include "../../../gameplay/weapons/bullet.h" #include "../../../gameplay/weapons/bullet.h"
#include "../../../gameplay/entity.h" #include "../../../gameplay/gameactor.h"
#include "../../../utility/component.h" #include "../../../utility/component.h"
#include "../../../utility/events.h" #include "../../../utility/events.h"
#include "../../../gameplay/physics.h" #include "../../../gameplay/physics.h"
@ -76,9 +76,9 @@ void Weapon::shoot()
origin.x -= ((bulletSize.x) * sizeMod) * 0.5f; origin.x -= ((bulletSize.x) * sizeMod) * 0.5f;
origin.y -= ((bulletSize.y) * sizeMod) * 0.5f; origin.y -= ((bulletSize.y) * sizeMod) * 0.5f;
auto bullet = std::make_shared<Bullet>(bulletShader, origin, facing, bulletSpeed, bulletDrop, bulletSize); auto bullet = std::make_shared<Bullet>(wielder->getActorID(), bulletShader, origin, facing, bulletSpeed, bulletDrop, bulletSize);
bullet->addComponent(bulletSprite); bullet->addComponent(bulletSprite);
bullet->addPhysicsComponent(std::make_shared<PhysicsComponent>(PhysicsComponentFactory::makeBullet(origin, mass, bulletSize.x / 2))); bullet->addPhysicsComponent(std::make_shared<PhysicsComponent>(PhysicsComponentFactory::makeBullet(wielder->getActorID(), origin, mass, bulletSize.x / 2)));
bullet->getPhysicsComponent()->rigidBody.velocity += bulletSpeed * glm::vec3(facing.x, facing.y, 0.f) / mass; bullet->getPhysicsComponent()->rigidBody.velocity += bulletSpeed * glm::vec3(facing.x, facing.y, 0.f) / mass;
if (eventManager) if (eventManager)
eventManager->notify(std::make_shared<BulletFiredEvent>(bullet)); eventManager->notify(std::make_shared<BulletFiredEvent>(bullet));
@ -136,6 +136,5 @@ void Weapon::render(const std::shared_ptr<Camera>& camera)
component->bind(); component->bind();
component->render(); component->render();
} }
DebugDrawer::getInstance().addCircle(wielder->getCenter(), wielder->getScale().x + (weaponSize.x * 0.5) + (weaponOffset.x), glm::vec4(1.f, 0.5f, 0.25f, 0.4f));
bulletManager->render(camera); bulletManager->render(camera);
} }

View file

@ -31,6 +31,14 @@ public:
std::shared_ptr<PhysicsComponent> physObj; std::shared_ptr<PhysicsComponent> physObj;
}; };
class BulletCollideEvent : public Event {
public:
BulletCollideEvent(const unsigned int ownerID, const unsigned int victimID) : ownerID(ownerID), victimID(victimID) {}
std::string getType() const override { return "OnBulletCollide"; }
unsigned int ownerID;
unsigned int victimID;
};
class DirectionChangeEvent : public Event { class DirectionChangeEvent : public Event {
public: public:
DirectionChangeEvent(const int actorid, Direction direction) : actorid(actorid), direction(direction) {} DirectionChangeEvent(const int actorid, Direction direction) : actorid(actorid), direction(direction) {}