# HG changeset patch # User terom # Date 1228700323 0 # Node ID e36f5e1a1c8db93383896f03558434f9e512b62c # Parent 2b856bc88e6d6048bd2946039057f8cf2fee229b let projectiles bounce, the new BounceBounce weapon puts the Physics engine into an infinite loop diff -r 2b856bc88e6d -r e36f5e1a1c8d src/PhysicsObject.cc --- a/src/PhysicsObject.cc Mon Dec 08 01:31:09 2008 +0000 +++ b/src/PhysicsObject.cc Mon Dec 08 01:38:43 2008 +0000 @@ -5,9 +5,10 @@ #include #include -PhysicsObject::PhysicsObject (PhysicsWorld &world, float mass, Vector position, Vector velocity, ObjectType type, bool enabled) : +PhysicsObject::PhysicsObject (PhysicsWorld &world, float mass, Vector position, Vector velocity, ObjectType type, + float collision_elasticity, bool enabled) : world(world), position(position), velocity(velocity), mass(mass), inAir(true), aim(0), facing(FACING_RIGHT), - alive(false), shouldDelete(false), type(type), pivot(NULL) + alive(false), shouldDelete(false), type(type), pivot(NULL), collision_elasticity(collision_elasticity) { if (enabled) enable(); @@ -187,30 +188,32 @@ bool collided = false; Vector collisionPoint; - const Vector diffVec = newPosition-position; + const Vector diffVec = newPosition - position; const Vector unitVector = diffVec / diffVec.length(); Vector reached = position; - while ((position-reached).sqrLength() < diffVec.sqrLength()) { + while ((position - reached).sqrLength() < diffVec.sqrLength()) { reached += unitVector; + // Check if any of the shapes points collide for (uint64_t i = 0; i < shape.size(); i++) { if (world.collides(reached+shape[i])) { // Collision collisionPoint = reached+shape[i]; - if (inAir) { - this->bounce(world.getNormal(reached+shape[i], - reached-unitVector+shape[i])); - } + if (inAir) + this->bounce(world.getNormal(reached+shape[i], reached-unitVector+shape[i])); + reached = reached - unitVector; // Return to last point collided = true; - if (this->velocity.sqrLength() < PLAYER_MIN_SPEED * PLAYER_MIN_SPEED) { + + if (this->velocity.sqrLength() < PLAYER_MIN_SPEED * PLAYER_MIN_SPEED) this->velocity = Vector(0,0); - } + break; } } + if (collided) break; } diff -r 2b856bc88e6d -r e36f5e1a1c8d src/PhysicsObject.hh --- a/src/PhysicsObject.hh Mon Dec 08 01:31:09 2008 +0000 +++ b/src/PhysicsObject.hh Mon Dec 08 01:38:43 2008 +0000 @@ -45,8 +45,8 @@ PhysicsObject *pivot; - PhysicsObject(PhysicsWorld &world, float mass, Vector position, - Vector velocity, ObjectType type, bool enabled = true); + PhysicsObject (PhysicsWorld &world, float mass, Vector position, Vector velocity, ObjectType type, + float collision_elasticity, bool enabled = true); virtual ~PhysicsObject (void); diff -r 2b856bc88e6d -r e36f5e1a1c8d src/Player.cc --- a/src/Player.cc Mon Dec 08 01:31:09 2008 +0000 +++ b/src/Player.cc Mon Dec 08 01:38:43 2008 +0000 @@ -20,8 +20,8 @@ const int img_width = 17; Player::Player(GameState &state, Vector position, bool visible) : - PhysicsObject(state.world, PLAYER_MASS, position, Vector(0, 0), PLAYER), state(state), visible(visible), - weapons(buildWeaponsList()), selectedWeapon(0), animation_step(0), rope(*this) + PhysicsObject(state.world, PLAYER_MASS, position, Vector(0, 0), PLAYER, PLAYER_COLLISION_ELASTICITY), state(state), + visible(visible), weapons(buildWeaponsList()), selectedWeapon(0), animation_step(0), rope(*this) { // XXX: populate weapons from somewhere else @@ -36,9 +36,6 @@ // Initialize the shape of the player (salmiakki shape) setShape(shape); - // XXX: this should be a PhysicsObject constructor arg - collision_elasticity = PLAYER_COLLISION_ELASTICITY; - // add to GameState players list state.addPlayer(this); } diff -r 2b856bc88e6d -r e36f5e1a1c8d src/Projectile.cc --- a/src/Projectile.cc Mon Dec 08 01:31:09 2008 +0000 +++ b/src/Projectile.cc Mon Dec 08 01:38:43 2008 +0000 @@ -4,8 +4,8 @@ Projectile::Projectile (Player *player, Vector position, Vector velocity, Weapon *weapon, bool visible) : - PhysicsObject(player->state.world, PROJECTILE_MASS, position, velocity, PROJECTILE), player(player), - visible(visible), explosionRadius(weapon->getExplosionRadius()), radius(weapon->getRadius()), + PhysicsObject(player->state.world, PROJECTILE_MASS, position, velocity, PROJECTILE, weapon->getBounce()), + player(player), visible(visible), explosionRadius(weapon->getExplosionRadius()), radius(weapon->getRadius()), expire(weapon->getExpire()) { // set birth tick @@ -21,9 +21,6 @@ setShape(shape); - // XXX: get this as an argument - collision_elasticity = 0.9; - // add to state player->state.addProjectile(this); } @@ -40,7 +37,8 @@ } void Projectile::onCollision (Vector collisionPoint, PhysicsObject *other) { - onDestroy(collisionPoint, true); + if (collision_elasticity == 0) + onDestroy(collisionPoint, true); } diff -r 2b856bc88e6d -r e36f5e1a1c8d src/Weapon.cc --- a/src/Weapon.cc Mon Dec 08 01:31:09 2008 +0000 +++ b/src/Weapon.cc Mon Dec 08 01:38:43 2008 +0000 @@ -1,9 +1,9 @@ #include "Weapon.hh" Weapon::Weapon(WeaponID id, TickCount expire, float velocity, float recoil, float explosionRadius, float radius, - TimeMS reloadTime, std::string name) : + TimeMS reloadTime, std::string name, float bounce) : id(id), expire(expire), velocity(velocity), recoil(recoil), explosionRadius(explosionRadius), radius(radius), - reloadTime(reloadTime), name(name), reloadTimer(0) + reloadTime(reloadTime), name(name), reloadTimer(0), bounce(bounce) { } diff -r 2b856bc88e6d -r e36f5e1a1c8d src/Weapon.hh --- a/src/Weapon.hh Mon Dec 08 01:31:09 2008 +0000 +++ b/src/Weapon.hh Mon Dec 08 01:38:43 2008 +0000 @@ -62,11 +62,16 @@ */ int reloadTimer; + /** + * If nonzero, projectiles bounce off walls (it's the elasticity factor), else they explode on contact + */ + float bounce; + public: /** * Create a weapon with the given parameters */ - Weapon (WeaponID id, TickCount expire, float velocity, float recoil, float explosionRadius, float radius, TimeMS reloadTime, std::string name); + Weapon (WeaponID id, TickCount expire, float velocity, float recoil, float explosionRadius, float radius, TimeMS reloadTime, std::string name, float bounce); /** * Decrement the reload timer, if it's still going @@ -88,6 +93,7 @@ float getExplosionRadius (void) const { return explosionRadius; } float getRadius (void) const { return radius; } TickCount getExpire (void) const { return expire; } + float getBounce (void) const { return bounce; } /** * Start reloading diff -r 2b856bc88e6d -r e36f5e1a1c8d src/Weapons.cc --- a/src/Weapons.cc Mon Dec 08 01:31:09 2008 +0000 +++ b/src/Weapons.cc Mon Dec 08 01:38:43 2008 +0000 @@ -8,15 +8,17 @@ float explosionRadius; float radius; TickCount reloadTime; + float bounce; std::string name; } WEAPON_PARAMS[] = { - /* age speed recoil expRadius radius reloadTime name */ - { 10000, 5 * 80 + 50, 0 * 5 + 10000, 0 * 6 + 5, 1, 0 * 100 + 50, "Weapon 1" }, - { 10000, 4 * 80 + 50, 2 * 5 + 5, 1 * 6 + 5, 2, 1 * 100 + 50, "Weapon 2" }, - { 10000, 3 * 80 + 50, 3 * 5 + 5, 2 * 6 + 5, 3, 2 * 100 + 50, "Weapon 3" }, - { 10000, 2 * 80 + 50, 4 * 5 + 5, 3 * 6 + 5, 4, 3 * 100 + 50, "Weapon 4" }, - { 10000, 1 * 80 + 50, 5 * 5 + 5, 4 * 6 + 5, 5, 4 * 100 + 50, "Weapon 5" }, - { 0, 0, 0, 0, 0, 0, "" } + /* age speed recoil expRadius radius reloadTime bounce name */ + { 10000, 5 * 80 + 50, 0 * 5 + 10000, 0 * 6 + 5, 1, 0 * 100 + 50, 0.00, "Weapon 1" }, + { 10000, 4 * 80 + 50, 2 * 5 + 5, 1 * 6 + 5, 2, 1 * 100 + 50, 0.00, "Weapon 2" }, + { 10000, 3 * 80 + 50, 3 * 5 + 5, 2 * 6 + 5, 3, 2 * 100 + 50, 0.00, "Weapon 3" }, + { 10000, 2 * 80 + 50, 4 * 5 + 5, 3 * 6 + 5, 4, 3 * 100 + 50, 0.00, "Weapon 4" }, + { 10000, 1 * 80 + 50, 5 * 5 + 5, 4 * 6 + 5, 5, 4 * 100 + 50, 0.00, "Weapon 5" }, + { 10000, 600, 50000, 100, 10, 1000, 1.05, "BounceBounce" }, + { 0, 0, 0, 0, 0, 0, 0.00, "" } }; std::vector buildWeaponsList (void) { @@ -24,9 +26,9 @@ int idx = 0; for (WeaponParams *wp = WEAPON_PARAMS; - wp->age || wp->speed || wp->recoil || wp->explosionRadius || wp->radius || wp->reloadTime; + wp->age || wp->speed || wp->recoil || wp->explosionRadius || wp->radius || wp->bounce || wp->reloadTime; wp++, idx++) { - weapons.push_back(new Weapon(idx, wp->age, wp->speed, wp->recoil, wp->explosionRadius, wp->radius, wp->reloadTime, wp->name)); + weapons.push_back(new Weapon(idx, wp->age, wp->speed, wp->recoil, wp->explosionRadius, wp->radius, wp->reloadTime, wp->name, wp->bounce)); } return weapons;