Sign in to follow this  
obi-wan shinobi

Collision detection in Win32/GDI

Recommended Posts

The following code is placed in a Window Procedure so that when holding down either 'w','a','s',or 'd', the RECT 'now' will be moved. The RECT 'bound' is the rectangle that tests for collison detection. The 4 integers are to determine whether the movable RECT 'now' should be allowed to go in a certain direction. The + or - is so that the movable object can hang over the edge by a certain number of pixels without falling off, so to speak.
case WM_CHAR: 
		{
			int up=0,down=0,left=0,right=0;
			char vkey = (TCHAR)wparam;
			if(now.top==bound.bottom && now.left>=bound.left-12 && now.right<=bound.right+12)	
				{	up=1;	}
			if(now.bottom==bound.top && now.left>=bound.left-12 && now.right<=bound.right+12)	
				{	down=1;	}
			if(now.right==bound.left && now.top<=bound.top+16 && now.bottom>=bound.bottom-16)		
				{	right=1;}
			if(now.left==bound.right && now.top<=bound.top+16 && now.bottom>=bound.bottom-16)		
				{	left=1;	}
			switch(vkey)
			{
			case 'w':	{	if(up==0)	y--;	break;	}
			case 'a':	{	if(left==0)	x--;	break;	}
			case 's':	{	if(down==0)	y++;	break;	}
			case 'd':	{	if(right==0)    x++;    break;	}
			}
		} break;

I've tested the code and so far it works well. I had trouble trying to use IntersectRect(RECT,RECT,RECT) (and also heard that it has problems), so I made my own algorithm as seen above. Is this a good algorithm in terms of optimization, so that when I create a sprite class for a DirectDraw game, I can do collisions between two sprites, or are there problems I can't see?

Share this post


Link to post
Share on other sites
The use of magic numbers is a negative, but in theory the code should work fine. Such a trivial bit of code is not worth messing around with optimizations unless your profiler shows you that it is a massive performance sink. (Hint: it isn't. Don't worry about optimizing something this tiny.)

Out of curiosity, what sort of problems did you have with IntersectRect? I've never heard of any trouble with it, and I know it's successfully used by a lot of reliable Win32 code. It doesn't do quite what you want as far as allowing overlap tolerance, but it's a highly reliable function.

Share this post


Link to post
Share on other sites
Quote:
Original post by ApochPiQ
The use of magic numbers is a negative, but in theory the code should work fine.
.......
Out of curiosity, what sort of problems did you have with IntersectRect?


I see about the magic numbers. In the future, I'll replace them with a 'width' and 'height' argument to pass into the function.

My problem with IntersectRect was not getting it to work. I know it took (LPRECT, CONST RECT, CONST RECT) for parameters, but the 'CONST RECT' was something that kept giving me such problems as "Unable to convert parameter 2 from x to y" in VC++6. I even tried to declare & initialize a CONST RECT in a function and I got an error saying "l-value denotes a constant". Also, I've noticed that members of RECT can't be initialized globally for some reason...

Share this post


Link to post
Share on other sites
Quote:
Original post by obi-wan shinobi
My problem with IntersectRect was not getting it to work. I know it took (LPRECT, CONST RECT, CONST RECT) for parameters, but the 'CONST RECT' was something that kept giving me such problems as "Unable to convert parameter 2 from x to y" in VC++6. I even tried to declare & initialize a CONST RECT in a function and I got an error saying "l-value denotes a constant". Also, I've noticed that members of RECT can't be initialized globally for some reason...

You have the parameters incorrect. The second and third parameters are not CONST RECT but rather CONST RECT *. You can pass the address of a RECT and it will work fine.

For example this should work fine


RECT a, b, c;
a.left = 0;
a.top = 0;
a.right = 10;
a.bottom = 10;
b.left = 5;
b.top = 5;
b.right = 15;
b.bottom = 15;

IntersectRect(&c, &a, &b);

Share this post


Link to post
Share on other sites
Just a little side note: You can shorten your code for initializing the rectangles this way:
RECT a={0,0,10,10}, b={5,5,15,15}, c;
//And if you need to change all of the points later in your code:
BOOL SetRect(LPRECT,long,long,long,long);

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