--- a/src/Network/Server.cc Sat Jan 24 00:47:54 2009 +0200
+++ b/src/Network/Server.cc Sat Jan 24 01:19:38 2009 +0200
@@ -97,7 +97,7 @@
// the initial NETMSG_PLAYER_HELLO
NetworkPacket hello_pkt;
- hello_pkt.write_vector(position);
+ hello_pkt.write_vector(getPosition());
this->send_to(node, NETMSG_SERVER_HELLO, hello_pkt, true);
@@ -110,7 +110,7 @@
assert(player != this);
// write packet
- player_pkt.write_vector(player->position);
+ player_pkt.write_vector(player->getPosition());
player->send_to(node, NETMSG_PLAYER_INFO, player_pkt, true);
@@ -279,8 +279,8 @@
(inAir ? NETWORK_PHYSICS_INAIR : 0) |
(facing == FACING_RIGHT ? NETWORK_PHYSICS_FACE_RIGHT : 0);
- pkt.write_vector(position);
- pkt.write_vector(velocity);
+ pkt.write_vector(getPosition());
+ pkt.write_vector(getVelocity());
pkt.write_uint8(flags);
pkt.write_float32(aim);
--- a/src/PhysicsObject.cc Sat Jan 24 00:47:54 2009 +0200
+++ b/src/PhysicsObject.cc Sat Jan 24 01:19:38 2009 +0200
@@ -26,10 +26,10 @@
}
PhysicsObject::~PhysicsObject (void) {
-// Engine::log(DEBUG, "PhysicsObject.destructor") << this /* << ": objects.size=" << ((int) world.objects.size()) */;
+
}
-/**
+/*
* Player walks on floor.
*/
Vector PhysicsObject::walk_one_step (float partial, bool right) {
@@ -134,31 +134,37 @@
// a force towards that
if (pivot != NULL) {
applyForce(getPivotForce());
+
if (pivot->type == PLAYER) {
- pivot->applyForce(getPivotForce()*(-1));
+ pivot->applyForce(-getPivotForce());
}
}
std::pair<Force, TimeMS> force;
std::queue<std::pair<Force, TimeMS> > newfq;
+
Force total;
+
while (!forceq.empty()) {
force = forceq.front();
+
if (force.second > dt) {
force.second -= dt;
newfq.push(force);
}
+
total += force.first;
forceq.pop();
}
+
forceq = newfq;
// If the player has stopped and there's some ground under some of the 3 some of the 3t
// set inAir false
if (this->velocity == Vector(0,0)) {
- this->inAir = !world.terrain.collides(this->position+shape[1]+Vector(0, 1))
- && !world.terrain.collides(this->position+shape[2]+Vector(0, 1))
- && !world.terrain.collides(this->position+shape[3]+Vector(0, 1));
+ this->inAir = !world.terrain.collides(this->position + shape[1] + Vector(0, 1))
+ && !world.terrain.collides(this->position + shape[2] + Vector(0, 1))
+ && !world.terrain.collides(this->position + shape[3] + Vector(0, 1));
// If, however, there's a force caused by a bomb, e.g., set it in air.
// Still, we have to be able to separate forces caused by walking attempts
// and bombs etc (+0.1 because float comparison can be dangerous)
@@ -166,7 +172,7 @@
this->inAir = true;
}
- if(!possibleLocation(position)) {
+ if (!possibleLocation(position)) {
//if we are trapped in ground form dirtball or something
//we might want to just return and set velocity to some value
//return;
@@ -200,7 +206,7 @@
const Vector diffVec = newPosition - position;
const Vector unitVector = diffVec / diffVec.length();
- if(unitVector == Vector(0, 0)) {
+ if (unitVector == Vector(0, 0)) {
return;
}
Vector reached = position;
@@ -239,15 +245,16 @@
if (!collided) {
if (!possibleLocation(newPosition)) {
newPosition = reached;
+
} else {
// This means everything was ok, so no need to do anything
}
- setPosition (newPosition);
+ setPosition(newPosition);
} else {
newPosition = reached;
- setPosition (newPosition);
+ setPosition(newPosition);
// the following may delete this object, so it must be the last thing called
onCollision(collisionPoint);
@@ -264,9 +271,11 @@
// normal.sqrLength can't be 0 when got from getNormal()
if (normal.sqrLength() != 0) {
Vector nvel = velocity;
+
// We project the velocity on normal and remove twice that much from velocity
- nvel = nvel - ((2)*((nvel*normal)/(normal*normal))*normal);
+ nvel = nvel - (2 * ((nvel * normal) / (normal * normal)) * normal);
velocity = nvel;
+
// We lose some of our speed on collision
this->velocity *= this->collision_elasticity;
}
@@ -278,38 +287,32 @@
* @param force Force vector.
* @param dt The time the force is applied (<=PHYSICS_TICK_MS)
*/
-void PhysicsObject::integrate(Force force, TimeMS dt, Vector &posAfterTick, Vector &velAfterTick) {
+void PhysicsObject::integrate (Force force, TimeMS dt, Vector &posAfterTick, Vector &velAfterTick) {
posAfterTick = position;
velAfterTick = velocity;
+
Derivative tmpd;
Derivative k1 = evaluate(force, 0, tmpd, posAfterTick, velAfterTick);
Derivative k2 = evaluate(force, dt / 2, k1, posAfterTick, velAfterTick);
Derivative k3 = evaluate(force, dt / 2, k2, posAfterTick, velAfterTick);
Derivative k4 = evaluate(force, dt, k3, posAfterTick, velAfterTick);
-
- const Vector dxdt = (k1.dx + (k2.dx + k3.dx) * 2.0f + k4.dx) * 1.0f/6.0f;
- const Vector dvdt = (k1.dv + (k2.dv + k3.dv) * 2.0f + k4.dv) * 1.0f/6.0f;
+ const Vector dxdt = (k1.dx + (k2.dx + k3.dx) * 2.0f + k4.dx) * 1.0f / 6.0f;
+ const Vector dvdt = (k1.dv + (k2.dv + k3.dv) * 2.0f + k4.dv) * 1.0f / 6.0f;
- // Engine::log(DEBUG, "PhysicsObject.integrate") << "Changes: "<< dxdt << " " << dvdt << " Time: " <<dt;
- posAfterTick = posAfterTick + (dxdt * dt)/1000;
- velAfterTick = velAfterTick + (dvdt * dt)/1000;
- //Engine::log(DEBUG, "PhysicsObject.integrate") << "velAfterTick: " << velAfterTick;
+ posAfterTick = posAfterTick + (dxdt * dt) / 1000;
+ velAfterTick = velAfterTick + (dvdt * dt) / 1000;
}
-Derivative PhysicsObject::evaluate(Force force, TimeMS dt, Derivative &d, const Vector &posAfterTick, const Vector &velAfterTick) {
- Vector curPos = posAfterTick + (d.dx*dt)/1000;
- Vector curVel = velAfterTick + (d.dv*dt)/1000;
+Derivative PhysicsObject::evaluate (Force force, TimeMS dt, const Derivative &d, const Vector &posAfterTick, const Vector &velAfterTick) {
+ Vector curPos = posAfterTick + (d.dx * dt) / 1000;
+ Vector curVel = velAfterTick + (d.dv * dt) / 1000;
- Derivative out;
- out.dx = curVel;
- out.dv = acceleration(force);
- //Engine::log(DEBUG, "PhysicsObject.evaluate") << "Out.dx: " << out.dx;
- return out;
+ return Derivative(curVel, acceleration(force));
}
Vector PhysicsObject::acceleration(const Force &force) {
- return (force/mass);
+ return (force / mass);
}
void PhysicsObject::applyForce (Force force, TimeMS dt) {
@@ -325,14 +328,6 @@
//Engine::log(DEBUG, "PhysicsObject.changeAim") << "Player aim: " << this->aim;
}
-ObjectType PhysicsObject::getType (void) const {
- return this->type;
-}
-
-void PhysicsObject::setFacing (FacingDirection facing) {
- this->facing = facing;
-}
-
void PhysicsObject::updatePhysics (Vector position, Vector velocity, bool inAir, FacingDirection facing, float aim) {
setPosition (position);
this->velocity = velocity;
@@ -341,50 +336,14 @@
this->aim = aim;
}
-Vector PhysicsObject::getPosition (void) const {
- return position;
-}
-
-Vector PhysicsObject::getPreviousPosition (void) const {
- return previousPosition;
-}
-
PixelCoordinate PhysicsObject::getCoordinate (void) const {
return world.terrain.getPixelCoordinate(position);
}
-Vector PhysicsObject::getVelocity (void) const {
- return velocity;
-}
-
-FacingDirection PhysicsObject::getFacing (void) const {
- return facing;
-}
-
-float PhysicsObject::getAim (void) const {
- return aim;
-}
-
Vector PhysicsObject::getDirection (void) const {
return facing == FACING_RIGHT ? Vector(cos(aim), -sin(aim)) : Vector(-cos(aim), -sin(aim));
}
-const std::vector<Vector>& PhysicsObject::getShape () const {
- return shape;
-}
-
-void PhysicsObject::setShape (std::vector<Vector> shape) {
- this->shape = shape;
-}
-
-PhysicsObject *PhysicsObject::getPivot (void) {
- return this->pivot;
-}
-
-void PhysicsObject::setPivot (PhysicsObject *pivot) {
- this->pivot = pivot;
-}
-
void PhysicsObject::tick (TimeMS tick_length) {
this->updatePosition(tick_length);
}
@@ -412,10 +371,6 @@
shouldDelete = true;
}
-bool PhysicsObject::isAlive (void) {
- return alive;
-}
-
bool PhysicsObject::removeIfDestroyed (void) {
if (!alive) {
if (shouldDelete)
@@ -433,7 +388,7 @@
}
bool PhysicsObject::collides (const PhysicsObject &obj) {
- const std::vector<Vector> oShape = obj.getShape();
+ const std::vector<Vector> oShape = obj.shape;
Vector p1, p2, p3;
int8_t sign, nsign;
for (std::vector<Vector>::const_iterator i = oShape.begin(); i != oShape.end(); i++) { // For every point in other shape
@@ -470,6 +425,18 @@
this->position = pos;
}
-void PhysicsObject::setVelocity (Vector velocity) {
- this->velocity = velocity;
+void PhysicsObject::reset (void) {
+ // zero velocity
+ this->velocity = Vector(0, 0);
+
+ // disable
+ disable();
}
+
+void PhysicsObject::resume (Vector position) {
+ // update position
+ setPosition(position);
+
+ // enable again
+ enable();
+}
--- a/src/PhysicsObject.hh Sat Jan 24 00:47:54 2009 +0200
+++ b/src/PhysicsObject.hh Sat Jan 24 01:19:38 2009 +0200
@@ -30,33 +30,41 @@
* PhysicsObject class. Represents an object in the physics simulation.
*/
class PhysicsObject {
-public:
+protected:
/** Reference to PhysicsWorld. */
PhysicsWorld &world;
-protected:
- /** Object position. */
+private:
+ /** Position */
Vector position;
- /** Object position on previous physics tick. */
+ /** Position at previous tick */
Vector previousPosition;
- /** Object velocity */
+ /** Velocity */
Vector velocity;
- /** Object mass. */
- float mass;
+ /** Mass */
+ float mass;
+
+ /** Object's shape, polygon vertices */
+ std::vector<Vector> shape;
+ /** Force queue, emptied on every physics tick */
+ std::queue<std::pair<Force, TimeMS> > forceq;
+
+
+protected:
/** Tells if the object is "on the ground" */
bool inAir;
- /** Object elasticity. */
+ /** Object elasticity */
float collision_elasticity;
- /** Aim angle in radians. */
+ /** Aim angle in radians */
float aim;
- /** Player facing. */
+ /** Player facing */
FacingDirection facing;
/** Specifies if the object should be simulated */
@@ -111,7 +119,9 @@
*
* @param facingRight True if player is facing right.
*/
- void setFacing (FacingDirection facing);
+ void setFacing (FacingDirection facing) {
+ this->facing = facing;
+ }
/**
* Makes the player jump in the air.
@@ -152,13 +162,6 @@
void disable (void);
private:
- /** Objects shape. Edgepoints of the polygon */
- std::vector<Vector> shape;
-
- /** Object force queue. The queue is emptied on every physics
- tick.*/
- std::queue<std::pair<Force, TimeMS> > forceq;
-
/**
* Handle player movement and apply forces.
*
@@ -184,7 +187,7 @@
* @param d Previous derivative
* @return Derivative
*/
- Derivative evaluate (Force force, TimeMS dt, Derivative &d, const Vector &posAfterTick, const Vector &velAfterTick);
+ Derivative evaluate (Force force, TimeMS dt, const Derivative &d, const Vector &posAfterTick, const Vector &velAfterTick);
/**
* Return object acceleration with given force.
@@ -221,7 +224,9 @@
*
* @return Object type
*/
- ObjectType getType (void) const;
+ ObjectType getType (void) const {
+ return type;
+ }
/**
* Checks if it is possible for the object to be in the given
@@ -236,14 +241,18 @@
*
* @return position vector
*/
- Vector getPosition (void) const;
+ Vector getPosition (void) const {
+ return position;
+ }
/**
* Get previous object position.
*
* @return position vector
*/
- Vector getPreviousPosition (void) const;
+ Vector getPreviousPosition (void) const {
+ return previousPosition;
+ }
/**
* Get current object screen coordinates
@@ -257,36 +266,27 @@
*
* @return Velocity vector
*/
- Vector getVelocity (void) const;
-
-
- /**
- * Return object shape.
- *
- * @return Polygon points
- */
- const std::vector<Vector>& getShape (void) const;
-
- /**
- * Set object shape.
- *
- * @param shape Vector containing polygon points
- */
- void setShape(std::vector<Vector> shape);
+ Vector getVelocity (void) const {
+ return velocity;
+ }
/**
* Return object facing.
*
* @return Object facing (true if facing right)
*/
- FacingDirection getFacing (void) const;
+ FacingDirection getFacing (void) const {
+ return facing;
+ }
/**
* Return object aim angle.
*
* @return Object aim angle
*/
- float getAim (void) const;
+ float getAim (void) const {
+ return aim;
+ }
/**
* Get object direction.
@@ -305,7 +305,9 @@
*
* @return Is the object alive?
*/
- bool isAlive (void);
+ bool isAlive (void) const {
+ return alive;
+ }
/**
* Tells the state of the object.
@@ -319,12 +321,24 @@
*
* @param pivot Pivot object
*/
- void setPivot (PhysicsObject *pivot);
+ void setPivot (PhysicsObject *pivot) {
+ this->pivot = pivot;
+ }
/**
* Return the pivot object pointer.
*/
- PhysicsObject *getPivot (void);
+ PhysicsObject *getPivot (void) {
+ return pivot;
+ }
+
+ /**
+ * Compute the force that this object (as a pivot) exerts on the given object
+ *
+ * @param bob Othe object
+ * @return Force
+ */
+ virtual Vector getPivotForce (void);
/**
* Checks if object collides with other objects
@@ -335,14 +349,6 @@
bool collides (const PhysicsObject &obj);
/**
- * Compute the force that this object (as a pivot) exerts on the given object
- *
- * @param bob Othe object
- * @return Force
- */
- virtual Vector getPivotForce (void);
-
- /**
* Update object in physics simulation.
*
* @param tick_length Length of the physics tick
@@ -351,6 +357,17 @@
protected:
/**
+ * Set object shape.
+ *
+ * XXX: constructor
+ *
+ * @param shape Vector containing polygon points
+ */
+ void setShape(std::vector<Vector> shape) {
+ this->shape = shape;
+ }
+
+ /**
* Update object position, also updating our previous position
*
* @param pos new position
@@ -362,13 +379,35 @@
*
* @param velocity new velocity
*/
- void setVelocity (Vector velocity);
+ void setVelocity (Vector velocity) {
+ this->velocity = velocity;
+ }
+
+ /**
+ * Reset state and disable, ready to be resume()'d again in a different place
+ */
+ void reset (void);
+
+ /**
+ * Resume after a reset() at the given position with a zero velocity
+ */
+ void resume (Vector position);
};
/** Helper struct for the integration */
struct Derivative {
- Vector dx; // Velocity
- Vector dv; // Acceleration
+ /**
+ * Velocity
+ */
+ Vector dx;
+
+ /**
+ * Acceleration
+ */
+ Vector dv;
+
+ Derivative () : dx(), dv() { }
+ Derivative (Vector dx, Vector dv) : dx(dx), dv(dv) { }
};
/**
--- a/src/Player.cc Sat Jan 24 00:47:54 2009 +0200
+++ b/src/Player.cc Sat Jan 24 01:19:38 2009 +0200
@@ -68,19 +68,16 @@
}
void Player::spawn (Vector position) {
- // dig hole
+ // dig hole to make room
world.terrain.removeGround(position, PLAYER_DIG_RADIUS);
- // update position
- setPosition(position);
-
// reset health
health = PLAYER_HEALTH;
// XXX: reload weapons
- // enable
- enable();
+ // resume at our new position
+ resume(position);
}
void Player::die (bool start_timer) {
@@ -90,12 +87,9 @@
// we don't have a rope anymore
rope.release();
- // disable our PhysicsObject
- disable();
+ // reset/disable our PhysicsObject
+ reset();
- // XXX: PhysicsObject::reset
- this->velocity = Vector(0, 0);
-
if (start_timer) {
// start respawn timer
respawn_timer.fire_once();
@@ -163,8 +157,8 @@
*/
void LocalPlayer::fireWeapon (Weapon *weapon) {
// calculate new position and velocity
- Vector shotPosition = position + getDirection() * PROJECTILE_START_DISTANCE;
- Vector shotVelocity = velocity + getDirection() * weapon->getSpeed();
+ Vector shotPosition = getPosition() + getDirection() * PROJECTILE_START_DISTANCE;
+ Vector shotVelocity = getVelocity() + getDirection() * weapon->getSpeed();
// execute
handleFireWeapon(weapon, shotPosition, shotVelocity);
@@ -189,15 +183,16 @@
// handle movement left/right by applying a horizontal force, but limit the player's speed
// also update facing if needed
if (!((input & INPUT_MOVE_LEFT) && (input & INPUT_MOVE_RIGHT))) {
+ // XXX: this should be physics...
if (input & INPUT_MOVE_LEFT) {
- if (velocity.x > -PLAYER_MAX_SPEED)
+ if (getVelocity().x > -PLAYER_MAX_SPEED)
move_force.x -= PLAYER_MOVE_FORCE;
setFacing(FACING_LEFT);
}
if (input & INPUT_MOVE_RIGHT) {
- if (velocity.x < PLAYER_MAX_SPEED)
+ if (getVelocity().x < PLAYER_MAX_SPEED)
move_force.x += PLAYER_MOVE_FORCE;
setFacing(FACING_RIGHT);
@@ -226,7 +221,7 @@
// outsource digging to Player::handleDig, since this modifies the Terrain and Network needs to know
if (input & INPUT_DIG)
- handleDig(position, PLAYER_DIG_RADIUS);
+ handleDig(getPosition(), PLAYER_DIG_RADIUS);
// change weapon back/forth
if (input & INPUT_CHANGE_PREV)
@@ -349,6 +344,9 @@
skin_surface = CL_Surface(PLAYER_SKIN_PATH);
skin_loaded = true;
}
+
+ // screen position
+ PixelCoordinate position = getCoordinate();
// calulate where to draw the worm
CL_Rectf destination(
--- a/src/Projectile.cc Sat Jan 24 00:47:54 2009 +0200
+++ b/src/Projectile.cc Sat Jan 24 01:19:38 2009 +0200
@@ -68,7 +68,7 @@
void Projectile::tick (TimeMS dt) {
// expire projectiles
if (world.getTicks() > birth_tick + weapon->getExpire())
- onDestroy(position, true);
+ onDestroy(getPosition(), true);
// super
PhysicsObject::tick(dt);
--- a/src/Rope.cc Sat Jan 24 00:47:54 2009 +0200
+++ b/src/Rope.cc Sat Jan 24 01:19:38 2009 +0200
@@ -78,7 +78,9 @@
// attached to something!
state = ROPE_FIXED;
- velocity = Vector(0,0);
+
+ // XXX: reset, except we override tick() in ugly ways
+ setVelocity(Vector(0,0));
// 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.
@@ -204,7 +206,7 @@
return;
// If there's no ground on the pivot point anymore, release the rope
- if (!world.terrain.collides(position)) {
+ if (!world.terrain.collides(getPosition())) {
// XXX: move to some new method
state = ROPE_FLYING;
length = ROPE_LENGTH;