Rope can be drawn.
authorekku
Sat, 06 Dec 2008 19:38:01 +0000
changeset 225 22ecb9cb9245
parent 224 e6faefba2ec1
child 226 381487d07d17
Rope can be drawn.
src/GameState.cc
src/GameState.hh
src/Input.cc
src/Input.hh
src/PhysicsObject.cc
src/PhysicsObject.hh
src/PhysicsWorld.cc
src/PhysicsWorld.hh
src/Player.cc
src/Player.hh
src/Rope.cc
src/Rope.hh
--- a/src/GameState.cc	Sat Dec 06 19:14:58 2008 +0000
+++ b/src/GameState.cc	Sat Dec 06 19:38:01 2008 +0000
@@ -9,6 +9,10 @@
     projectiles.push_back(projectile);
 }
 
+void GameState::addRope (Rope *rope) {
+    ropes.push_back(rope);
+}
+
 LocalPlayer *GameState::getLocalPlayer (void) {
     return local_player;
 }
@@ -42,5 +46,10 @@
     for (std::list<Projectile*>::iterator it = projectiles.begin(); it != projectiles.end(); it++) {
         (*it)->draw(gc);
     }
+    // Draw ropes
+    for (std::list<Rope*>::iterator it = ropes.begin(); it != ropes.end(); it++) {
+        if ((*it)->getState() != FOLDED)
+            (*it)->draw(gc);
+    }
 }
  
--- a/src/GameState.hh	Sat Dec 06 19:14:58 2008 +0000
+++ b/src/GameState.hh	Sat Dec 06 19:38:01 2008 +0000
@@ -6,6 +6,7 @@
 #include "PhysicsWorld.hh"
 #include "Player.hh"
 #include "Projectile.hh"
+#include "Rope.hh"
 #include "Input.hh"
 #include "Config.hh"
 
@@ -17,6 +18,7 @@
 public:
     std::list<Player*> player_list;
     std::list<Projectile*> projectiles;
+    std::list<Rope*> ropes;
     PhysicsWorld world;
 
     // only one local player is supported
@@ -25,6 +27,7 @@
     GameState (void);
     
     void addProjectile(Projectile *projectile);
