reorganize PhysicsObject/Player/Projectile lists so that PhysicsObject doesn't need to know about its subclasses anymore, and PhysicsWorld doesn't need to know about GameState
--- a/src/GameState.cc Sat Dec 06 16:17:05 2008 +0000
+++ b/src/GameState.cc Sat Dec 06 17:51:19 2008 +0000
@@ -5,6 +5,10 @@
GameState::GameState (void) : local_player(NULL), world(Vector(0, MAP_GRAVITY), Vector(MAP_WIDTH, MAP_HEIGHT)) { }
+void GameState::addProjectile (Projectile *projectile) {
+ projectiles.push_back(projectile);
+}
+
LocalPlayer *GameState::getLocalPlayer (void) {
return local_player;
}
@@ -25,7 +29,18 @@
void GameState::removePlayer (Player *player) {
player_list.remove(player);
}
-
+
+void GameState::draw(CL_GraphicContext *gc) {
+ // Draw world/terrain
+ world.draw(gc);
-
-
+ // Draw players
+ for (std::list<Player*>::iterator it = player_list.begin(); it != player_list.end(); it++) {
+ (*it)->draw(gc);
+ }
+ // Draw projectiles
+ for (std::list<Projectile*>::iterator it = projectiles.begin(); it != projectiles.end(); it++) {
+ (*it)->draw(gc);
+ }
+}
+
--- a/src/GameState.hh Sat Dec 06 16:17:05 2008 +0000
+++ b/src/GameState.hh Sat Dec 06 17:51:19 2008 +0000
@@ -16,12 +16,15 @@
class GameState {
public:
std::list<Player*> player_list;
+ std::list<Projectile*> projectiles;
PhysicsWorld world;
// only one local player is supported
LocalPlayer *local_player;
GameState (void);
+
+ void addProjectile(Projectile *projectile);
/*
* This will return NULL if we don't have a local player - yet
@@ -29,10 +32,12 @@
LocalPlayer *getLocalPlayer (void);
void newLocalPlayer (LocalPlayer *player);
-
void newPlayer (Player *player);
void removePlayer (Player *player);
+
+ virtual void draw(CL_GraphicContext *gc);
+
};
#endif
--- a/src/Graphics.cc Sat Dec 06 16:17:05 2008 +0000
+++ b/src/Graphics.cc Sat Dec 06 17:51:19 2008 +0000
@@ -54,7 +54,7 @@
gc->clear(CL_Color::white);
// Draw terrain
- state.world.draw(gc);
+ state.draw(gc);
// Flip window buffer, sync
win.flip(1);
--- a/src/PhysicsObject.cc Sat Dec 06 16:17:05 2008 +0000
+++ b/src/PhysicsObject.cc Sat Dec 06 17:51:19 2008 +0000
@@ -1,15 +1,21 @@
-#include "Player.hh"
+
#include "PhysicsObject.hh"
#include "Engine.hh"
#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) {
- // TODO: Is thir the right way to do this?
- //world.addPlayerObject(this);
+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 (void) {
+ Engine::log(DEBUG, "PhysicsObject.destructor") << this /* << ": objects.size=" << ((int) world.objects.size()) */;
+
+ // world.objects.remove(this);
+
+ Engine::log(DEBUG, "PhysicsObject.destructor") << this /* << ": objects.size=" << ((int) world.objects.size()) */;
}
/**
@@ -103,10 +109,6 @@
return true;
}
-void func1() {
-
-}
-
/**
* Updates object speed and position. This function organises force
* integration and collision detection.
@@ -153,10 +155,9 @@
}
}
- if(!possibleLocation(position)) {
- Engine::log(DEBUG, "great failure") << "great failure";
- func1();
- }
+ if (!possibleLocation(position))
+ Engine::log(DEBUG, "PhysicsObject.updatePosition") << "impossible location: " << position;
+
Vector newPosition;
Vector velAfterTick;
// Calculate new position and velocity to the given references
@@ -196,26 +197,28 @@
}
- if(!possibleLocation(reached)) {
- Engine::log(DEBUG, "PhysicsObject.updatePosition") << "inside ground. diffVec: " << diffVec;
- func1();
- }
+ if (!possibleLocation(reached))
+ Engine::log(DEBUG, "PhysicsObject.updatePosition") << "impossible location: " << position << ", diffVec=" << diffVec;
// In case of some float error check the final coordinate
- if(!collided) {
- if(!possibleLocation(newPosition)) {
+ if (!collided) {
+ if (!possibleLocation(newPosition)) {
newPosition = reached;
} else {
// This means everything was ok, so no need to do anything
}
+
+ this->position = newPosition;
+
} else {
newPosition = reached;
this->position = newPosition;
+
+ // the following may delete this object, so it must be the last thing called
onCollision();
- //TODO: It should be moved before onCollision, for Shots
+
+ return;
}
- this->position = newPosition;
-// Engine::log(DEBUG, "PhysicsObject.updatePosition") << "Pos: " << this->position;
}
/**
@@ -304,6 +307,10 @@
return this->position;
}
+Vector PhysicsObject::getVelocity () {
+ return this->velocity;
+}
+
bool PhysicsObject::getFacing() {
return this->facingRight;
}
@@ -323,6 +330,23 @@
void PhysicsObject::tick (TimeMS tick_length) {
this->updatePosition(tick_length);
}
+
+void PhysicsObject::destroy (void) {
+ alive = false;
+}
+
+bool PhysicsObject::isDestroyed (void) {
+ return !alive;
+}
+
+bool PhysicsObject::removeIfDestroyed (void) {
+ if (!alive) {
+ delete this;
+ return true;
+ } else {
+ return false;
+ }
+}
void PhysicsObject::draw(CL_GraphicContext *gc) {
CL_Quad player(
--- a/src/PhysicsObject.hh Sat Dec 06 16:17:05 2008 +0000
+++ b/src/PhysicsObject.hh Sat Dec 06 17:51:19 2008 +0000
@@ -21,9 +21,6 @@
*/
class PhysicsObject {
protected:
- // This probably shouldn't be done this way.
-
-
Vector position;
Vector velocity;
float mass;
@@ -34,9 +31,11 @@
float aim; // Aim direction (half circle)
bool facingRight; // Player facing
+ bool alive;
+
PhysicsObject(PhysicsWorld &world, float mass, Vector position,
Vector velocity);
- ~PhysicsObject() {}
+ virtual ~PhysicsObject (void);
/**
@@ -159,6 +158,13 @@
Vector getPosition();
/**
+ * Get current object velocity.
+ *
+ * @return Velocity vector
+ */
+ Vector getVelocity();
+
+ /**
* Return object shape.
*
* @return Polygon points
@@ -187,6 +193,21 @@
float getAim();
/**
+ * Mark object as destroyed, it will be delete'd later
+ */
+ void destroy (void);
+
+ /*
+ * Had the object been destroyed?
+ */
+ bool isDestroyed (void);
+
+ /**
+ * Delete ourselves if we've been destroyed and return true, else return false
+ */
+ bool removeIfDestroyed (void);
+
+ /**
* Update object in physics simulation.
*/
virtual void tick (TimeMS tick_length);
--- a/src/PhysicsWorld.cc Sat Dec 06 16:17:05 2008 +0000
+++ b/src/PhysicsWorld.cc Sat Dec 06 17:51:19 2008 +0000
@@ -1,64 +1,28 @@
-#include "GameState.hh"
#include "PhysicsWorld.hh"
#include "Engine.hh"
-PhysicsWorld::PhysicsWorld (Vector gravity, Vector dimensions)
- : Terrain(1337), tick_timer(PHYSICS_TICK_MS), dimensions(dimensions),
- gravity(gravity) {
+#include <functional>
+
+PhysicsWorld::PhysicsWorld (Vector gravity, Vector dimensions) :
+ Terrain(1337), tick_timer(PHYSICS_TICK_MS), dimensions(dimensions), gravity(gravity)
+{
slots.connect(tick_timer.sig_tick(), this, &PhysicsWorld::tick);
tick_timer.start();
}
-void PhysicsWorld::addPlayerObject (PhysicsObject *object) {
- players.push_back(object);
-}
-
-void PhysicsWorld::addProjectile (Projectile *projectile) {
- projectiles.push_back(projectile);
+void PhysicsWorld::addPhysicsObject (PhysicsObject *po) {
+ objects.push_back(po);
}
-/**
- * Function pointer used to clear the projectile list
- * from those that have already been destroyd.
- */
-bool isDestroyedProjectile (Projectile* po) {
- // return po->isDestroyed();
- if (po->isDestroyed() || (po->world.tick_timer.get_ticks() > (po->birth_tick + po->age))) {
- Engine::log(DEBUG, "PhysicsWorld.isDestroyedProjectile") << "Destroying projectile: " << po;
- delete po;
- return true;
- } else {
- return false;
- }
-}
void PhysicsWorld::tick (TimeMS tick_length) {
- // Engine::log(DEBUG, "physics.apply_force") << "*tick*";
-
- for (std::list<PhysicsObject*>::iterator i = players.begin(); i != players.end(); i++) {
+ for (std::list<PhysicsObject*>::iterator i = objects.begin(); i != objects.end(); i++) {
+// Engine::log(DEBUG, "PhysicsWorld.tick") << (*i);
(*i)->tick(tick_length);
}
- for (std::list<Projectile*>::iterator i = projectiles.begin(); i != projectiles.end(); i++) {
- (*i)->tick(tick_length);
- }
-
- // Delete destroyed projectiles
- std::list<Projectile*>::iterator new_end = remove_if(projectiles.begin(), projectiles.end(), isDestroyedProjectile);
- projectiles.erase(new_end, projectiles.end());
+ // Delete destroyed objects
+ objects.remove_if(std::mem_fun(&PhysicsObject::removeIfDestroyed));
}
-void PhysicsWorld::draw(CL_GraphicContext *gc) {
- Terrain::draw(gc);
-
- // Draw players
- for (std::list<PhysicsObject*>::iterator it = players.begin(); it != players.end(); it++) {
- (*it)->draw(gc);
- }
- // Draw projectiles
- for (std::list<Projectile*>::iterator it = projectiles.begin(); it != projectiles.end(); it++) {
- (*it)->draw(gc);
- }
-}
-
--- a/src/PhysicsWorld.hh Sat Dec 06 16:17:05 2008 +0000
+++ b/src/PhysicsWorld.hh Sat Dec 06 17:51:19 2008 +0000
@@ -13,7 +13,6 @@
class PhysicsWorld;
#include "PhysicsObject.hh"
-#include "Projectile.hh"
#include "Vector.hh"
#include "Timer.hh"
#include "Config.hh"
@@ -29,9 +28,7 @@
protected:
- std::list<PhysicsObject*> players;
- std::list<Projectile*> projectiles;
-// std::vector<PhysicsObject*> objects;
+ std::list<PhysicsObject*> objects;
// Contains connections between signals and slots
CL_SlotContainer slots;
@@ -40,29 +37,19 @@
Vector dimensions;
Vector gravity;
-
-
public:
-
// Someone is going to kill me for this
Timer tick_timer;
-
PhysicsWorld(Vector gravity, Vector dimensions);
- // TODO: Replace addObject with these?
- //void addPlayerObject(PlayerObject *object);
- //void addProjectileObject(ProjectileObject *object);
-
- /**
+ /**
* Add object to the PhysicsWorld.
*
* @param object Pointer to the PhysicsObject to add.
*/
- void addPlayerObject(PhysicsObject *object);
+ void addPhysicsObject(PhysicsObject *object);
- void addProjectile(Projectile *projectile);
-
/**
* Advance one time step in physics simulation.
*/
@@ -75,8 +62,6 @@
*/
uint32_t getTick();
- virtual void draw(CL_GraphicContext *gc);
-
// TODO This should probably be protected or in GameStat or in GameStatee
};
--- a/src/Player.cc Sat Dec 06 16:17:05 2008 +0000
+++ b/src/Player.cc Sat Dec 06 17:51:19 2008 +0000
@@ -18,7 +18,9 @@
const int img_width = 10;
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) {
+ PhysicsObject(state.world, PLAYER_MASS, position, Vector(0, 0)), state(state), visible(visible), arsenal(),
+ 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
for (int i = 0; i < 5; i++) {
@@ -38,9 +40,6 @@
// XXX: this should be a PhysicsObject constructor arg
collision_elasticity = PLAYER_COLLISION_ELASTICITY;
-
- // add to player-object list
- world.addPlayerObject(this);
}
void Player::handleDig (Vector position, float radius) {
--- a/src/Player.hh Sat Dec 06 16:17:05 2008 +0000
+++ b/src/Player.hh Sat Dec 06 17:51:19 2008 +0000
@@ -9,16 +9,20 @@
#include "PhysicsObject.hh"
#include "Input.hh"
#include "Weapon.hh"
+//#include "Rope.hh"
#include <vector>
class Player : public PhysicsObject {
+ public:
+ GameState &state;
+
protected:
- GameState &state;
bool visible;
std::vector<Weapon> arsenal;
unsigned int selectedWeapon; //unsigned for x%sW not to fail
bool changing;
+// Rope rope;
int animation_step;
// default constructor for use with virtual inheritance... it's not defined
--- a/src/Projectile.cc Sat Dec 06 16:17:05 2008 +0000
+++ b/src/Projectile.cc Sat Dec 06 17:51:19 2008 +0000
@@ -2,7 +2,7 @@
#include "Timer.hh"
Projectile::Projectile(GameState &state, Vector position, Vector velocity, bool visible, float radius, TickCount age) :
- PhysicsObject(state.world, PLAYER_MASS, position, velocity), state(state), visible(visible), radius(radius), destroyed(false), age(age) {
+ PhysicsObject(state.world, PLAYER_MASS, position, velocity), state(state), visible(visible), radius(radius), age(age) {
birth_tick = world.tick_timer.get_ticks();
// Don't think these are needed anymore
std::vector<Vector> shape(4);
@@ -14,17 +14,17 @@
target_visible = false;
collision_elasticity = 0.9; // = shotType.elasticity
- world.addProjectile(this);
+ state.addProjectile(this);
}
-
+
+Projectile::~Projectile (void) {
+ state.projectiles.remove(this);
+}
void Projectile::onCollision() {
world.removeGround(position, radius);
- this->destroyed = true;
-}
-
-bool Projectile::isDestroyed (void) const {
- return this->destroyed;
+
+ destroy();
}
void Projectile::draw(CL_GraphicContext *gc) const {
@@ -57,3 +57,13 @@
}
}
}
+
+void Projectile::tick (TimeMS dt) {
+ // expire projectiles
+ if (world.tick_timer.get_ticks() > birth_tick + age)
+ destroy();
+
+ // super
+ PhysicsObject::tick(dt);
+}
+
--- a/src/Projectile.hh Sat Dec 06 16:17:05 2008 +0000
+++ b/src/Projectile.hh Sat Dec 06 17:51:19 2008 +0000
@@ -3,8 +3,8 @@
class Projectile;
+#include "GameState.hh"
#include "PhysicsObject.hh"
-#include "GameState.hh"
#include "Timer.hh"
class Projectile : public PhysicsObject {
@@ -12,7 +12,6 @@
GameState &state;
bool visible;
bool target_visible;
- bool destroyed;
float radius;
public:
@@ -20,12 +19,13 @@
TickCount age;
Projectile(GameState &state, Vector position, Vector velocity, bool visible, float radius, TickCount age=1000000000);
- ~Projectile() {};
+ virtual ~Projectile (void);
- bool isDestroyed (void) const;
- virtual void draw(CL_GraphicContext *gc) const;
-private:
- virtual void onCollision();
+ virtual void draw (CL_GraphicContext *gc) const;
+
+protected:
+ virtual void onCollision (void);
+ virtual void tick (TimeMS dt);
};
#endif
--- a/src/Terrain.hh Sat Dec 06 16:17:05 2008 +0000
+++ b/src/Terrain.hh Sat Dec 06 17:51:19 2008 +0000
@@ -142,6 +142,7 @@
* @param gc CL_GraphicContext
*/
virtual void draw(CL_GraphicContext *gc);
+
/**
* Draw part of the terrain for given graphiscontext.
*
--- a/src/Weapon.hh Sat Dec 06 16:17:05 2008 +0000
+++ b/src/Weapon.hh Sat Dec 06 17:51:19 2008 +0000
@@ -5,6 +5,7 @@
class Weapon;
#include "GameState.hh"
+#include "Projectile.hh"
#include "Timer.hh"
#include <string>