void UpdateBall() { BallRect.x += BallXVel; BallRect.y += BallYVel; //If the ball hits the player, make it bounce if(RectsOverlap(BallRect, PlayerPaddleRect)) { BallXVel = rand()%BALL_MAX_SPEED + 1; Mix_PlayChannel(-1, BallBounceSound, 0); } //If the ball hits the enemy, make it bounce if(RectsOverlap(BallRect, EnemyPaddleRect)) { BallXVel = (rand()%BALL_MAX_SPEED +1) * -1; Mix_PlayChannel(-1, BallBounceSound, 0); } //Make sure the ball doesn't leave the screen and make it //bounce randomly if(BallRect.y < 0) { BallRect.y = 0; BallYVel = rand()%BALL_MAX_SPEED + 1; Mix_PlayChannel(-1, BallBounceSound, 0); } if(BallRect.y > SCREEN_HEIGHT - BallRect.h) { BallRect.y = SCREEN_HEIGHT - BallRect.h; BallYVel = (rand()%BALL_MAX_SPEED + 1)* -1; Mix_PlayChannel(-1, BallBounceSound, 0); } //If player scores if(BallRect.x > SCREEN_WIDTH) { PlayerScore++; Mix_PlayChannel(-1, PlayerScoreSound, 0); ResetGame(); } //If enemy scores if(BallRect.x < 0-BallRect.h) { EnemyScore++; Mix_PlayChannel(-1, EnemyScoreSound, 0); ResetGame(); } }
void Bitmap::copyRectFromBitmap(const Bitmap& src, unsigned srcCol, unsigned srcRow, unsigned destCol, unsigned destRow, unsigned width, unsigned height) { if (srcCol == 0 && srcRow == 0 && width == 0 && height == 0){ width = src.width(); height = src.height(); } if (width == 0 || height == 0) throw std::runtime_error("Can't copy zero height/width rectangle"); if (srcCol + width >= src.width() || srcRow + height >= src.height()) throw std::runtime_error("Rectangle doesn't fit within source bitmap"); if (destCol + width >= _width || destRow + height >= _height) throw std::runtime_error("Rectangle doesn't fit within destination bitmap"); if (_pixels == src._pixels && RectsOverlap(srcCol, srcRow, destCol, destRow, width, height)) throw std::runtime_error("Source and destination are the same bitmap, and rects overlap. Not allowed!"); FormatConverterFunc converter = NULL; if(_format != src._format) converter = ConverterFuncForFormats(_format, src._format); for (unsigned row = 0; row < height; ++row) { for (unsigned col = 0; col < width; ++col) { unsigned char *srcPixel = src._pixels + GetPixelOffset(srcCol + col, srcRow + row, src._width, src._height, src._format); unsigned char *destPixel = _pixels + GetPixelOffset(destCol + col, destRow + row, _width, _height, _format); if (converter) { converter(srcPixel, destPixel); } else { memcpy(destPixel, srcPixel, _format); } } } }
bool CollisionManager::PixelsToRect(const CollisionPixelData * pixels, double px, double py, double rx, double ry, double rw, double rh) const { double overlapRectX, overlapRectY, overlapRectW, overlapRectH,x,y; if (RectsOverlap(px, py, pixels->GetWidth(), pixels->GetHeight(), rx, ry, rw, rh)) { OverlappingRect(px, py, pixels->GetWidth(), pixels->GetHeight(), rx, ry, rw, rh, &overlapRectX, &overlapRectY, &overlapRectW, &overlapRectH); x = overlapRectX; y = overlapRectY; bool collision = false; while (!collision && y < (overlapRectY + overlapRectH)) { while (!collision && x <(overlapRectX + overlapRectW)) { collision = pixels->GetData(x - px, y - py); x++; } y++; x = overlapRectX; } return collision; } else { return false; } }
bool CollisionManager::PixelsToPixels(const CollisionPixelData * p1, double x1, double y1, const CollisionPixelData * p2, double x2, double y2) const { double overlapRectX, overlapRectY, overlapRectW, overlapRectH; double x, y, p1x, p1y, p2x, p2y; if(RectsOverlap(x1, y1, p1->GetWidth(), p1->GetHeight(), x2, y2, p2->GetWidth(), p2->GetHeight())){ OverlappingRect(x1, y1, p1->GetWidth(), p1->GetHeight(), x2, y2, p2->GetWidth(), p2->GetHeight(), &overlapRectX, &overlapRectY, &overlapRectW, &overlapRectH); x = overlapRectX; y = overlapRectY; bool collision = false; while (!collision && y < (overlapRectY + overlapRectH)) { while (!collision && x <(overlapRectX + overlapRectW)) { collision = (p1->GetData(x - x1, y - y1) && p2->GetData(x - x2, y - y2)); x++; } y++; x = overlapRectX; } return collision; } else { return false; } }
bool CollisionManager::CircleToPixels(double cx, double cy, double cr, const CollisionPixelData * pixels, double px, double py) const { double overlapRectX, overlapRectY, overlapRectW, overlapRectH; double x, y; //check overlap if (RectsOverlap(cx-cr, cy-cr, cr*2, cr*2, px, py, pixels->GetWidth(), pixels->GetHeight())) { //get overlapingRect OverlappingRect(cx-cr, cy-cr, cr * 2, cr * 2, px, py, pixels->GetWidth(), pixels->GetHeight(), &overlapRectX, &overlapRectY, &overlapRectW, &overlapRectH); //reference coords x = overlapRectX; y = overlapRectY; //cicle through pixels bool collision = false; while (!collision && y < (overlapRectY + overlapRectH)) { while (!collision && x <(overlapRectX + overlapRectW)) { collision = pixels->GetData(x - px, y - py) && Distance(x, y, cx, cy) < cr; x++; } y++; x = overlapRectX; } return collision; } else { return false; } }
//comprobamos si colisionan los rectangulos que contienen los pixeles, obtenemos la zona en la que se solapan y comprobamos en esa zona si hay un pixel para los dos sprites bool CollisionManager::PixelsToPixels(const CollisionPixelData* p1, double x1, double y1, const CollisionPixelData* p2, double x2, double y2) const { //si los dos rectangulos se solapan if (RectsOverlap(x1, y1, p1->GetWidth(), p1->GetHeight(), x2, y2, p2->GetWidth(), p2->GetHeight())) { double rx, ry, rw, rh; //obtenemos el rectangulo de solapamiento OverlappingRect(x1, y1, p1->GetWidth(), p1->GetHeight(), x2, y2, p2->GetWidth(), p2->GetHeight(), &rx, &ry, &rw, &rh); //obtenemos los pixeles del los dos rectangulos donde empieza al rectangulo de solapamiento uint16 rect1x = uint16(rx - x1); uint16 rect1y = uint16(ry - y1); uint16 rect2x = uint16(rx - x2); uint16 rect2y = uint16(ry - y2); //recorremos desde esos puntos nuestro buffer de booleanos y si los dos son opacos, for (int i = 0; i < rw; i++) for (int j = 0; j < rh; j++) if (p1->GetData(rect1x + i, rect1y + j) && p2->GetData(rect2x + i, rect2y + j)) return true; } return false; }
bool CollisionManager::PixelsToRect(const CollisionPixelData* pixels, double px, double py, double rx, double ry, double rw, double rh) const{ if (RectsOverlap(px, py, pixels->GetWidth(), pixels->GetHeight(), rx, ry, rw, rh)){ double outx, outy, outwidth, outheight; OverlappingRect(px, py, pixels->GetWidth(), pixels->GetHeight(), rx, ry, rw, rh, &outx, &outy, &outwidth, &outheight); uint32 px1 = outx - px; uint32 py1 = outy - py; //1º pixel relativo a p1 for (int32 pyy = 0; pyy < outheight; pyy++){ for (int32 pxx = 0; pxx < outwidth; pxx++){ if (pixels->GetData(px1 + pxx, py1 + pyy) == true) return true; } } } return false; }
bool CollisionManager::CircleToPixels(double cx, double cy, double cr, const CollisionPixelData * pixels, double px, double py) const { if (RectsOverlap(cx - cr, cy - cr, cr * 2, cr * 2, px, py, pixels->GetWidth(), pixels->GetHeight())) { double overlapX, overlapY, overlapWidth, overlapHeight; OverlappingRect(cx - cr, cy - cr, cr * 2, cr * 2, px, py, pixels->GetWidth(), pixels->GetHeight(), &overlapX, &overlapY, &overlapWidth, &overlapHeight); double offY = overlapY - py; double offX; while (offY < overlapHeight + overlapY - py) { offX = overlapX - px; while (offX < overlapWidth + overlapX - px) { if (pixels->GetData(offX, offY) && Distance(cx, cy, offX + px, offY + py) <= cr) return true; offX++; } offY++; } } return false; }
bool CollisionManager::PixelsToPixels(const CollisionPixelData* p1, double x1, double y1, const CollisionPixelData* p2, double x2, double y2) const{ if (RectsOverlap(x1, y1, p1->GetWidth(), p1->GetHeight(), x2, y2, p2->GetWidth(), p2->GetHeight())){ double outx, outy, outwidth, outheight; OverlappingRect(x1, y1, p1->GetWidth(), p1->GetHeight(), x2, y2, p2->GetWidth(), p2->GetHeight(), &outx, &outy, &outwidth, &outheight); uint32 px1 = outx - x1; uint32 py1 = outy - y1; //1º pixel relativo a p1 uint32 px2 = outx - x2; uint32 py2 = outy - y2; //1º pixel relativo a p2 for (int32 py = 0; py < outheight; py++){ for (int32 px = 0; px < outwidth; px++){ if (p1->GetData(px1 + px, py1 + py) == true && p2->GetData(px2 + px, py2 + py) == true) return true; } } } return false; }
bool CollisionManager::PixelsToRect(const CollisionPixelData * pixels, double px, double py, double rx, double ry, double rw, double rh) const { if (RectsOverlap(px, py, pixels->GetWidth(), pixels->GetHeight(), rx, ry , rw, rh)) { double overlapX, overlapY, overlapWidth, overlapHeight; OverlappingRect(px, py, pixels->GetWidth(), pixels->GetHeight(), rx, ry, rw, rh, &overlapX, &overlapY, &overlapWidth, &overlapHeight); double offsetY = overlapY - py; double offsetX; while (offsetY < overlapHeight + overlapY - py) { offsetX = overlapX - px; while (offsetX < overlapWidth + overlapX - px) { if (pixels->GetData(offsetX, offsetY)) return true; offsetX++; } offsetY++; } } return false; }
//comprobamos si colisiona el rectangulo y el rectangulo que contiene los pixeles, obtenemos la zona en la que se solapan y comprobamos en esa zona si hay un pixel opaco en el buffer bool CollisionManager::PixelsToRect(const CollisionPixelData* pixels, double px, double py, double rx, double ry, double rw, double rh) const { if (RectsOverlap(px,py, pixels->GetWidth(), pixels->GetHeight(),rx,ry,rw,rh)) { double overlapx, overlapy, overlapw, overlaph; OverlappingRect(px,py,pixels->GetWidth(), pixels->GetHeight(),rx,ry,rw,rh,&overlapx,&overlapy,&overlapw, &overlaph); uint16 rect1x = uint16(overlapx - px); uint16 rect1y = uint16(overlapy - py); uint16 rect2x = uint16(overlapx - rx); uint16 rect2y = uint16(overlapy - ry); //recorremos desde esos puntos nuestro buffer de booleanos y si algun pixel es opaco colisionan for (int i = 0; i < overlapw; i++) for (int j = 0; j < overlaph; j++) if (pixels->GetData(rect1x + i, rect1y + j)) return true; } return false; }
bool CollisionManager::CircleToPixels(double cx, double cy, double cr, const CollisionPixelData* pixels, double px, double py) const{ //Si chocan sus rectangulos if (RectsOverlap(px, py, pixels->GetWidth(), pixels->GetHeight(), cx, cy, 2 * cr, 2 * cr)){ //Calculamos el rectangulo de colision double outx, outy, outwidth, outheight; OverlappingRect(px, py, pixels->GetWidth(), pixels->GetHeight(), cx, cy, 2*cr, 2*cr, &outx, &outy, &outwidth, &outheight); uint32 px1 = outx - px; uint32 py1 = outy - py; //1º pixel relativo a p1 for (int32 pyy = 0; pyy < outheight; pyy++){ for (int32 pxx = 0; pxx < outwidth; pxx++){ //if one pixel is visible and inside the circle if (pixels->GetData(px1 + pxx, py1 + pyy) == true && Distance(cx + cr, cy + cr, outx + pxx, outy + pyy) < cr) return true; } } } return false; }
bool CollisionManager::PixelsToPixels(const CollisionPixelData * p1, double x1, double y1, const CollisionPixelData * p2, double x2, double y2) const { if (RectsOverlap(x1, y1, p1->GetWidth(), p1->GetHeight(), x2, y2, p2->GetWidth(), p2->GetHeight())) { double overlapX, overlapY, overlapWidth, overlapHeight; OverlappingRect(x1, y1, p1->GetWidth(), p1->GetHeight(), x2, y2, p2->GetWidth(), p2->GetHeight(), &overlapX, &overlapY, &overlapWidth, &overlapHeight); double py1 = overlapY - y1; double py2 = overlapY - y2; double px1, px2; while (py1 < overlapHeight + overlapY - y1 && py2 < overlapHeight + overlapY - y2) { px1 = overlapX - x1; px2 = overlapX - x2; while (px1 < overlapWidth + overlapX - x1 && px2 < overlapWidth + overlapX - x2) { if (p1->GetData(px1, py1) && p2->GetData(px2, py2)) { return true; } px1++; px2++; } py1++; py2++; } } return false; }
bool CollisionManager::RectToRect(double x1, double y1, double w1, double h1, double x2, double y2, double w2, double h2) const { return RectsOverlap(x1, y1, w1, h1, x2, y2, w2, h2); }
bool CollisionManager::RectToRect(double x1, double y1, double w1, double h1, double x2, double y2, double w2, double h2) const { if (RectsOverlap(x1, y1, w1, h1, x2, y2, w2, h2)) return true; else return false; }