void Physics::addCollisionSpriteSprite(CollidableObject *dynamicObjectA, CollidableObject *dynamicObjectB) { // IF WE'VE ALREADY HANDLED A COLLISION BETWEEN THESE TWO OBJECTS THIS // FRAME THEN IGNORE IT //PAULO- MAYBE IMPORTANT*********************** /*set<CollidableObject*> doSprite = spriteToSpriteCollisionsThisFrame[dynamicObjectB]; if (doSprite.find(dynamicObjectB) != doSprite.end()) return;*/ // FIRST WE'RE GOING TO DO A MORE NARROW CHECK TO SEE IF THE dynamicObject // REALLY DOES COLLIDE WITH THE TILE. TO DO SO WE'LL CALCULATE THE TIME // OF COLLISION. IF IT HAPPENS AFTER THIS FRAME IS OVER (> 1), THEN WE // WILL IGNORE IT unsigned int co1Edge, co2Edge; float timeUntilCollision = calculateTimeUntilCollision(dynamicObjectA,dynamicObjectB, co1Edge, co2Edge, 0.0f); if (timeUntilCollision > 1.0f) return; //// NOW LET'S MAKE A COLLISION FOR THE SPRITE-SPRITE Collision *collisionToAdd = recycledCollisions.back(); collisionToAdd->setCO1(dynamicObjectA); collisionToAdd->setCO2(dynamicObjectB); collisionToAdd->setCO1Edge(co1Edge); collisionToAdd->setCO2Edge(co2Edge); collisionToAdd->setCollisionWithSprite(true); collisionToAdd->setCollisionWithTile(false); collisionToAdd->setTimeOfCollision(timeUntilCollision); //collisionToAdd->setTile(tile); recycledCollisions.pop_back(); activeCollisions.push_back(collisionToAdd); }
/* Called when a collision is detected between a world tile and a sprite, this records that collision so that it can be resolved later if needed. */ void Physics::addTileCollision(CollidableObject *dynamicObject, Tile *tile, float tileX, float tileY, float tileWidth, float tileHeight) { // IF WE'VE ALREADY HANDLED A COLLISION BETWEEN THESE TWO OBJECTS THIS // FRAME THEN IGNORE IT set<Tile*> doTiles = spriteToTileCollisionsThisFrame[dynamicObject]; if (doTiles.find(tile) != doTiles.end()) return; // GET A DUMMY COLLIABLE OBJECT TO USE FOR THE TILE CollidableObject *tileInfoForCollision = recycledCollidableObjectsList.back(); // FILL IT WITH DATA AABB *bv = tileInfoForCollision->getBoundingVolume(); bv->setCenterX(tileX + (tileWidth/2)); bv->setCenterY(tileY + (tileHeight/2)); bv->setWidth(tileWidth); bv->setHeight(tileHeight); // FIRST WE'RE GOING TO DO A MORE NARROW CHECK TO SEE IF THE dynamicObject // REALLY DOES COLLIDE WITH THE TILE. TO DO SO WE'LL CALCULATE THE TIME // OF COLLISION. IF IT HAPPENS AFTER THIS FRAME IS OVER (> 1), THEN WE // WILL IGNORE IT unsigned int co1Edge, co2Edge; float timeUntilCollision = calculateTimeUntilCollision(dynamicObject, tileInfoForCollision, co1Edge, co2Edge, 0.0f); if (timeUntilCollision > 1.0f) return; // IF IT MADE IT HERE, A COLLISION IS HAPPENING // AND REMOVE IT FROM THE RECYCLING CENTER recycledCollidableObjectsList.pop_back(); // NOW LET'S MAKE A COLLISION FOR THE TILE-SPRITE Collision *collisionToAdd = recycledCollisions.back(); collisionToAdd->setCO1(dynamicObject); collisionToAdd->setCO2(tileInfoForCollision); collisionToAdd->setCO1Edge(co1Edge); collisionToAdd->setCO2Edge(co2Edge); collisionToAdd->setCollisionWithTile(true); collisionToAdd->setTimeOfCollision(timeUntilCollision); collisionToAdd->setTile(tile); recycledCollisions.pop_back(); activeCollisions.push_back(collisionToAdd); }
//FOR NOW, TESTS SPRITES AGAINST ALL OTHER SPRITES. IF I HAVE TIME, I WILL IMPLEMENT SWEEP AND PRUNE void Physics::collideTestWithSprites(Game* game, CollidableObject* c, list<Collision*> *collisions) { SpriteManager *sm = game->getGSM()->getSpriteManager(); AnimatedSprite* player = sm->getPlayer(); if(c != player) { if(player->isCurrentlyCollidable() == true) { if(willObjectsCollide(player, c) == true) { Collision* currentCollision = collisionStack[collisionStackCounter]; collisionStackCounter --; currentCollision->setCO1(player); currentCollision->setCO2(c); currentCollision->calculateTimes(); if(currentCollision->getTOC() > 0 && currentCollision->getTOC() <= 1) { collisions->push_back(currentCollision); } else { collisionStackCounter ++; collisionStack[collisionStackCounter] = currentCollision; } }//end if }//end if }//end if else { list<Bot*>::iterator botIterator = sm->getBotsIterator(); while (botIterator != sm->getEndOfBotsIterator()) { Bot *bot = (*botIterator); if(c != bot && bot->isCurrentlyCollidable() == true) { if(willObjectsCollide(c, bot) == true) { Collision* currentCollision = collisionStack[collisionStackCounter]; collisionStackCounter --; currentCollision->setCO1(c); currentCollision->setCO2(bot); currentCollision->calculateTimes(); if(currentCollision->getTOC() > 0 && currentCollision->getTOC() <= 1) { collisions->push_back(currentCollision); } else { collisionStackCounter ++; collisionStack[collisionStackCounter] = currentCollision; } }//end if }//end if botIterator++; }//end while } /*Collision* currentCollision = collisionStack[collisionStackCounter]; collisionStackCounter --; currentCollision->setCO1(c); currentCollision->setCO2(tileCO); currentCollision->calculateTimes(); collisions->push_back(currentCollision);*/ }
void Physics::collideTestWithTiles(CollidableObject *c,TiledLayer *tL, list<Collision*> *collisions) { BoundingVolume *bv = c->getBoundingVolume(); float toRight= bv->getWidth()/2; float toBottom = bv->getHeight()/2; PhysicalProperties *pp = c->getPhysicalProperties(); float x = pp->getX()+bv->getX(); float y = pp->getY()+bv->getY(); float xVel = pp->getVelocityX(); float yVel = pp->getVelocityY(); float minX = x - toRight; float maxX = x + toRight; float minY = y - toBottom; float maxY = y + toBottom; if(xVel > 0) maxX += xVel; else minX += xVel; if(yVel > 0) maxY += yVel; else minY += yVel; int tW = tL->getTileWidth(); int tH = tL->getTileHeight(); int firstCol = minX/tW; int lastCol = maxX/tW; int firstRow = minY/tH; int lastRow = maxY/tH; if(firstCol < 0) firstCol = 0; if(firstRow < 0) firstRow = 0; if(lastCol >= tL->getColumns()) lastCol = tL->getColumns() - 1; if(lastRow >= tL->getRows()) lastRow = tL->getRows() - 1; for(int i = firstRow; i <= lastRow; i++) { for(int j = firstCol; j <= lastCol; j++) { Tile* current = tL->getTile(i,j); if(current->collidable == true) { if( !( (i+1)*tH < minY || i*tH > maxY || (j+1)*tW < minX || j*tW > maxX) ) { CollidableObject* tileCO = coStack[coStackCounter]; coStackCounter --; BoundingVolume *bv = tileCO->getBoundingVolume(); bv->setWidth(tW); bv->setHeight(tH); bv->setX(tW/2); bv->setY(tW/2); pp = tileCO->getPhysicalProperties(); pp->setPosition(j*tW,i*tH); /* Collision* currentCollision = collisionStack.top(); collisionStack.pop();*/ Collision* currentCollision = collisionStack[collisionStackCounter]; collisionStackCounter --; currentCollision->setCO1(c); currentCollision->setCO2(tileCO); currentCollision->calculateTimes(); collisions->push_back(currentCollision); } } } } }