let projectiles bounce, the new BounceBounce weapon puts the Physics engine into an infinite loop
authorterom
Mon, 08 Dec 2008 01:38:43 +0000
changeset 279 e36f5e1a1c8d
parent 278 2b856bc88e6d
child 280 332f9eb9f309
let projectiles bounce, the new BounceBounce weapon puts the Physics engine into an infinite loop
src/PhysicsObject.cc
src/PhysicsObject.hh
src/Player.cc
src/Projectile.cc
src/Weapon.cc
src/Weapon.hh
src/Weapons.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 <utility>
 #include <queue>
 
-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;
     }
--- 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);
 
 
--- 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);
 }
--- 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);
 }
 
    
--- 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)
 {
 
 }
--- 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
--- 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<Weapon*> 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;