# HG changeset patch # User ekku # Date 1227464393 0 # Node ID 08bebac3d0c2c954b622b7664a5f91d2548a3674 # Parent 05a69f3f2ed49f8055b4d4bffd203d8f877e9adc Maalla liikkumista diff -r 05a69f3f2ed4 -r 08bebac3d0c2 src/proto2/GameState.cc --- 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; +} diff -r 05a69f3f2ed4 -r 08bebac3d0c2 src/proto2/GameState.hh --- 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 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 { diff -r 05a69f3f2ed4 -r 08bebac3d0c2 src/proto2/Graphics.cc --- 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 ); } diff -r 05a69f3f2ed4 -r 08bebac3d0c2 src/proto2/Physics.cc --- 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) { diff -r 05a69f3f2ed4 -r 08bebac3d0c2 src/proto2/Physics.hh --- 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.