Maalla liikkumista
authorekku
Sun, 23 Nov 2008 18:19:53 +0000
changeset 94 08bebac3d0c2
parent 93 05a69f3f2ed4
child 95 10704e1df844
Maalla liikkumista
src/proto2/GameState.cc
src/proto2/GameState.hh
src/proto2/Graphics.cc
src/proto2/Physics.cc
src/proto2/Physics.hh
--- 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.