--- a/src/proto2/GameState.cc Fri Nov 21 22:42:55 2008 +0000
+++ b/src/proto2/GameState.cc Sun Nov 23 18:19:53 2008 +0000
@@ -1,5 +1,6 @@
#include "GameState.hh"
+#include "Engine.hh"
void LocalPlayer::handleMove (PlayerInput_Move input) {
float fx = 0, fy = 0;
@@ -16,9 +17,22 @@
if (input & INPUT_MOVE_RIGHT)
fx += PLAYER_MOVE_FORCE;
-
- if (fx || fy) {
- // apply force
- applyForce(Vector(fx, fy), INPUT_INTERVAL_MS);
- }
+
+ // If the player if on the ground make it crawl, jump or dig
+ if(!inAir) {
+ if(fy == 0)
+ this->position = moveVertically(fx > 0);
+ else
+ jump();
+ } else {
+
+ if(fx) {
+ // apply force
+ applyForce(Vector(fx, 0), INPUT_INTERVAL_MS);
+ }
+ }
}
+
+void Player::debugInfo (void) {
+ Engine::log(DEBUG, "Player.debugInfo") << "In air: " << this->inAir;
+}
--- a/src/proto2/GameState.hh Fri Nov 21 22:42:55 2008 +0000
+++ b/src/proto2/GameState.hh Sun Nov 23 18:19:53 2008 +0000
@@ -29,14 +29,15 @@
PhysicsObject((PhysicsWorld &) state, PLAYER_MASS, position, Vector(0, 0)), state(state), visible(visible) {
std::vector<Vector> shape(4);
- shape[0] = Vector(0,-9);
- shape[1] = Vector(6,0);
- shape[2] = Vector(0,9);
- shape[3] = Vector(-6,0);
+ shape[0] = Vector(0,-18);
+ shape[1] = Vector(6,-9);
+ shape[2] = Vector(0,0);
+ shape[3] = Vector(-6,-9);
// Initialize the shape of the player (salmiakki shape)
setShape(shape);
}
+ void debugInfo ();
};
class LocalPlayer : public Player {
--- a/src/proto2/Graphics.cc Fri Nov 21 22:42:55 2008 +0000
+++ b/src/proto2/Graphics.cc Sun Nov 23 18:19:53 2008 +0000
@@ -65,6 +65,9 @@
if (keyboard.get_keycode(CL_KEY_RIGHT))
input_move |= INPUT_MOVE_RIGHT;
+
+ if (keyboard.get_keycode(CL_KEY_I))
+ player->debugInfo();
// apply movement if applicable
if (input_move)
@@ -92,10 +95,10 @@
// draw quad
gc->fill_quad(
CL_Quad(
- (loc.x-shape[0].x) * factorX, (loc.y-shape[0].y) * factorY,
- (loc.x-shape[1].x) * factorX, (loc.y-shape[1].y) * factorY,
- (loc.x-shape[2].x) * factorX, (loc.y-shape[2].y) * factorY,
- (loc.x-shape[3].x) * factorX, (loc.y-shape[3].y) * factorY
+ (loc.x+shape[0].x) * factorX, (loc.y+shape[0].y) * factorY,
+ (loc.x+shape[1].x) * factorX, (loc.y+shape[1].y) * factorY,
+ (loc.x+shape[2].x) * factorX, (loc.y+shape[2].y) * factorY,
+ (loc.x+shape[3].x) * factorX, (loc.y+shape[3].y) * factorY
), CL_Color::green
);
}
--- a/src/proto2/Physics.cc Fri Nov 21 22:42:55 2008 +0000
+++ b/src/proto2/Physics.cc Sun Nov 23 18:19:53 2008 +0000
@@ -30,14 +30,106 @@
PhysicsObject::PhysicsObject (PhysicsWorld &world, float mass, Vector position, Vector velocity)
: world(world), mass(mass), position(position), velocity(velocity) {
+ this->inAir = true;
world.addObject(this);
}
/**
+ * TODO This method doesnt quite work as it should but
+ * it makes the worm move pretty smoothly.
+ *
+ * Make the worm walk on the ground.
+ * @return Final position.
+ */
+Vector PhysicsObject::moveVertically (bool right) {
+ Vector cursor = right ? this->position + Vector(1,0) : this->position + Vector(-1,0);
+ Vector reached = this->position;
+
+ //for(int steps = 0; steps < 3; steps++) {
+
+ // Go up but not if the wall is over two pixels
+ if(world.getType(cursor) != EMPTY) {
+ for(int height = 0, max = 3; height < max+42; height++) {
+
+ if(height >= max)
+ return reached;
+
+ cursor.y--;
+ if(world.getType(cursor) == EMPTY) {
+ // Check that the other parts of the worm don't collide with anything
+ if(possibleLocation(cursor)) {
+ reached = cursor;
+ continue;
+ } else {
+ // Can't get any further
+ return reached;
+ }
+ }
+ }
+ } else {
+ if(possibleLocation(cursor)) {
+ reached = cursor;
+ }
+ // Start checking if the lower squares are empty
+ for(int depth = 0, max = 3; depth < max+42; depth++) {
+
+ if(depth >= max) {
+ // We can start a free fall now
+ this->inAir = true;
+ // Put some speed there to make loke smoother
+ //this->velocity.y = -5;
+ return reached;
+ }
+
+ cursor.y++;
+ if(world.getType(cursor) == EMPTY) {
+ // Check that the other parts of the worm don't collide with anything
+ if(possibleLocation(cursor)) {
+ reached = cursor;
+ continue;
+ } else {
+ // Can't get any further
+ return reached;
+ }
+ }
+ }
+ }
+
+ // cursor.x += right ? 1 : -1;
+ //}
+ return reached;
+}
+
+void PhysicsObject::jump () {
+ this->velocity.y = -100;
+ this->inAir = true;
+}
+
+bool PhysicsObject::possibleLocation (Vector loc) {
+ for(unsigned int i = 0; i < this->shape.size(); i++) {
+ if(world.getType(loc+shape[i]) != EMPTY)
+ return false;
+ }
+ return true;
+}
+
+/**
* Updates object speed and position. This function organises force
* integration and collision detection.
*/
void PhysicsObject::updatePosition () {
+
+ if(!this->inAir) {
+ /*if(!forceq.empty()) {
+ if(forceq.front().y == 0) {
+ this->position = moveVertically(forceq.front().x > 0);
+ forceq.pop();
+ }
+ } */
+ return;
+ }
+ // TODO HERE
+
// Add gravity to the force queue
forceq.push(world.gravity);
@@ -79,12 +171,19 @@
for(int i = 0; i < steps; i++) {
tmpVector += unitVector;
- // Check if any of the four corners of worm collides
+
+ float minVelocity = 10;
+ // Check if any of the four corners of the worm collide
if(velocity.y > 0) {
if(world.getType(tmpVector+shape[2])) {
reached = position + unitVector*(i-1);
collided = true;
this->velocity.y *= -0.3;
+ this->velocity.x *= 0.7;
+ if(abs(this->velocity.x) < minVelocity && (abs(this->velocity.y) < minVelocity)) {
+ this->inAir = false;
+ this->velocity = Vector(0,0);
+ }
break;
}
} else {
@@ -92,6 +191,11 @@
reached = position + unitVector*(i-1);
collided = true;
this->velocity.y *= -0.3;
+ this->velocity.x *= 0.7;
+ if(abs(this->velocity.x) < minVelocity && (abs(this->velocity.y) < minVelocity)) {
+ this->inAir = false;
+ this->velocity = Vector(0,0);
+ }
break;
}
}
@@ -100,32 +204,49 @@
if(world.getType(tmpVector+shape[1])) {
reached = position + unitVector*(i-1);
collided = true;
- this->velocity.x *= -0.5;
+ this->velocity.x *= -0.6;
+ this->velocity.y *= 0.7;
+ if(abs(this->velocity.x) < minVelocity && (abs(this->velocity.y) < minVelocity)) {
+ this->inAir = false;
+ this->velocity = Vector(0,0);
+ }
break;
}
} else {
if(world.getType(tmpVector+shape[3])) {
reached = position + unitVector*(i-1);
collided = true;
- this->velocity.x *= -0.5;
+ this->velocity.x *= -0.6;
+ this->velocity.y *= 0.7;
+ if(abs(this->velocity.x) < minVelocity && (abs(this->velocity.y) < minVelocity)) {
+ this->inAir = false;
+ this->velocity = Vector(0,0);
+ }
break;
}
}
// This col. det. doesn't let worms inside the ground, but on the other hand the worms get often stuck
- /*
- if(world.getType(tmpVector+shape[0]) != EMPTY || (world.getType(tmpVector+shape[2]))) {
+ /*if(world.getType(tmpVector+shape[0]) != EMPTY || (world.getType(tmpVector+shape[2]))) {
reached = position + unitVector*(i-1);
collided = true;
this->velocity.y *= -0.3;
+ if(this->velocity.x < 3 && (this->velocity.y < 3)) {
+ this->inAir = false;
+ this->velocity = Vector(0,0);
+ }
break;
} else if(world.getType(tmpVector+shape[1]) != EMPTY || (world.getType(tmpVector+shape[3]))) {
reached = position + unitVector*(i-1);
collided = true;
- this->velocity.x *= -0.5;
+ this->velocity.x *= -0.6;
+ if(this->velocity.x < 3 && (this->velocity.y < 3)) {
+ this->inAir = false;
+ this->velocity = Vector(0,0);
+ }
break;
- }
- */
+ }*/
+
//Engine::log(DEBUG, "physics.update_position") << "didnt hit";
}
@@ -149,24 +270,9 @@
}
-bool PhysicsWorld::collided (Vector oldPos, Vector newPos) {
- int deltaX = oldPos.x - newPos.x;
- int deltaY = oldPos.y - newPos.y;
- double distance = sqrt(deltaX * deltaX + deltaY * deltaY);
- double xInc = deltaX / distance;
- double yInc = deltaY / distance;
- double currentX = oldPos.x;
- double currentY = oldPos.y;
-
- // This implementation is bit slow since it checks some squares twice.
- for(unsigned int i = 1; i < distance; i++) {
- currentX += xInc;
- currentY += yInc;
- if(terrain[(int)currentX][(int)currentY] != EMPTY)
- return true;
- }
- return false;
-}
+/*bool PhysicsWorld::collided (Vector oldPos, Vector newPos) {
+ return false;
+}*/
/**
* Integrates given force over time and stores new position to
@@ -213,8 +319,10 @@
* @param dt The time the force is applied.
*/
void PhysicsObject::applyForce (Force force, TimeMS dt) {
+
// Add applied force to the queue
forceq.push(force);
+ this->inAir = true;
}
void PhysicsObject::updatePhysics (Vector position, Vector velocity) {
--- a/src/proto2/Physics.hh Fri Nov 21 22:42:55 2008 +0000
+++ b/src/proto2/Physics.hh Sun Nov 23 18:19:53 2008 +0000
@@ -76,9 +76,12 @@
virtual void applyForce (Force force, TimeMS dt);
void updatePhysics (Vector position, Vector velocity);
+ Vector moveVertically (bool right);
+ void jump (void);
private:
void updatePosition (void);
+ bool possibleLocation (Vector loc);
/**
* Use RK4 to integrate the effects of force over a time intervall.