changed collision detection, remove old if content with new
authornireco
Thu, 20 Nov 2008 18:24:59 +0000
changeset 77 98dc9008d15f
parent 76 577f248b03b4
child 78 bbc21da84813
changed collision detection, remove old if content with new
src/proto2/Physics.cc
src/proto2/Physics.hh
src/proto2/Vector.hh
--- a/src/proto2/Physics.cc	Thu Nov 20 17:23:01 2008 +0000
+++ b/src/proto2/Physics.cc	Thu Nov 20 18:24:59 2008 +0000
@@ -4,6 +4,7 @@
 
 #include <algorithm>
 #include <functional>
+#include <cmath>
 
 PhysicsWorld::PhysicsWorld (Vector gravity, Vector dimensions)
     : tick_timer(PHYSICS_TICK_MS), gravity(gravity), dimensions(dimensions), terrain(dimensions.x, std::vector<TerrainType>(dimensions.y, DIRT) {
@@ -50,7 +51,39 @@
     
 //    Engine::log(DEBUG, "physics.update_position") << "position=" << newPosition << ", velocity=" << velocity;
 
-    bool collided = false;
+    bool collided = true;
+
+    //goes 1 unit forward every step and check if has hit anything
+    Vector unitVector = newPosition / newPosition.length();
+    Vector tmpVector = position;
+    Vector reached = position;
+    for(int i = 0; i < newPosition.length(); i++) {
+        tmpVector += unitVector;
+        if(world.getType(tmpVector) != EMPTY) {
+            // Then we have hit something
+            reached = position + unitVector*(i-1);
+            collided = false;
+            break;
+        }
+    }
+
+    // In case of some float error
+    if(!collided) {
+        if(world.getType(newPosition)) {
+            // There was error, and there is ground
+            newPosition = tmpVector;
+        } else {
+            // This means everything was ok, so no need to do anything
+        }
+    } else {
+        newPosition = reached;
+        this->velocity = Vector(0, 0);
+        //TODO: it shouldn't just stop on collision
+    }
+    this->position = newPosition;
+    
+/*
+    collided = false;
      
     if (newPosition.x < 0 || (newPosition.x > world.dimensions.x)) {
         // CRASH!
@@ -87,7 +120,7 @@
     
     if(!collided) {
         this->position = newPosition;
-    }
+    }*/
 }
 
 bool PhysicsWorld::collided (Vector oldPos, Vector newPos) {
@@ -172,3 +205,16 @@
         }
     }
 }
+
+/**
+ * Returns terrainType in given tile. ROCK if tile is out of area
+ * @param pos - coordinate of tile
+ */
+TerrainType PhysicsWorld::getType(Vector pos) {
+    int x = (int)(pos.x);
+    int y = (int)(pos.y);
+    if(x < 0 || y < 0 || x >= dimensions.x || y >= dimensions.y) {
+        return ROCK;
+    }
+    return terrain[x][y];
+}
--- a/src/proto2/Physics.hh	Thu Nov 20 17:23:01 2008 +0000
+++ b/src/proto2/Physics.hh	Thu Nov 20 18:24:59 2008 +0000
@@ -36,6 +36,8 @@
     void tick (void);
     void generateTerrain (int seed);
     bool collided (Vector oldPos, Vector newPos);
+
+    TerrainType getType(Vector pos) const;
 };
 
 class PhysicsObject {
--- a/src/proto2/Vector.hh	Thu Nov 20 17:23:01 2008 +0000
+++ b/src/proto2/Vector.hh	Thu Nov 20 18:24:59 2008 +0000
@@ -2,6 +2,7 @@
 #define COOR_H
 
 #include <iostream>
+#include <cmath>
 
 /**
  * 2D Vector class. Implements standard vector operations.
@@ -55,6 +56,9 @@
         this->x /= d;
         this->y /= d;
     }
+    T length() const {
+        return sqrt(x*x+y*y);
+    }
 };
 
 template<typename T>