let projectiles bounce, the new BounceBounce weapon puts the Physics engine into an infinite loop
--- 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;