Sign in to follow this  
escudo825

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 this post


Link to post
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 this post


Link to post
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 this post


Link to post
Share on other sites
Guest Anonymous Poster
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 this post


Link to post
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 this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this