--- a/src/proto2/Physics.cc Fri Nov 28 11:28:22 2008 +0000
+++ b/src/proto2/Physics.cc Fri Nov 28 11:42:56 2008 +0000
@@ -10,7 +10,7 @@
PhysicsWorld::PhysicsWorld (Vector gravity, Vector dimensions)
: tick_timer(PHYSICS_TICK_MS), tick_counter(0), gravity(gravity), dimensions(dimensions), terrain(dimensions.x, std::vector<TerrainType>(dimensions.y, DIRT)) {
- generateTerrain(1337);
+ generateTerrain(1337);
slots.connect(tick_timer.sig_timer(), this, &PhysicsWorld::tick);
tick_timer.enable();
@@ -48,78 +48,78 @@
* @return Final position.
*/
Vector PhysicsObject::walk (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;
+ Vector cursor = right ? this->position + Vector(1,0) : this->position + Vector(-1,0);
+ Vector reached = this->position;
- 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 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
- //
- // TODO it should be set inAir if it falls from a cliff
- //this->inAir = true;
+
+ if(depth >= max) {
+ // We can start a free fall now
+ //
+ // TODO it should be set inAir if it falls from a cliff
+ //this->inAir = true;
// Put some speed there to make loke smoother
- //this->velocity.y = -5;
- return reached;
- }
+ //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.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;
+ // cursor.x += right ? 1 : -1;
+ //}
+ return reached;
}
void PhysicsObject::jump () {
- velocity.y = -100;
- inAir = true;
+ velocity.y = -100;
+ 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;
+ for(unsigned int i = 0; i < this->shape.size(); i++) {
+ if(world.getType(loc+shape[i]) != EMPTY)
+ return false;
+ }
+ return true;
}
/**
@@ -136,8 +136,8 @@
}
} */
return;
- }
- // TODO HERE
+ }
+ // TODO HERE
// Add gravity to the force queue
forceq.push(world.gravity);
@@ -170,119 +170,119 @@
//goes 1 unit forward every step and check if has hit anything
Vector unitVector = (newPosition-position) / (newPosition-position).length();
- Vector tmpVector = position;
+ Vector tmpVector = position;
Vector reached = position;
- int steps = (int) (newPosition-position).length() + 2;
-
- //Engine::log(DEBUG, "physics.update_position") << unitVector-newPosition;
- //Vector foo = position+unitVector*steps-newPosition;
+ int steps = (int) (newPosition-position).length() + 2;
+
+ //Engine::log(DEBUG, "physics.update_position") << unitVector-newPosition;
+ //Vector foo = position+unitVector*steps-newPosition;
//Engine::log(DEBUG, "PhysicsObject.updatePosition") << "Virhe: "<< foo;
for(int i = 0; i < steps; i++) {
tmpVector += unitVector;
- float minVelocity = 10;
- // Check if any of the four corners of the worm collide
- for(int sh = 0; sh < 4; sh++) {
+ float minVelocity = 10;
+ // Check if any of the four corners of the worm collide
+ for(int sh = 0; sh < 4; sh++) {
if(world.getType(tmpVector+shape[sh]) != EMPTY) {
- reached = position + unitVector*(i-1);
- collided = true;
- this->bounce(world.getNormal(tmpVector+shape[sh], tmpVector-unitVector+shape[sh]));
- this->velocity *= 0.4;
- if(abs(this->velocity.x) < minVelocity && (abs(this->velocity.y) < minVelocity)) {
- this->inAir = false;
- this->velocity = Vector(0,0);
- }
- break;
- }
- }
- if(collided)
- break;
- /*
- if(velocity.y > 0) {
- if(world.getType(tmpVector+shape[2]) != EMPTY) {
- 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 {
- if(world.getType(tmpVector+shape[0]) != EMPTY) {
- 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;
- }
+ reached = position + unitVector*(i-1);
+ collided = true;
+ this->bounce(world.getNormal(tmpVector+shape[sh], tmpVector-unitVector+shape[sh]));
+ this->velocity *= 0.4;
+ if(abs(this->velocity.x) < minVelocity && (abs(this->velocity.y) < minVelocity)) {
+ this->inAir = false;
+ this->velocity = Vector(0,0);
+ }
+ break;
+ }
+ }
+ if(collided)
+ break;
+ /*
+ if(velocity.y > 0) {
+ if(world.getType(tmpVector+shape[2]) != EMPTY) {
+ 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 {
+ if(world.getType(tmpVector+shape[0]) != EMPTY) {
+ 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;
+ }
}
- if(velocity.x > 0) {
- if(world.getType(tmpVector+shape[1]) != EMPTY) {
- reached = position + unitVector*(i-1);
- collided = true;
- 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]) != EMPTY) {
- reached = position + unitVector*(i-1);
- collided = true;
- 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;
- }
+ if(velocity.x > 0) {
+ if(world.getType(tmpVector+shape[1]) != EMPTY) {
+ reached = position + unitVector*(i-1);
+ collided = true;
+ 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]) != EMPTY) {
+ reached = position + unitVector*(i-1);
+ collided = true;
+ 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]) != EMPTY)) {
+
+ // 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]) != EMPTY)) {
reached = position + unitVector*(i-1);
collided = true;
- this->velocity.y *= -0.3;
- if(abs(this->velocity.x) < minVelocity && (abs(this->velocity.y) < minVelocity)) {
- this->inAir = false;
- this->velocity = Vector(0,0);
- }
+ this->velocity.y *= -0.3;
+ if(abs(this->velocity.x) < minVelocity && (abs(this->velocity.y) < minVelocity)) {
+ this->inAir = false;
+ this->velocity = Vector(0,0);
+ }
break;
}
- if(world.getType(tmpVector+shape[1]) != EMPTY || (world.getType(tmpVector+shape[3]) != EMPTY)) {
+ if(world.getType(tmpVector+shape[1]) != EMPTY || (world.getType(tmpVector+shape[3]) != EMPTY)) {
reached = position + unitVector*(i-1);
collided = true;
- this->velocity.x *= -0.6;
- if(abs(this->velocity.x) < minVelocity && (abs(this->velocity.y) < minVelocity)) {
- this->inAir = false;
- this->velocity = Vector(0,0);
- }
+ this->velocity.x *= -0.6;
+ if(abs(this->velocity.x) < minVelocity && (abs(this->velocity.y) < minVelocity)) {
+ this->inAir = false;
+ this->velocity = Vector(0,0);
+ }
break;
- }*/
-
- //Engine::log(DEBUG, "physics.update_position") << "didnt hit";
+ }*/
+
+ //Engine::log(DEBUG, "physics.update_position") << "didnt hit";
}
// In case of some float error check the final coordinate
if(!collided) {
if(world.getType(newPosition+shape[0]) != EMPTY || (world.getType(newPosition+shape[1]) != EMPTY)
- || (world.getType(newPosition+shape[2]) != EMPTY) || (world.getType(newPosition+shape[3]) != EMPTY)) {
+ || (world.getType(newPosition+shape[2]) != EMPTY) || (world.getType(newPosition+shape[3]) != EMPTY)) {
- Engine::log(DEBUG, "physics.update_position") << "didnt hit";
- // There was error, and there is ground
+ Engine::log(DEBUG, "physics.update_position") << "didnt hit";
+ // There was error, and there is ground
//newPosition = tmpVector;
} else {
// This means everything was ok, so no need to do anything
@@ -326,38 +326,38 @@
* Computes hitten wall's normal. Calculated from 3*3 grid
*/
Vector PhysicsWorld::getNormal (Vector hitPoint, Vector prevPoint) {
- // Search free points with bfs and put them to vector
- std::vector<Vector> frees;
- Vector hit = Vector((int)hitPoint.x, (int)hitPoint.y);
- Vector prev = Vector((int)prevPoint.x, (int)prevPoint.y);
+ // Search free points with bfs and put them to vector
+ std::vector<Vector> frees;
+ Vector hit = Vector((int)hitPoint.x, (int)hitPoint.y);
+ Vector prev = Vector((int)prevPoint.x, (int)prevPoint.y);
- assert(hit != prev);
-
- int dirIdx = getDirectionIndex(prev-hit);
- float tmp1 = hit.x-prev.x;
- float tmp2 = hit.y-prev.y;
+ assert(hit != prev);
+
+ int dirIdx = getDirectionIndex(prev-hit);
+ float tmp1 = hit.x-prev.x;
+ float tmp2 = hit.y-prev.y;
// Engine::log(DEBUG, "physics.getNormal ") << dirIdx << " " << tmp1 << " " << tmp2;
- for(int i = 1; i <= 2; i++) {
- if(getType(hit+DIRECTIONS[(dirIdx+i) % 8]) == EMPTY)
- frees.push_back(DIRECTIONS[(dirIdx+i) % 8]);
- else
- break;
- }
- for(int i = 1; i <= 2; i++) {
- if(getType(hit+DIRECTIONS[(dirIdx-i+8) % 8]) == EMPTY)
- frees.push_back(DIRECTIONS[(dirIdx-i+8) % 8]);
- else
- break;
- }
+ for(int i = 1; i <= 2; i++) {
+ if(getType(hit+DIRECTIONS[(dirIdx+i) % 8]) == EMPTY)
+ frees.push_back(DIRECTIONS[(dirIdx+i) % 8]);
+ else
+ break;
+ }
+ for(int i = 1; i <= 2; i++) {
+ if(getType(hit+DIRECTIONS[(dirIdx-i+8) % 8]) == EMPTY)
+ frees.push_back(DIRECTIONS[(dirIdx-i+8) % 8]);
+ else
+ break;
+ }
frees.push_back(DIRECTIONS[dirIdx]);
- Vector normal(0,0);
- for(unsigned int i = 0; i < frees.size(); i++) {
- normal += frees[i];
- }
+ Vector normal(0,0);
+ for(unsigned int i = 0; i < frees.size(); i++) {
+ normal += frees[i];
+ }
Engine::log(DEBUG, "physics.getNormal ") << "normal: " << normal;
- return normal;
+ return normal;
}
/**
@@ -373,7 +373,7 @@
}
/*bool PhysicsWorld::collided (Vector oldPos, Vector newPos) {
- return false;
+ return false;
}*/
/**
@@ -420,7 +420,7 @@
// Add applied force to the queue
forceq.push(force);
- this->inAir = true;
+ this->inAir = true;
}
void PhysicsObject::changeAim(float da) {
@@ -459,7 +459,7 @@
}
void PhysicsObject::setShape (std::vector<Vector> shape) {
- this->shape = shape;
+ this->shape = shape;
}
void PhysicsObject::tick () {
@@ -490,12 +490,12 @@
int range = rand()%(max_range-min_range)+min_range;
// put first circle in the middle of the cave
- // so that we have some area we can certainly spawn into
- if(i == 0) {
- midx = dimensions.x/2;
- midy = dimensions.y/2;
- range = 150;
- }
+ // so that we have some area we can certainly spawn into
+ if(i == 0) {
+ midx = dimensions.x/2;
+ midy = dimensions.y/2;
+ range = 150;
+ }
TerrainType type = EMPTY;
if(rand()%rock_rarity == 0) {
@@ -518,11 +518,35 @@
* Returns terrainType in given tile. ROCK if tile is out of area
* @param pos - coordinate of tile
*/
-TerrainType PhysicsWorld::getType(Vector pos) const {
- int x = (int)(pos.x);
- int y = (int)(pos.y);
+TerrainType PhysicsWorld::getType(int x, int y) const {
if(x < 0 || y < 0 || x >= dimensions.x || y >= dimensions.y) {
return ROCK;
}
return terrain[x][y];
}
+TerrainType PhysicsWorld::getType(Vector pos) const {
+ int x = (int)(pos.x);
+ int y = (int)(pos.y);
+ return getType(x, y);
+}
+
+/**
+ * Removes ground from given circle. ROCK is not removed.
+ * @param (x, y) or pos - center of circle.
+ * @param r - radius of circle
+ */
+void PhysicsWorld::removeGround(int x, int y, float r) {
+ for(int i = x-(int)r; i < x+r; i++) {
+ for(int j = y-(int)r; j < y+r; j++) {
+ if(getType(i, j) != ROCK) {
+ if((i-x)*(i-x)+(j-y)*(j-y) < r*r) {
+ // Safe because getType returns ROCK if tile is out of bounds
+ terrain[i][j] = EMPTY;
+ }
+ }
+ }
+ }
+}
+void PhysicsWorld::removeGround(Vector pos, float r) {
+ removeGround((int)pos.x, (int)pos.y, r);
+}