Added normal parameter for easier knockback implemention script-side

Moved scripts to more descriptive location
This commit is contained in:
Ethan Adams 2024-06-25 15:40:17 -04:00
parent cefcb3889b
commit 1f38730c96
12 changed files with 61 additions and 21 deletions

View file

@ -39,15 +39,15 @@
</player> </player>
<entity x="10" y="3" weapon="pistolGun"> <entity x="10" y="3" weapon="pistolGun">
<sprite file="sprites/player3Atlas.png" frameSize="64.0" directional="true"/> <sprite file="sprites/player3Atlas.png" frameSize="64.0" directional="true"/>
<script file="scripts/grunt_behaviour.lua"/> <script file="scripts/ai/grunt_behaviour.lua"/>
</entity> </entity>
<entity x="6" y="3" weapon="pistolGun"> <entity x="6" y="3" weapon="pistolGun">
<sprite file="sprites/player2Atlas.png" frameSize="128.0"/> <sprite file="sprites/player2Atlas.png" frameSize="128.0"/>
<script file="scripts/grunt_behaviour.lua"/> <script file="scripts/ai/grunt_behaviour.lua"/>
</entity> </entity>
<entity x="5" y="3" weapon="pistolGun"> <entity x="5" y="3" weapon="pistolGun">
<sprite file="sprites/player2Atlas.png" frameSize="128.0"/> <sprite file="sprites/player2Atlas.png" frameSize="128.0"/>
<script file="scripts/grunt_behaviour.lua"/> <script file="scripts/ai/grunt_behaviour.lua"/>
</entity> </entity>
</entities> </entities>
</scene> </scene>

View file

@ -1,17 +1,21 @@
function length(vec)
return math.sqrt(vec.x^2 + vec.y^2)
end
-- How bullets are produced make sure to generate bullet data, then pass it through createBullet -- How bullets are produced make sure to generate bullet data, then pass it through createBullet
function onShoot() function onShoot()
rot = weapon.wielder.rotation rot = weapon.wielder.rotation
data = weapon:genBulletData() data = weapon:genBulletData()
for i=1, 10 do for i=-20, 20, 10 do
spread = math.random(-20, 20) spread = i
print("direction x: "..data.direction.x.." y: "..data.direction.y);
data.direction.x = math.cos(math.rad(rot + spread)) data.direction.x = math.cos(math.rad(rot + spread))
data.direction.y = math.sin(math.rad(rot + spread)) data.direction.y = math.sin(math.rad(rot + spread))
weapon:createBullet(data) weapon:createBullet(data)
end end
end end
-- How the bulllet, target or wielder respond when the bullet hits a target. -- How the bullet, target or wielder respond when the bullet hits a target.
function onHit(target) function onHit(target, bullet, normal)
target.physics.rigidBody:applyForce(vec3.new(normal.x, normal.y, 0.0), 5000.0);
end end

View file

@ -12,7 +12,7 @@
</weapon> </weapon>
<weapon name="shotGun" fireSpeed="750.0"> <weapon name="shotGun" fireSpeed="750.0">
<script file="scripts/shotgun_script.lua"/> <script file="scripts/weapons/shotgun_script.lua"/>
<sprite file="sprites/machineGunAtlas256.png" animated="true" frameSize="256.0"> <sprite file="sprites/machineGunAtlas256.png" animated="true" frameSize="256.0">
<size x="55.0" y="55.0"/> <size x="55.0" y="55.0"/>
<offset x="-30.0" y="0.0"/> <offset x="-30.0" y="0.0"/>

View file

@ -21,6 +21,7 @@ class EventManager;
class ResourceManager; class ResourceManager;
class GameActor; class GameActor;
class WeaponScript; class WeaponScript;
struct PhysicsComponent;
struct WeaponData; struct WeaponData;
class Weapon : public Entity, public std::enable_shared_from_this<Weapon> class Weapon : public Entity, public std::enable_shared_from_this<Weapon>
@ -45,7 +46,7 @@ public:
float speedMod; float speedMod;
float dropMod; float dropMod;
}; };
void onHitCallback(std::shared_ptr<GameActor> target); void onHitCallback(std::shared_ptr<GameActor> target, std::shared_ptr<PhysicsComponent> bullet, const glm::vec2& normal);
glm::vec2 getWeaponSize() const { return weaponSize; } glm::vec2 getWeaponSize() const { return weaponSize; }
// This is the offset from the center right point of the weapon to the barrel of the gun defined in // This is the offset from the center right point of the weapon to the barrel of the gun defined in

View file