+    void addRope(Rope *rope);
 
     /*
      * This will return NULL if we don't have a local player - yet
--- a/src/Input.cc	Sat Dec 06 19:14:58 2008 +0000
+++ b/src/Input.cc	Sat Dec 06 19:38:01 2008 +0000
@@ -12,6 +12,7 @@
     {   CL_KEY_M,       INPUT_DIG           },
     {   CL_KEY_F,       INPUT_SHOOT         },
     {   CL_KEY_D,       INPUT_CHANGE        },
+    {   CL_KEY_R,       INPUT_ROPE          },
     {   0,              (_PlayerInput) 0    }
 };
 
--- a/src/Input.hh	Sat Dec 06 19:14:58 2008 +0000
+++ b/src/Input.hh	Sat Dec 06 19:38:01 2008 +0000
@@ -17,6 +17,7 @@
     INPUT_DIG           = 0x0020,
     INPUT_SHOOT         = 0x0040,
     INPUT_CHANGE        = 0x0080,
+    INPUT_ROPE          = 0x0100
 };
 
 typedef uint16_t PlayerInput;
--- a/src/PhysicsObject.cc	Sat Dec 06 19:14:58 2008 +0000
+++ b/src/PhysicsObject.cc	Sat Dec 06 19:38:01 2008 +0000
@@ -4,14 +4,15 @@
 
 #include <cmath>
 
-PhysicsObject::PhysicsObject (PhysicsWorld &world, float mass, Vector position, Vector velocity) :
-    world(world), position(position), velocity(velocity), mass(mass), inAir(true), aim(0), facingRight(true), alive(true)
-{
-    world.addPhysicsObject(this);
+PhysicsObject::PhysicsObject (PhysicsWorld &world, float mass, Vector position, Vector velocity, bool enabled) :
+    world(world), position(position), velocity(velocity), mass(mass), inAir(true), aim(0), facingRight(true), alive(false), shouldDelete(false)
+{  
+    if (enabled)
+        enable();  
 }
 
 PhysicsObject::~PhysicsObject (void) {
-    // Engine::log(DEBUG, "PhysicsObject.destructor") << this /* << ": objects.size=" << ((int) world.objects.size()) */;
+//    Engine::log(DEBUG, "PhysicsObject.destructor") << this /* << ": objects.size=" << ((int) world.objects.size()) */;
 }
 
 /**
@@ -296,7 +297,7 @@
     this->facingRight = facingRight;
     this->aim = aim;
 }
-   
+
 Vector PhysicsObject::getPosition () {
     return this->position;
 }
@@ -325,8 +326,18 @@
     this->updatePosition(tick_length);
 }
     
+void PhysicsObject::enable (void) {
+    alive = true;
+    world.addPhysicsObject(this);
+}
+
+void PhysicsObject::disable (void) {
+    alive = false;
+}
+
 void PhysicsObject::destroy (void) {
     alive = false;
+    shouldDelete = true;
 }
     
 bool PhysicsObject::isDestroyed (void) {
@@ -335,8 +346,11 @@
     
 bool PhysicsObject::removeIfDestroyed (void) {
     if (!alive) {
-        delete this;
+        if (shouldDelete)
+            delete this;
+
         return true;
+
     } else {
         return false;
     }
--- a/src/PhysicsObject.hh	Sat Dec 06 19:14:58 2008 +0000
+++ b/src/PhysicsObject.hh	Sat Dec 06 19:38:01 2008 +0000
@@ -32,9 +32,10 @@
     bool facingRight; // Player facing
 
     bool alive;
+    bool shouldDelete;
 
     PhysicsObject(PhysicsWorld &world, float mass, Vector position, 
-                  Vector velocity);
+                  Vector velocity, bool enabled = true);
     virtual ~PhysicsObject (void);
 
 
@@ -83,6 +84,16 @@
      */
     virtual void updatePhysics(Vector position, Vector velocity, bool inAir, bool facingRight, float aim);
 
+    /**
+     * Put object to the objects list so that its movement will be calculated.
+     */
+    void enable (void);
+
+    /**
+     * Remove object from the objects list but don't delete the object itself.
+     */
+    void disable (void);
+
 private:
     // TODO: I'd be tempted to use some already made ClanLib structure
     // here.  
--- a/src/PhysicsWorld.cc	Sat Dec 06 19:14:58 2008 +0000
+++ b/src/PhysicsWorld.cc	Sat Dec 06 19:38:01 2008 +0000
@@ -15,6 +15,9 @@
     objects.push_back(po);
 }
 
