# HG changeset patch # User ekku # Date 1228679532 0 # Node ID 25054ce94d07eba27376c83fa559b10559f2019b # Parent 6a6208e5c7a151fb958c96653195ca327972e133 Rope is released if the ground on the pivot point is destroyed. diff -r 6a6208e5c7a1 -r 25054ce94d07 src/PhysicsObject.cc --- 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; } diff -r 6a6208e5c7a1 -r 25054ce94d07 src/PhysicsObject.hh --- 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 diff -r 6a6208e5c7a1 -r 25054ce94d07 src/Projectile.cc --- 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); } diff -r 6a6208e5c7a1 -r 25054ce94d07 src/Projectile.hh --- 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); diff -r 6a6208e5c7a1 -r 25054ce94d07 src/Rope.cc --- 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 +#include 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"); + } +} diff -r 6a6208e5c7a1 -r 25054ce94d07 src/Rope.hh --- 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 */