@ -33,10 +33,13 @@ public:
class BulletCollideEvent : public Event { class BulletCollideEvent : public Event {
public: public:
BulletCollideEvent(const unsigned int ownerID, const unsigned int victimID) : ownerID(ownerID), victimID(victimID) {} BulletCollideEvent(const unsigned int ownerID, const unsigned int victimID, const std::shared_ptr<PhysicsComponent>& bullet, const glm::vec2& normal)
: ownerID(ownerID), victimID(victimID), bullet(bullet), normal(normal){}
std::string getType() const override { return "OnBulletCollide"; } std::string getType() const override { return "OnBulletCollide"; }
unsigned int ownerID; unsigned int ownerID;
unsigned int victimID; unsigned int victimID;
std::shared_ptr<PhysicsComponent> bullet;
glm::vec2 normal;
}; };
class DirectionChangeEvent : public Event { class DirectionChangeEvent : public Event {

View file

@ -101,16 +101,18 @@ void PhysicsEngine::resolvePossibleCollisions()
if (glm::length(distance) < sumOfRadius) if (glm::length(distance) < sumOfRadius)
{ {
// We got impact! // We got impact!
glm::vec3 normal = distance / glm::length(distance);
// That impact is a bullet hitting a gameactor! // That impact is a bullet hitting a gameactor!
if (objs.first->isBullet || objs.second->isBullet && !(objs.first->isBullet && objs.second->isBullet)) if ((objs.first->isBullet || objs.second->isBullet) && !(objs.first->isBullet && objs.second->isBullet))
{ {
eventManager->notify(std::make_shared<BulletCollideEvent>( eventManager->notify(std::make_shared<BulletCollideEvent>(
( objs.first->isBullet) ? objs.first->ID : objs.second->ID, ( objs.first->isBullet) ? objs.first->ID : objs.second->ID,
(!objs.first->isBullet) ? objs.first->ID : objs.second->ID (!objs.first->isBullet) ? objs.first->ID : objs.second->ID,
std::make_shared<PhysicsComponent>(( objs.first->isBullet) ? objs.first : objs.second),
normal
)); ));
} }
// Apply impulse force // Apply impulse force
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)));
glm::vec3 vrel = objs.first->rigidBody.velocity - objs.second->rigidBody.velocity; glm::vec3 vrel = objs.first->rigidBody.velocity - objs.second->rigidBody.velocity;

View file

@ -31,6 +31,7 @@ Scene::Scene(SceneType sceneType, std::shared_ptr<ResourceManager> resources) :
physicsEngine = std::make_shared<PhysicsEngine>(); physicsEngine = std::make_shared<PhysicsEngine>();
eventManager = std::make_shared<EventManager>(); eventManager = std::make_shared<EventManager>();
physicsEngine->hookEventManager(eventManager); physicsEngine->hookEventManager(eventManager);
hookSceneEvents();
if (sceneType == SCENE_SHOOTER) if (sceneType == SCENE_SHOOTER)
loadDebugShooterScene(); loadDebugShooterScene();
} }
@ -150,7 +151,7 @@ void Scene::hookSceneEvents()
std::shared_ptr<GameActor> shooter = getGameActorByID(collideEvent->ownerID); std::shared_ptr<GameActor> shooter = getGameActorByID(collideEvent->ownerID);
std::shared_ptr<GameActor> target = getGameActorByID(collideEvent->victimID); std::shared_ptr<GameActor> target = getGameActorByID(collideEvent->victimID);
if (shooter && target) if (shooter && target)
shooter->getHeldWeapon()->onHitCallback(target); shooter->getHeldWeapon()->onHitCallback(target, collideEvent->bullet, collideEvent->normal);
}); });
} }

View file

