touched which side? (2d box collision detection in C++)
Posted: Tue Jun 26, 2007 3:43 am
I'm writing an Arkanoid clone (called Andrewanoid) in C++, and I need some help with collision detection. How do I tell which side of the box the ball hit (like if the ball hit the top/bottom/left/right)? The ball is only 20x20px, and most blocks are 70x30. I'm only using box collision because the ball is small and moves fairly fast so I'm not gaim to try mixing box and circle collision.
Anyway here is the collision code I've got so far. I'm using a linked list of balls and a linked list of blocks.
The last parameter of sprintf should be the side the ball hit the block (hardcoded to 0 until I work it out). If you're wondering what these numbers are, this is from my LUA script:
The ball won't move any faster than 10-15 pixels per update.
Anyway here is the collision code I've got so far. I'm using a linked list of balls and a linked list of blocks.
Code: Select all
void BallManager::Update()
{
int ballid = 0;
int blockid = 0;
Ball *current = m_firstBall;
Block *currentBlock = 0;
while(current != 0)
{
int x = current->GetXPosition();
int y = current->GetYPosition();
int width = current->GetWidth();
int height = current->GetHeight();
int direction = current->GetDirection();
int speed = current->GetSpeed();
int left = x - (width / 2);
int top = y - (height / 2);
switch(direction)
{
case 0: // nw
x -= speed;
y -= speed;
break;
case 1: // ne
x += speed;
y -= speed;
break;
case 2: // sw
x -= speed;
y += speed;
break;
case 3: // se
x += speed;
y += speed;
break;
default:
break;
}
current->SetPosition(x, y);
// check for collision
currentBlock = m_blockManager->GetBlock(0);
blockid = 0;
while(currentBlock != 0)
{
if(currentBlock->GetCollidability())
{
int blockx = currentBlock->GetXPosition();
int blocky = currentBlock->GetYPosition();
int blockwidth = currentBlock->GetWidth();
int blockheight = currentBlock->GetHeight();
int blockleft = blockx - (blockwidth / 2);
int blocktop = blocky - (blockheight / 2);
if(blockid == 0)
{
}
if (top + height < blocktop)
{
}
else if (top > blocktop + blockheight)
{
}
else if (left + width < blockleft)
{
}
else if (left > blockleft + blockwidth)
{
}
else
{ // woohoo collision :P
char luabuf[50];
sprintf(luabuf, "OnCollide(%d,%d,%d);",ballid,blockid, 0);
m_lua->DoString(luabuf);
}
}
currentBlock = currentBlock->GetNext();
blockid++;
}
ballid++;
current = current->GetNext();
}
}
Code: Select all
-- Directions (for the ball)
DIRECTION_NW = 0;
DIRECTION_NE = 1;
DIRECTION_SW = 2;
DIRECTION_SE = 3;
-- Sides (for testing which side the ball collided from)
SIDE_TOP = 0;
SIDE_BOTTOM = 1;
SIDE_LEFT = 2;
SIDE_RIGHT = 3;