Rope is released if the ground on the pivot point is destroyed.
--- a/src/PhysicsObject.cc Sun Dec 07 19:40:40 2008 +0000
+++ b/src/PhysicsObject.cc Sun Dec 07 19:52:12 2008 +0000
@@ -126,8 +126,6 @@
forceq.push(direction);
}
}
-
- // Go trough every force in the queue
Force total;
while (!forceq.empty()) {
total += forceq.front();
@@ -175,26 +173,25 @@
integrate(total, dt, newPosition, velAfterTick);
this->velocity = velAfterTick;
-
// Collision detection
bool collided = false;
+ Vector collisionPoint;
const Vector diffVec = newPosition-position;
const Vector unitVector = diffVec / diffVec.length();
Vector reached = position;
- Engine::log(DEBUG, "physics.update_position") << "unitVector=" << unitVector;
-
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) {
- // Engine::log(DEBUG, "Here");
this->bounce(world.getNormal(reached+shape[i],
reached-unitVector+shape[i]));
- //this->velocity *= COLLISION_ELASTICITY;
}
reached = reached - unitVector; // Return to last point
collided = true;
@@ -228,7 +225,7 @@
this->position = newPosition;
// the following may delete this object, so it must be the last thing called
- onCollision();
+ onCollision(collisionPoint);
return;
}
--- a/src/PhysicsObject.hh Sun Dec 07 19:40:40 2008 +0000
+++ b/src/PhysicsObject.hh Sun Dec 07 19:52:12 2008 +0000
@@ -146,7 +146,7 @@
/**
* Define object behaviour on collisions.
*/
- virtual void onCollision() {}
+ virtual void onCollision (Vector collisionPoint) {}
/**
* Checks if it is possible for the object to be in the given
--- a/src/Projectile.cc Sun Dec 07 19:40:40 2008 +0000
+++ b/src/Projectile.cc Sun Dec 07 19:52:12 2008 +0000
@@ -29,8 +29,8 @@
destroy();
}
-void Projectile::onCollision() {
- onDestroy(position, true);
+void Projectile::onCollision (Vector collisionPoint) {
+ onDestroy(collisionPoint, true);
}
--- a/src/Projectile.hh Sun Dec 07 19:40:40 2008 +0000
+++ b/src/Projectile.hh Sun Dec 07 19:52:12 2008 +0000
@@ -25,19 +25,19 @@
virtual void draw (Graphics *g, Vector camera = Vector(0, 0)) const;
protected:
- /*
+ /**
* Removes ground at given position if applicable, and destroys this PhysicsObject.
*
* This is overriden by Network.
*/
virtual void onDestroy (Vector position, bool removeGround);
- /*
+ /**
* Call onDestroy, removingGround
*/
- virtual void onCollision (void);
+ virtual void onCollision (Vector collisionPoint);
- /*
+ /**
* If we have expired, call onDestory without removingGround
*/
virtual void tick (TimeMS dt);
--- a/src/Rope.cc Sun Dec 07 19:40:40 2008 +0000
+++ b/src/Rope.cc Sun Dec 07 19:52:12 2008 +0000
@@ -3,6 +3,7 @@
#include "Engine.hh"
#include "Graphics.hh"
#include <math.h>
+#include <stdexcept>
Rope::Rope(Player &player) :
PhysicsObject(player.state.world, ROPE_MASS, Vector(0,0), Vector(0,0), false), player(player), state(ROPE_FOLDED)
@@ -36,12 +37,13 @@
player.handleRopeState(state);
}
-void Rope::onCollision() {
+void Rope::onCollision (Vector collisionPoint) {
// attached to something!
state = ROPE_FIXED;
-
- // stop movement
- disable();
+
+ // Ropes location will be used as the pivot point, so move the location to the collisionPoint.
+ // Currently the position is something like one pixel away from the collisionPoint where there isn't ground.
+ this->position = collisionPoint;
// set player's pivot
player.setPivot(this);
@@ -51,11 +53,9 @@
}
void Rope::release (void) {
- // disable if we're flying
- if (state == ROPE_FLYING)
- disable();
+ // Remove the rope from the PhysicsWorld
+ disable();
- // TODO make it fly first and fold only after it's close to the player
state = ROPE_FOLDED;
// player doesn't have a pivot anymore
@@ -131,3 +131,18 @@
);
}
+void Rope::tick (TimeMS dt) {
+ if (this->state == ROPE_FLYING) {
+ // super
+ PhysicsObject::tick(dt);
+ }
+ else if (this->state == ROPE_FIXED) {
+ // If there's not ground on the pivot point anymore, release the rope
+ if (!world.collides(position)) {
+ release();
+ }
+ }
+ else { // ROPE_FOLDED
+ throw std::logic_error("Rope shouldn't be ticking if it is folded");
+ }
+}
--- a/src/Rope.hh Sun Dec 07 19:40:40 2008 +0000
+++ b/src/Rope.hh Sun Dec 07 19:52:12 2008 +0000
@@ -27,10 +27,11 @@
RopeState state;
protected:
- /*
+ /**
* Attach the rope, so disable the PhysicsObject and change state
+ * @param collisionPoint Where the rope has hit the ground.
*/
- virtual void onCollision (void);
+ virtual void onCollision (Vector collisionPoint);
/*
* If the rope is currently longer than length, this returns ROPE_FORCE, else 0
@@ -71,6 +72,8 @@
void updateState (RopeState state, Vector position, Vector velocity, float length);
void updateLength (float length);
+ virtual void tick (TimeMS dt);
+
/*
* Just draws it
*/