+void PhysicsWorld::removePhysicsObject (PhysicsObject *po) {
+    objects.remove(po);
+}
 
 void PhysicsWorld::tick (TimeMS tick_length) {
     for (std::list<PhysicsObject*>::iterator i = objects.begin(); i != objects.end(); i++) {
--- a/src/PhysicsWorld.hh	Sat Dec 06 19:14:58 2008 +0000
+++ b/src/PhysicsWorld.hh	Sat Dec 06 19:38:01 2008 +0000
@@ -43,7 +43,7 @@
 
     PhysicsWorld(Vector gravity, Vector dimensions);
 
-   /**
+    /**
      * Add object to the PhysicsWorld.
      *
      * @param object Pointer to the PhysicsObject to add.
@@ -51,6 +51,11 @@
     void addPhysicsObject(PhysicsObject *object);
     
     /**
+     * Remove the object from the PhysicsWorld.
+     */
+    void removePhysicsObject (PhysicsObject *po);
+    
+    /**
      * Advance one time step in physics simulation.
      */
     void tick(TimeMS tick_length);
@@ -61,8 +66,6 @@
      * @return tick Current simulation tick.
      */
     uint32_t getTick();
-
-    // TODO This should probably be protected or in GameStat or in GameStatee
 };
 
 #endif 
--- a/src/Player.cc	Sat Dec 06 19:14:58 2008 +0000
+++ b/src/Player.cc	Sat Dec 06 19:38:01 2008 +0000
@@ -19,7 +19,7 @@
 
 Player::Player(GameState &state, Vector position, bool visible) : 
     PhysicsObject(state.world, PLAYER_MASS, position, Vector(0, 0)), state(state), visible(visible), arsenal(),
-    selectedWeapon(0), changing(false), animation_step(0) //, rope(*this) 
+    selectedWeapon(0), changing(false), animation_step(0), rope(*this) 
 {
     // TODO: arsenal's size should be affected by some value
     // and weapons should be loaded from somewhere, not generated here
@@ -154,6 +154,9 @@
     if (input & INPUT_SHOOT && getWeapon().canShoot())
         fireWeapon(getWeapon());
     
+    if (input & INPUT_ROPE)
+        rope.shoot();
+
     // XXX: how should this be written?
     if (move_force.x != 0) 
         animation_step = (animation_step + 1) % img_num_step;
--- a/src/Player.hh	Sat Dec 06 19:14:58 2008 +0000
+++ b/src/Player.hh	Sat Dec 06 19:38:01 2008 +0000
@@ -9,7 +9,7 @@
 #include "PhysicsObject.hh"
 #include "Input.hh"
 #include "Weapon.hh"
-//#include "Rope.hh"
+#include "Rope.hh"
 #include <vector>
 
 class Player : public PhysicsObject {
@@ -22,7 +22,7 @@
         unsigned int selectedWeapon; //unsigned for x%sW not to fail
         bool changing;
 
-//        Rope rope;
+        Rope rope;
         int animation_step;
 
         // default constructor for use with virtual inheritance... it's not defined
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/Rope.cc	Sat Dec 06 19:38:01 2008 +0000
@@ -0,0 +1,49 @@
+#include "Player.hh"
+#include "Rope.hh"      
+#include "Engine.hh"
+#include <math.h>
+
+Rope::Rope(Player &climber) : PhysicsObject(climber.state.world, PLAYER_MASS, Vector(0,0), Vector(0,0), false), pl(climber), rs(FOLDED) {
+    std::vector<Vector> shape(4);
+    shape[0] = Vector(-1, -1);
+    shape[1] = Vector(-1, 1);
+    shape[2] = Vector(1, 1);
+    shape[3] = Vector(1, -1);
+    setShape(shape);
+}
+
+void Rope::shoot(void) {
+
+    this->rs = FLYING;
+
+    this->length = 100;
+    this->position = pl.getPosition();
+    Vector direction = pl.getFacing() ? Vector( cos(pl.getAim()), -sin(pl.getAim()) ) 
+                                      : Vector( -cos(pl.getAim()), -sin(pl.getAim()) );
+    this->velocity = pl.getVelocity() + direction*500;
+    this->inAir = true;
+
+    enable();
+    pl.state.addRope(this);
+}
+
+void Rope::onCollision() {
+    this->rs = FIXED;
+    disable();
+}
+
+void Rope::release (void) {
+    // TODO make it fly first and fold only 
+    // after it's close to the player
+    this->rs = FOLDED;
+}
+
+RopeState Rope::getState (void) {
+    return this->rs;
+}
+
+void Rope::draw (CL_GraphicContext *gc) const {
+    gc->draw_line((int)(this->pl.getPosition().x), (int)(this->pl.getPosition().y)
+        , (int)(this->position.x), (int)(this->position.y), CL_Color::black);
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/Rope.hh	Sat Dec 06 19:38:01 2008 +0000
@@ -0,0 +1,29 @@
+#ifndef ROPE_HH
+#define ROPE_HH
+
+// Pre-declarations since rope wants to know the Player
+// and the Player wants to know the rope.
+class Rope;
+
+#include "Player.hh"
+#include "PhysicsObject.hh"
+
+enum RopeState { FOLDED, FLYING, FIXED };
+
+class Rope : public PhysicsObject {
+private:
+    Player &pl;
+    // How long is the rope in its static state
+    float length;
+    virtual void onCollision (void);
+    RopeState rs;
+public:
+    Rope(Player &climber);
+
+    void shoot (void);
+    void release (void);
+    RopeState getState (void);
+    virtual void draw(CL_GraphicContext *gc) const;
+};
+
+#endif