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>
<entity x="10" y="3" weapon="pistolGun">
<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 x="6" y="3" weapon="pistolGun">
<sprite file="sprites/player2Atlas.png" frameSize="128.0"/>
<script file="scripts/grunt_behaviour.lua"/>
<script file="scripts/ai/grunt_behaviour.lua"/>
</entity>
<entity x="5" y="3" weapon="pistolGun">
<sprite file="sprites/player2Atlas.png" frameSize="128.0"/>
<script file="scripts/grunt_behaviour.lua"/>
<script file="scripts/ai/grunt_behaviour.lua"/>
</entity>
</entities>
</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
function onShoot()
rot = weapon.wielder.rotation
data = weapon:genBulletData()
for i=1, 10 do
spread = math.random(-20, 20)
print("direction x: "..data.direction.x.." y: "..data.direction.y);
for i=-20, 20, 10 do
spread = i
data.direction.x = math.cos(math.rad(rot + spread))
data.direction.y = math.sin(math.rad(rot + spread))
weapon:createBullet(data)
end
end
-- How the bulllet, target or wielder respond when the bullet hits a target.
function onHit(target)
-- How the bullet, target or wielder respond when the bullet hits a target.
function onHit(target, bullet, normal)
target.physics.rigidBody:applyForce(vec3.new(normal.x, normal.y, 0.0), 5000.0);
end

View file

@ -12,7 +12,7 @@
</weapon>
<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">
<size x="55.0" y="55.0"/>
<offset x="-30.0" y="0.0"/>

View file

@ -21,6 +21,7 @@ class EventManager;
class ResourceManager;
class GameActor;
class WeaponScript;
struct PhysicsComponent;
struct WeaponData;
class Weapon : public Entity, public std::enable_shared_from_this<Weapon>
@ -45,7 +46,7 @@ public:
float speedMod;
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; }
// 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 {
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"; }
unsigned int ownerID;
unsigned int victimID;
std::shared_ptr<PhysicsComponent> bullet;
glm::vec2 normal;
};
class DirectionChangeEvent : public Event {

View file

@ -101,16 +101,18 @@ void PhysicsEngine::resolvePossibleCollisions()
if (glm::length(distance) < sumOfRadius)
{
// We got impact!
glm::vec3 normal = distance / glm::length(distance);
// 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>(
(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
glm::vec3 normal = distance / 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 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>();
eventManager = std::make_shared<EventManager>();
physicsEngine->hookEventManager(eventManager);
hookSceneEvents();
if (sceneType == SCENE_SHOOTER)
loadDebugShooterScene();
}
@ -150,7 +151,7 @@ void Scene::hookSceneEvents()
std::shared_ptr<GameActor> shooter = getGameActorByID(collideEvent->ownerID);
std::shared_ptr<GameActor> target = getGameActorByID(collideEvent->victimID);
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;
}
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())
{
auto result = weaponScript->lua["onHit"](target);
auto result = weaponScript->lua["onHit"](target, bullet, normal);
if (!result.valid())
{
sol::error err = result;

View file

@ -7,31 +7,60 @@
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
lua.new_usertype<glm::vec3>("vec3",
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,
"y", &glm::vec3::y,
"z", &glm::vec3::z);
lua.new_usertype<glm::vec2>("vec2",
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,
"y", &glm::vec2::y);
lua.new_usertype<GameActor>("GameActor",
// properties
"position", sol::property(&GameActor::getCenter, &GameActor::setPosition),
"rotation", sol::property(&GameActor::getRotation, &GameActor::setRotation),
"physics", sol::property(&GameActor::getPhysicsComponent),
// methods
"moveUp", &GameActor::moveUp,
"moveDown", &GameActor::moveDown,
"moveLeft", &GameActor::moveLeft,
"moveRight", &GameActor::moveRight,
"moveForward", &GameActor::moveForward,
"shoot", &GameActor::fireWeapon,
"physics", &GameActor::getPhysicsComponent);
"shoot", &GameActor::fireWeapon);
lua.new_usertype<PhysicsComponent>("PhysicsComponent",
"rigidBody", &PhysicsComponent::rigidBody);
lua.new_usertype<PhysicsComponent::RigidBody>("RigidBody",
"position", &PhysicsComponent::RigidBody::position,
"mass", &PhysicsComponent::RigidBody::mass,
"veloctiy", &PhysicsComponent::RigidBody::velocity,
"applyForce", &PhysicsComponent::RigidBody::applyForce);