--- a/src/Config.hh Mon Dec 08 15:59:33 2008 +0000
+++ b/src/Config.hh Mon Dec 08 16:01:49 2008 +0000
@@ -47,6 +47,7 @@
const float PLAYER_COLLISION_ELASTICITY = 0.25; // TODO: This could be
// different for different
// objects
+const float PLAYER_RADIUS = 10;
/*
* Projectiles
--- a/src/PhysicsObject.cc Mon Dec 08 15:59:33 2008 +0000
+++ b/src/PhysicsObject.cc Mon Dec 08 16:01:49 2008 +0000
@@ -247,7 +247,7 @@
setPosition (newPosition);
// the following may delete this object, so it must be the last thing called
- onCollision(collisionPoint, NULL);
+ onCollision(collisionPoint);
return;
}
--- a/src/PhysicsObject.hh Mon Dec 08 15:59:33 2008 +0000
+++ b/src/PhysicsObject.hh Mon Dec 08 16:01:49 2008 +0000
@@ -156,14 +156,14 @@
void walk(TimeMS, bool right);
Vector walk_one_step(float, bool);
+public:
/**
* Define object behaviour on collisions.
*
* XXX: make this pure-virtual
*/
- virtual void onCollision (Vector collisionPoint, PhysicsObject *other);
+ virtual void onCollision (Vector collisionPoint, PhysicsObject *other = NULL);
-public:
/**
* Return the type of the physics object (player, projectile...)
*/
--- a/src/PhysicsWorld.cc Mon Dec 08 15:59:33 2008 +0000
+++ b/src/PhysicsWorld.cc Mon Dec 08 16:01:49 2008 +0000
@@ -23,11 +23,65 @@
objects.remove(po);
}
+
+float distancePointToLine(Vector l1, Vector l2, Vector p) {
+ Vector v(l2.y - l1.y, -(l2.x - l1.x));
+ Vector r(l1.x-p.x, l1.y-p.y);
+ v = v/v.length();
+ float dist = v*r/v.sqrLength();
+ return dist;
+}
+
void PhysicsWorld::tick (TimeMS tick_length) {
// tick each object in turn
for (std::list<PhysicsObject*>::iterator i = objects.begin(); i != objects.end(); i++) {
(*i)->tick(tick_length);
}
+ for (std::list<PhysicsObject*>::iterator i = objects.begin(); i != objects.end(); i++) {
+ for (std::list<PhysicsObject*>::iterator j = i; j != objects.end(); j++) {
+ if(i == j)
+ continue;
+ float range_sum_sqr = 2;
+ if((*i)->getType() == PLAYER) {
+ range_sum_sqr += PLAYER_RADIUS-1;
+ }
+ if((*j)->getType() == PLAYER) {
+ range_sum_sqr += PLAYER_RADIUS-1;
+ }
+ range_sum_sqr *= range_sum_sqr;
+ bool collision = false;
+ Vector a1 = (*i)->getPreviousPosition();
+ Vector a2 = (*i)->getPosition();
+ Vector b1 = (*j)->getPreviousPosition();
+ Vector b2 = (*j)->getPosition();
+/* if(a1 == a2) {
+ float d = abs(distancePointToLine(b1, b2, a1));
+ if(d*d < range_sum_sqr)
+ collision = true;
+ } else if(b1 == b2) {
+ float d = abs(distancePointToLine(a1, a2, b1));
+ if(d*d < range_sum_sqr)
+ collision = true;
+ } else {*/
+ float db1 = distancePointToLine(a1, a2, b1);
+ float db2 = distancePointToLine(a1, a2, b2);
+ float da1 = distancePointToLine(b1, b2, a1);
+ float da2 = distancePointToLine(b1, b2, a2);
+ if(db1*db2 < 0 && da1*da2 < 0) {
+ // lines intersected
+// collision = true;
+ }
+ float dab = (a2-b2).sqrLength();
+ if(dab < range_sum_sqr) {
+ collision = true;
+ }
+// }
+ if(collision) {
+ (*i)->onCollision(a2, *j);
+ (*j)->onCollision(b2, *i);
+ }
+ }
+ }
// Delete destroyed objects
objects.remove_if(std::mem_fun(&PhysicsObject::removeIfDestroyed));