# HG changeset patch # User ekku # Date 1227560916 0 # Node ID 2e7c8ab485dea975b096169bd61f8225a503caea # Parent 4a801210096c0c639a7f9630c10bad1942c18d1f Voi tuska mun kanssani diff -r 4a801210096c -r 2e7c8ab485de src/proto2/Physics.cc --- a/src/proto2/Physics.cc Mon Nov 24 17:14:29 2008 +0000 +++ b/src/proto2/Physics.cc Mon Nov 24 21:08:36 2008 +0000 @@ -174,8 +174,24 @@ float minVelocity = 10; // Check if any of the four corners of the worm collide - /*if(velocity.y > 0) { - if(world.getType(tmpVector+shape[2])) { + for(int sh = 0; sh < 4; sh++) { + if(world.getType(tmpVector+shape[2]) != EMPTY) { + reached = position + unitVector*(i-1); + collided = true; + this->bounce(world.getNormal(tmpVector+shape[2], tmpVector-unitVector+shape[2])); + this->velocity *= 0.6; + 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; @@ -187,7 +203,7 @@ break; } } else { - if(world.getType(tmpVector+shape[0])) { + if(world.getType(tmpVector+shape[0]) != EMPTY) { reached = position + unitVector*(i-1); collided = true; this->velocity.y *= -0.3; @@ -201,7 +217,7 @@ } if(velocity.x > 0) { - if(world.getType(tmpVector+shape[1])) { + if(world.getType(tmpVector+shape[1]) != EMPTY) { reached = position + unitVector*(i-1); collided = true; this->velocity.x *= -0.6; @@ -213,7 +229,7 @@ break; } } else { - if(world.getType(tmpVector+shape[3])) { + if(world.getType(tmpVector+shape[3]) != EMPTY) { reached = position + unitVector*(i-1); collided = true; this->velocity.x *= -0.6; @@ -224,10 +240,10 @@ } 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)) { + /*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; @@ -246,7 +262,7 @@ this->velocity = Vector(0,0); } break; - } + }*/ //Engine::log(DEBUG, "physics.update_position") << "didnt hit"; } @@ -270,18 +286,62 @@ this->position = newPosition; } -/* + +/** + * Gets the index of the given coordinate direction + * referring to the DIRECTIONS table in Physics.hh + */ int getDirectionIndex (Vector dir) { int index = 0; if(dir.x < -0.1 || (dir.y > 0.1 && dir.x < 0.1)) index += 4; - if((dir.x > 0.1 && dir.y + if((dir.x > 0.1 && dir.y > 0.1) || (dir.y > 0.1 && dir.x < 0.1)) { + index += 2; + if(!(dir.x > -0.1 && dir < 0.1) && !(dir.y < 0.1 && dir.y > -0.1)) { + index += 1; + return index; } +/** + * 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 frees; -*/ + Vector hit = Vector((int)hitPoint.x, (int)hitPoint.y); + Vector prev = Vector((int)prevPoint.x, (int)prevPoint.y); + int dirIdx = getDirectionIndex(hit-prev); + for(int i = 1; i <= 2; i++) { + if(getType(hit+DIRECTIONS[dirIdx+i]) == EMPTY) + frees.push_back(DIRECTIONS[dirIdx+i]); + else + break; + } + for(int i = 1; i <= 2; i++) { + if(getType(hit+DIRECTIONS[dirIdx-i]) == EMPTY) + frees.push_back(DIRECTIONS[dirIdx-i]); + else + break; + } + frees.push_back(DIRECTION[dirIdx]); + + Vector normal(0,0); + for(int i = 0; i < size(); i++) { + normal += frees[i]; + } + return normal; +} + +/** + * Bounces from straight wall in any direction. + * Direction given as normal of that wall + */ +void PhysicsObject::bounce (Vector normal) { + Vector tangent(normal.y, -normal.x); + Vector tprojection = velocity * tangent / tangent.length(); + Vector nprojection = velocity * normal / normal.length(); + velocity = tprojection - nprojection; +} /*bool PhysicsWorld::collided (Vector oldPos, Vector newPos) { return false;