//Est-ce que l'objet d'indice a est en collision avec les autres ? int Physique::collisionObjet(std::vector<Objet*> &objets, int idx) { int i, nobjets = objets.size(); double x1,x2,y1,y2; double w1,h1,w2,h2; bool cercle=false; double cx1=0, cy1=0, cr1=0, cx2=0, cy2=0, cr2=0; x1 = objets[idx]->getX(); y1 = objets[idx]->getY(); w1 = objets[idx]->getW(); h1 = objets[idx]->getH(); //Si c'est un cercle, on recupere son centre if(objets[idx]->getType()==CERCLE) { cx1 = x1+w1/2; cy1 = y1+h1/2; cr1 = w1/2; cercle = true; } //On parcourt tous les objets for(i=0;i<nobjets;i++) { if(idx!=i) { x2 = objets[i]->getX(); y2 = objets[i]->getY(); w2 = objets[i]->getW(); h2 = objets[i]->getH(); //Si on a deux cercles if( cercle && (objets[i]->getType()==CERCLE)) { cx2 = x2 + w2/2; cy2 = y2 + h2/2; cr2 = w2/2; if(collisionCercle(cx1,cy1,cr1,cx2,cy2,cr2)) return i; } else //Sinon on fait une collision entre rectangles { if(collisionRect(x1,y1,w1,h1,x2,y2,w2,h2)) return i; } } } return -1; }
void Gn2DMeshObject::Create2DAVData(GnVector2 cSize) { mpsAVData = GnNew Gn2DAVData(); GnFRect collisionRect( 0.0f, 0.0f, cSize.x, cSize.y ); mpsAVData->AddCollisionRect( 0, collisionRect ); cSize = GnVector2( 0.5f, 0.5f ); mpsAVData->SetImageCenter( cSize ); mpsAVData->SetAnchorPoint( cSize ); }
//Y-a-t-il une collision entres les objets et le rectangle (x,y,w,h) ? bool Physique::isCollision(std::vector<Objet*> &objets, double x, double y, double w, double h) { int i; double x1,y1,w1,h1; int nobjets = objets.size(); for(i=0;i<nobjets;i++) { x1 = objets[i]->getX(); y1 = objets[i]->getY(); w1 = objets[i]->getW(); h1 = objets[i]->getH(); if(collisionRect(x1,y1,w1,h1,x,y,w,h)) return true; } return false; }
void updatePositions() { oldPaddle = paddle; oldBall = ball; if (KEY_DOWN_NOW(BUTTON_RIGHT)) { paddle.x = min(paddle.x + PADDLE_SPEED, GAME_WIDTH - PADDLE_WIDTH); if (ball.onPaddle) ball.x = paddle.x + PADDLE_WIDTH / 2; } if (KEY_DOWN_NOW(BUTTON_LEFT)) { paddle.x = max(paddle.x - PADDLE_SPEED, 0); if (ball.onPaddle) ball.x = paddle.x + PADDLE_WIDTH / 2; } //release ball from paddle if (ball.onPaddle && KEY_DOWN_NOW(BUTTON_A)) { ball.onPaddle = FALSE; ball.xspeed = 1; ball.yspeed = -3; ball.y -= 1; //give it one pixel of space so it doesn't "collide" with paddle right away } //--------------------------CHECK FOR COLLISIONS-------------------------------// //check collision with right boundary if (collisionRect(ball.x, ball.y, ball.x + BALL_SIZE, ball.y + BALL_SIZE, GAME_WIDTH, 0, GAME_WIDTH + 10, GAME_HEIGHT)) { ball.xspeed = -ball.xspeed; ball.x -= 2; } //check collision with top boundary if (collisionRect(ball.x, ball.y, ball.x + BALL_SIZE, ball.y + BALL_SIZE, 0, -10, GAME_WIDTH, 0)) { ball.yspeed = -ball.yspeed; ball.y += 2; } //check collision with left boundary if (collisionRect(ball.x, ball.y, ball.x + BALL_SIZE, ball.y + BALL_SIZE, -10, 0, 0, GAME_HEIGHT)) { ball.xspeed = -ball.xspeed; ball.x += 2; } //check collision with bricks for (int i = 0; i < NUM_OF_BRICKS; i++) { if (brickArray[i].health && collisionRect(ball.x, ball.y, ball.x + BALL_SIZE, ball.y + BALL_SIZE, brickArray[i].x, brickArray[i].y, brickArray[i].x + BRICK_WIDTH, brickArray[i].y + BRICK_HEIGHT)) { int ballxmid = ball.x + BALL_SIZE/2; int ballymid = ball.y + BALL_SIZE/2; int brickxmid = brickArray[i].x + BRICK_WIDTH/2; int brickymid = brickArray[i].y + BRICK_HEIGHT/2; //slope of the vector pointing from the ball to the brick int deltax = brickxmid - ballxmid; int deltay = brickymid - ballymid; //below or above brick if (abs(deltax) < 2 * abs(deltay) + 2) // abs(dy/dx) > 1/2 (visual->) \_____/ { ball.yspeed = -ball.yspeed; ball.y += signOf(ball.yspeed) * 2; //"push it out of brick just a bit" } //side of brick else { ball.xspeed = -ball.xspeed; ball.x += signOf(ball.xspeed) * 2; //"push it out of brick just a bit" } brickArray[i].health -= 1; if (!brickArray[i].health) { //draw part of the background image that was previously hidden drawImageExt3(brickArray[i].x, brickArray[i].y, brickArray[i].x, brickArray[i].y, BRICK_WIDTH, BRICK_HEIGHT, gtech); bricksLeft --; sprintf(bricksString, "%d", bricksLeft); //store lives as a string waitForVblank(); drawRect(215, 85, 12, 8, RGB(6, 0, 6)); drawString(215, 85, bricksString, WHITE); } } } //check collision with paddle if (!ball.onPaddle && collisionRect(ball.x, ball.y, ball.x + BALL_SIZE, ball.y + BALL_SIZE, paddle.x, PADDLE_Y, paddle.x + PADDLE_WIDTH, PADDLE_Y + PADDLE_HEIGHT)) { setNewBallSpeed(); } //check for death if (ball.y > GAME_HEIGHT) { lives--; sprintf(livesString, "%d", lives); //store lives as a string //draw new lives number waitForVblank(); drawRect(215, 35, 6, 8, RGB(6, 0, 6)); drawString(215, 35, livesString, WHITE); setBallOnPaddle(); } ball.x += ball.xspeed; ball.y += ball.yspeed; }
void TileMap::load(const std::string& mapPath_){ this->map = new Tmx::Map(); this->map->ParseFile(mapPath_); if(!this->map->HasError()){ const Tmx::Tileset* metaTileset = nullptr; // Iterating through the tilesets to load their respective sprites. for (int i = 0; i < this->map->GetNumTilesets(); i++) { const Tmx::Tileset* tileSet = this->map->GetTileset(i); if(tileSet->GetProperties().HasProperty("meta")){ metaTileset = tileSet; } addTileSet("assets/maps/" + tileSet->GetImage()->GetSource()); } if(metaTileset == nullptr){ Log(ERROR) << "The map (" << mapPath_ << ") does not contain a meta tileset!"; } // Getting the number of layers inside the map. this->layers = this->map->GetNumLayers(); // Getting the map width/height by the first layer, since theoretically the // width/height should be the same for all layers. this->mapWidth = this->map->GetLayer(0)->GetWidth(); this->mapHeight = this->map->GetLayer(0)->GetHeight(); unsigned int i = 0; unsigned int j = 0; unsigned int k = 0; // Setting the size of the TileMap::tileMatrix, defaulting values to zero. // First dimension. this->tileMatrix.resize(this->mapWidth); // Second dimension. for (i = 0; i < this->tileMatrix.size(); i++){ this->tileMatrix[i].resize(this->mapHeight); } // Third dimension. for (i = 0; i < this->tileMatrix.size(); i++){ for (j = 0; j < this->tileMatrix[0].size(); j++){ this->tileMatrix[i][j].resize(this->layers, 0); } } const Tmx::Layer* currentLayer; for (i = 0; i < this->layers; i++){ currentLayer = this->map->GetLayer(i); // Saving all the tile IDs on the TileMap::tileMatrix for (j = 0; j < this->mapWidth; j++){ for (k = 0; k < this->mapHeight; k++){ int tileId = currentLayer->GetTileId(j, k); if (currentLayer->IsTileFlippedDiagonally(j, k)){ tileId |= Tmx::FlippedDiagonallyFlag; } if (currentLayer->IsTileFlippedHorizontally(j, k)){ tileId |= Tmx::FlippedHorizontallyFlag; } if (currentLayer->IsTileFlippedVertically(j, k)){ tileId |= Tmx::FlippedVerticallyFlag; } this->tileMatrix[j][k][i] = tileId; if(currentLayer->GetName() == "Collision"){ if(this->tileMatrix[j][k][i] > 0){ const Tmx::Tile* tile = metaTileset->GetTile(tileId); const std::string property = tile->GetProperties().GetList().begin()->second; SDL_Rect tileRect = {(int)(j * TILE_SIZE), (int)(k * TILE_SIZE), TILE_SIZE, TILE_SIZE}; if(property == "level_begin"){ this->initialX = tileRect.x; this->initialY = tileRect.y; continue; } else if(property == "enemy_patrol" || property == "enemy_no_patrol"){ this->enemiesX.push_back(tileRect.x); this->enemiesY.push_back(tileRect.y); this->enemiesPatrol.push_back((property == "enemy_patrol") ? true : false); continue; } TypeCollision type = CollisionRect::stringToType(property); CollisionRect collisionRect(tileRect, type); this->collisionRects.push_back(collisionRect); } } } } } Log(DEBUG) << "TileMap::load Map loaded (width:" << this->mapWidth << " height:" << this->mapHeight << " layers:" << this->layers << ")"; } else{ Log(ERROR) << "Unable to parse map at \"" << mapPath_ << "\" with error: " << this->map->GetErrorText(); } }
SDL_Rect Vampire::getCollisionRect(Point offset) const{ return collisionRect() + loc_ - offset; }
//Est-ce que l'objet d'indice a est en collision avec les autres de sa zone ? int Physique::collisionObjetZone(std::vector<Objet*> &objets, int idx) { int i,k,l; double x1,x2,y1,y2; double w1,h1,w2,h2; bool cercle=false; double cx1=0, cy1=0, cr1=0, cx2=0, cy2=0, cr2=0; int nobjets_zone; double x=0,y=0; int newzonei, newzonej; int oldzonei=-1, oldzonej=-1; x1 = objets[idx]->getX(); y1 = objets[idx]->getY(); w1 = objets[idx]->getW(); h1 = objets[idx]->getH(); //Si c'est un cercle, on recupere son centre if(objets[idx]->getType()==CERCLE) { cx1 = x1+w1/2; cy1 = y1+h1/2; cr1 = w1/2; cercle = true; } //Pour chaque coin for(i=0;i<4;i++) { //Recupere le coin recupereCoinObjet(objets[idx],i,x,y); //Calcul de la zone newzonei = recupereZoneLigne(y); newzonej = recupereZoneColonne(x); //Si c'est une autre zone if((newzonei!=oldzonei)||(newzonej!=oldzonej)) { oldzonei = newzonei; oldzonej = newzonej; //Ok on va regarder dans cette zone nobjets_zone = tableau_zones[newzonei][newzonej].size(); std::vector<int> &objets_zone = tableau_zones[newzonei][newzonej]; //On parcourt tous les objets de la zone for(k=0;k<nobjets_zone;k++) { l = objets_zone[k]; x2 = objets[l]->getX(); y2 = objets[l]->getY(); w2 = objets[l]->getW(); h2 = objets[l]->getH(); //Si on a deux cercles if( cercle && (objets[l]->getType()==CERCLE)) { cx2 = x2 + w2/2; cy2 = y2 + h2/2; cr2 = w2/2; if(collisionCercle(cx1,cy1,cr1,cx2,cy2,cr2)) return l; } else //Sinon on fait une collision entre rectangles { if(collisionRect(x1,y1,w1,h1,x2,y2,w2,h2)) return l; } } } } return -1; }