@ -86,11 +86,11 @@ void Weapon::attachScript(const std::shared_ptr<WeaponScript>& script)
std::cout << "weapon state bound" << std::endl; std::cout << "weapon state bound" << std::endl;
} }
void Weapon::onHitCallback(std::shared_ptr<GameActor> target) void Weapon::onHitCallback(std::shared_ptr<GameActor> target, std::shared_ptr<PhysicsComponent> bullet, const glm::vec2& normal)
{ {
if (weaponScript && weaponScript->lua["onHit"].valid()) if (weaponScript && weaponScript->lua["onHit"].valid())
{ {
auto result = weaponScript->lua["onHit"](target); auto result = weaponScript->lua["onHit"](target, bullet, normal);
if (!result.valid()) if (!result.valid())
{ {
sol::error err = result; sol::error err = result;

View file

@ -7,31 +7,60 @@
void Script::registerGlobalUserTypes() void Script::registerGlobalUserTypes()
{ {
auto vec3_mult_overloads = sol::overload(
[](const glm::vec3& v1, const glm::vec3& v2) -> glm::vec3 {return v1 * v2; },
[](const glm::vec3& v1, const float f) -> glm::vec3 { return v1 * f; },
[](const float f, const glm::vec3& v1) -> glm::vec3 { return f * v1; }
);
auto vec2_mult_overloads = sol::overload(
[](const glm::vec2& v1, const glm::vec2& v2) -> glm::vec2 { return v1 * v2; },
[](const glm::vec2& v1, const float f) -> glm::vec2 { return v1 * f; },
[](const float f, const glm::vec3& v1) -> glm::vec2 { return f * v1; }
);
auto vec3_div_overloads = sol::overload(
[](const glm::vec3& v1, const glm::vec3& v2) -> glm::vec3 {return v1 / v2; },
[](const glm::vec3& v1, const float f) -> glm::vec3 { return v1 / f; },
[](const float f, const glm::vec3& v1) -> glm::vec3 { return f / v1; }
);
auto vec2_div_overloads = sol::overload(
[](const glm::vec2& v1, const glm::vec2& v2) -> glm::vec2 { return v1 / v2; },
[](const glm::vec2& v1, const float f) -> glm::vec2 { return v1 / f; },
[](const float f, const glm::vec3& v1) -> glm::vec2 { return f / v1; }
);
// These usertypes are constant for every script // These usertypes are constant for every script
lua.new_usertype<glm::vec3>("vec3", lua.new_usertype<glm::vec3>("vec3",
sol::constructors<glm::vec3(), glm::vec3(float, float, float)>(), sol::constructors<glm::vec3(), glm::vec3(float, float, float)>(),
sol::meta_function::multiplication, vec3_mult_overloads,
sol::meta_function::division, vec3_div_overloads,
"x", &glm::vec3::x, "x", &glm::vec3::x,
"y", &glm::vec3::y, "y", &glm::vec3::y,
"z", &glm::vec3::z); "z", &glm::vec3::z);
lua.new_usertype<glm::vec2>("vec2", lua.new_usertype<glm::vec2>("vec2",
sol::constructors<glm::vec2(), glm::vec2(float, float)>(), sol::constructors<glm::vec2(), glm::vec2(float, float)>(),
sol::meta_function::multiplication, vec2_mult_overloads,
sol::meta_function::division, vec2_div_overloads,
"x", &glm::vec2::x, "x", &glm::vec2::x,
"y", &glm::vec2::y); "y", &glm::vec2::y);
lua.new_usertype<GameActor>("GameActor", lua.new_usertype<GameActor>("GameActor",
// properties // properties
"position", sol::property(&GameActor::getCenter, &GameActor::setPosition), "position", sol::property(&GameActor::getCenter, &GameActor::setPosition),
"rotation", sol::property(&GameActor::getRotation, &GameActor::setRotation), "rotation", sol::property(&GameActor::getRotation, &GameActor::setRotation),
"physics", sol::property(&GameActor::getPhysicsComponent),
// methods // methods
"moveUp", &GameActor::moveUp, "moveUp", &GameActor::moveUp,
"moveDown", &GameActor::moveDown, "moveDown", &GameActor::moveDown,
"moveLeft", &GameActor::moveLeft, "moveLeft", &GameActor::moveLeft,
"moveRight", &GameActor::moveRight, "moveRight", &GameActor::moveRight,
"moveForward", &GameActor::moveForward, "moveForward", &GameActor::moveForward,
"shoot", &GameActor::fireWeapon, "shoot", &GameActor::fireWeapon);
"physics", &GameActor::getPhysicsComponent);
lua.new_usertype<PhysicsComponent>("PhysicsComponent", lua.new_usertype<PhysicsComponent>("PhysicsComponent",
"rigidBody", &PhysicsComponent::rigidBody); "rigidBody", &PhysicsComponent::rigidBody);
lua.new_usertype<PhysicsComponent::RigidBody>("RigidBody", lua.new_usertype<PhysicsComponent::RigidBody>("RigidBody",
"position", &PhysicsComponent::RigidBody::position,
"mass", &PhysicsComponent::RigidBody::mass, "mass", &PhysicsComponent::RigidBody::mass,
"veloctiy", &PhysicsComponent::RigidBody::velocity, "veloctiy", &PhysicsComponent::RigidBody::velocity,
"applyForce", &PhysicsComponent::RigidBody::applyForce); "applyForce", &PhysicsComponent::RigidBody::applyForce);