Rope is released if the ground on the pivot point is destroyed.
authorekku
Sun, 07 Dec 2008 19:52:12 +0000
changeset 252 25054ce94d07
parent 251 6a6208e5c7a1
child 253 747b1037d83e
Rope is released if the ground on the pivot point is destroyed.
src/PhysicsObject.cc
src/PhysicsObject.hh
src/Projectile.cc
src/Projectile.hh
src/Rope.cc
src/Rope.hh
--- 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
          */