# HG changeset patch # User nireco # Date 1227872576 0 # Node ID 1b9ad61bdf2d247169343f36eb4b2d2857cd5f6d # Parent d90977611fee7449654617abbbc4bba416aef32c added method for removing ground, not used anywhere diff -r d90977611fee -r 1b9ad61bdf2d src/proto2/Physics.cc --- 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(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 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 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 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); +} diff -r d90977611fee -r 1b9ad61bdf2d src/proto2/Physics.hh --- a/src/proto2/Physics.hh Fri Nov 28 11:28:22 2008 +0000 +++ b/src/proto2/Physics.hh Fri Nov 28 11:42:56 2008 +0000 @@ -54,7 +54,11 @@ Vector getNormal(Vector hitPoint, Vector prevPoint); + TerrainType getType(int x, int y) const; TerrainType getType(Vector pos) const; + + void removeGround(int x, int y, float r); + void removeGround(Vector pos, float r); }; class PhysicsObject {