# 2d collision problems

## Recommended Posts

I'm doing some simple 2d collision detection and everything worked fine, I think. but when I threw in some very simple physics some collisions didn't work. for some reason about half the time on top or bottom collisions the sprite passes through another. but the left/right collisions work fine. does anyone know what could be wrong wrong?
for (i = 0; i < NUM_SPRITES; i++)
{
if (i != sprite)
{
//top collisions
RECT1.top = g_Sprite[sprite].fPosY;
RECT1.left = g_Sprite[sprite].fPosX;
RECT1.bottom = g_Sprite[sprite].fPosY + SPRITE_DIAMETER;
RECT1.right = g_Sprite[sprite].fPosX + SPRITE_DIAMETER;

RECT2.top = g_Sprite[i].fPosY + g_Sprite[i].fVelX;
RECT2.left = g_Sprite[i].fPosX;
RECT2.bottom = g_Sprite[i].fPosY - SPRITE_DIAMETER + g_Sprite[i].fVelX;
RECT2.right = g_Sprite[i].fPosX + SPRITE_DIAMETER;

collision = IntersectRects(RECT1, RECT2);

if (collision == true)
{
hold = (-g_Sprite[i].fVelY + g_Sprite[sprite].fVelY)/2;
g_Sprite[i].fVelY = hold;
g_Sprite[sprite].fVelY = -hold;
}
}
}

for (i = 0; i < NUM_SPRITES; i++)
{
if (i != sprite)
{
//bottom collisions
RECT1.top = g_Sprite[sprite].fPosY;
RECT1.left = g_Sprite[sprite].fPosX;
RECT1.bottom = g_Sprite[sprite].fPosY + SPRITE_DIAMETER;
RECT1.right = g_Sprite[sprite].fPosX + SPRITE_DIAMETER;

RECT2.top = g_Sprite[i].fPosY + g_Sprite[i].fVelX;
RECT2.left = g_Sprite[i].fPosX;
RECT2.bottom = g_Sprite[i].fPosY + SPRITE_DIAMETER + g_Sprite[i].fVelX;
RECT2.right = g_Sprite[i].fPosX + SPRITE_DIAMETER;

collision = IntersectRects(RECT1, RECT2);

if (collision ==  true)
{
hold = (g_Sprite[i].fVelY + -g_Sprite[sprite].fVelY)/2;
g_Sprite[i].fVelY = -hold;
g_Sprite[sprite].fVelY = hold;
}
}
}

for (i = 0; i < NUM_SPRITES; i++)
{
if (i != sprite)
{
//left collisions
RECT1.top = g_Sprite[sprite].fPosY;
RECT1.left = g_Sprite[sprite].fPosX;
RECT1.bottom = g_Sprite[sprite].fPosY + SPRITE_DIAMETER;
RECT1.right = g_Sprite[sprite].fPosX + SPRITE_DIAMETER;

RECT2.top = g_Sprite[i].fPosY;
RECT2.left = g_Sprite[i].fPosX + g_Sprite[i].fVelX;
RECT2.bottom = g_Sprite[i].fPosY + SPRITE_DIAMETER;
RECT2.right = g_Sprite[i].fPosX + SPRITE_DIAMETER + g_Sprite[i].fVelX;

collision = IntersectRects(RECT1, RECT2);

if (collision == true)
{
hold = (-g_Sprite[i].fVelX + g_Sprite[sprite].fVelX)/2;
g_Sprite[i].fVelX = hold;
g_Sprite[sprite].fVelX = -hold;
}
}
}

for (i = 0; i < NUM_SPRITES; i++)
{
if (i != sprite)
{
//right collisions
RECT1.top = g_Sprite[sprite].fPosY;
RECT1.left = g_Sprite[sprite].fPosX;
RECT1.bottom = g_Sprite[sprite].fPosY + SPRITE_DIAMETER;
RECT1.right = g_Sprite[sprite].fPosX + SPRITE_DIAMETER;

RECT2.top = g_Sprite[i].fPosY;
RECT2.left = g_Sprite[i].fPosX + g_Sprite[i].fVelX;
RECT2.bottom = g_Sprite[i].fPosY + SPRITE_DIAMETER;
RECT2.right = g_Sprite[i].fPosX + SPRITE_DIAMETER + g_Sprite[i].fVelX;

collision = IntersectRects(RECT1, RECT2);

if (collision == true)
{
hold = (g_Sprite[i].fVelX + -g_Sprite[sprite].fVelX)/2;
g_Sprite[i].fVelX = -hold;
g_Sprite[sprite].fVelX = hold;
}
}
}


p.s. if you need to see anything else ask and I'll post it.

##### Share on other sites
I would like to see your IntersectRects(RECT1, RECT2), method if you'd please.

##### Share on other sites
that method seems to work fine. but here you go just in case:

bool IntersectRects(RECT rect1, RECT rect2){		if (rect1.right > rect2.left)	{		if (rect1.left < rect2.right)		{			if (rect1.top < rect2.bottom)			{				if (rect1.bottom > rect2.top)				{					return true;				}			}		}	}	return false;}

##### Share on other sites
That's a one-way collision comparison - that is, you'd have to call IntersectRects(r1, r2) AND IntersectRects(r2, r1) to get a valid collision detection. You can write a rectangular collision detection function that goes both ways without too much trouble, though.

##### Share on other sites
No, that rectangle collision detection appears to be correct.

On the other hand:

RECT2.top = g_Sprite[i].fPosY + g_Sprite[i].fVelX;
RECT2.bottom = g_Sprite[i].fPosY - SPRITE_DIAMETER + g_Sprite[i].fVelX;

RECT2.top = g_Sprite[i].fPosY + g_Sprite[i].fVelX;
RECT2.bottom = g_Sprite[i].fPosY + SPRITE_DIAMETER + g_Sprite[i].fVelX;

Unless there's some sort of explanation for why x velocities are being added to y positions, I think this could be the problem.

##### Share on other sites
that may be the problem, I thought I fixed that :(. well I'm not at a computer with a compiler right now so I can't do anything. but if it works then I'll say, if not I'll say anyway.

##### Share on other sites
yep that fixed it.

moral of the story? never assume something fixed. :)

## Create an account

Register a new account

• ### Forum Statistics

• Total Topics
627700
• Total Posts
2978695

• 21
• 14
• 12
• 10
• 12