Documenting more, cleaning variables. This code needs some serious
rewriting. (And we havent too many features either)
#ifndef PHYSICS_HH
#define PHYSICS_HH
#include "Vector.hh"
#include <vector>
#include <queue>
#include <ClanLib/core.h>
typedef uint16_t TimeMS;
const TimeMS PHYSICS_TICK_MS = 10;
enum TerrainType {EMPTY, DIRT, ROCK};
const Vector DIRECTIONS[] = { Vector(0,-1), Vector(1,-1), Vector(1,0), Vector(1,1),
Vector(0,1), Vector(-1,1), Vector(-1,0), Vector(-1,-1) };
// forward-declare
class PhysicsObject;
typedef Vector Force;
struct Derivative;
class PhysicsWorld {
friend class PhysicsObject;
private:
CL_Timer tick_timer;
uint32_t tick_counter;
protected:
std::vector<PhysicsObject*> objects;
Vector gravity;
Vector dimensions;
std::vector<std::vector<TerrainType> > terrain;
CL_SlotContainer slots;
PhysicsWorld (Vector gravity, Vector dimensions);
public:
/**
* Adds objects to the physicsworld.
*
* @param object Pointer to PhysicsObject to add.
*/
void addObject (PhysicsObject *object);
/**
* Advance one time step in physics simulation.
*/
void tick (void);
/**
* Get current tick in physics simulation.
*/
uint32_t getTick (void);
/**
* Generate random terrain.
*/
void generateTerrain (int seed);
/**
* TODO: We'll have to think about this.
*/
bool collided (Vector prevPos, Vector newPos);
/**
* Return a normal for the wall that has been hit.
*
* @param hitPoint The point of the wall that has been hit.
* @param prevPoint The point from where we were coming.
*/
Vector getNormal(Vector hitPoint, Vector prevPoint);
/**
* Return terrain type in specific position.
*
* @param x x-coordinate
* @param y y-coordinate
*/
TerrainType getType(int x, int y) const;
/**
* Return terrain type in specific position.
*
* @param pos Position vector
*/
TerrainType getType(Vector pos) const;
/**
* Remove ground from the terrain. Removes a circle with given
* radius.
*
* @param x center x coordinate
* @param y center y coordinate
* @param r circle radius
*/
void removeGround(int x, int y, float r);
/**
* Remove ground from the terrain. Removes a circle with given
* radius.
*
* @param pos circle center
* @param r circle radius
*/
void removeGround(Vector pos, float r);
};
class PhysicsObject {
protected:
PhysicsWorld &world;
float mass;
Vector position;
Vector velocity;
float aim; // Aim direction (half circle)
bool facingRight; // Player facing
bool inAir; // Is the object "on the ground"
// Shape of the object. We use a polygon with 4 edges
// to make easy to draw with Clanlib. The coordinates
// are relative to the center point.
std::vector<Vector> shape;
// Force queue that is emptied on every tick
std::queue<Force> forceq;
Vector posAfterTick;
Vector velAfterTick;
/**
* @param shape Corners of the four sided polygon.
*/
PhysicsObject (PhysicsWorld &world, float mass, Vector position, Vector velocity);
~PhysicsObject() {}
/**
* Adds force to the force queue. Force queue is emptied on each
* tick. Forces that last over one tick are also handled. This
* function is only used to handle in air movement.
*
* @param force Force vector.
* @param dt The time the force is applied.
*/
virtual void applyForce (Force force);
/**
* Changes player aim
*/
void changeAim(float da);
/**
* Set player facing.
*/
void setFacing(bool right);
/**
* Called on network clients to sync state from server
*/
void updatePhysics (Vector position, Vector velocity, bool inAir);
/**
* Handle ground movement
*
* @return new position
*/
Vector walk (bool right);
/**
* Handle ground-jumping
*/
void jump (void);
/**
* Handle ground-bounce
*/
void bounce (Vector normal);
private:
void updatePosition (void);
bool possibleLocation (Vector loc);
/**
* Use RK4 to integrate the effects of force over a time intervall.
*/
void integrate(Force force, TimeMS dt);
Derivative evaluate(Force force, TimeMS dt, Derivative &d);
Vector acceleration(const Force &force);
virtual void onCollision() {}
public:
Vector getPosition (void);
std::vector<Vector>& getShape(void);
void setShape (std::vector<Vector> shape);
bool getFacing(void);
float getAim(void);
void tick (void);
};
struct Derivative {
Vector dx; // Velocity
Vector dv; // Acceleration
};
#endif