PDA

View Full Version : Best Way to Check Collisions?

ArtOfWarfare
Jul 18, 2011, 10:06 AM
I'm not sure what the best way of putting this is... I'm trying to decide what the best way of drawing levels and detecting collisions with the environment in a 2D platforming game is.

Right now, I have four separate arrays for my grounds, ceilings, left walls, and right walls. Based on x and y velocities, I determine which I need to check for collisions with. For example, if yVelocity is negative, I check whether the character frame intersects with any of the grounds' frames:

if (yVelocity < 0)
{
int i;
for (i = 0; i < [grounds count]; i++)
{
CGRect ground = [[grounds objectAtIndex:i] frame];
if (CGRectIntersectsRect(frame, ground))
{
onGround = YES;
frame.origin.x -= (CGRectGetMaxX(frame) - CGRectGetMinX(ground));
yVelocity = 0;
break;
}
else onGround = NO;
}
}

If I throw in before the break in my check an NSLog that lets me know it's done checking for a collision with a given wall, then I receive the log reports every .003 seconds or so when running on the device. This means that if I have more than 10 different grounds to check, that I risk the game noticeably slowing down... right?

I was thinking about the possibility of instead using a pathing map or something. Like, if I have a bmp with 8 possible colors, it could check the color of the bit in the direction the character is heading to see whether or not they've hit a surface. Would this be faster?

What have other people done to check for collisions?

Edit: I'm looking at Apple's example "GKTank" app. They store walls a different way...

UIImageView *walls[NUMWALLS];

whereas I have

NSMutableArray *grounds;

Does the fact that they're using the [NUMWALLS] speed up the game somehow? I don't understand straight C so well, but I think that's what they're using by typing that... like, a straight C version of an NSArray. In doing so, I would guess there might be less overhead? Questions it prompts though... would using their method make the array immutable? How would I go from level to level if I wanted the size to change and stuff?

robbieduncan
Jul 18, 2011, 11:04 AM
Pure-C arrays will be much faster than Cocoa NSArray (or NSMutableArrays). The cost of accessing an element in a C array is basically a memory offset operation (addition) and that gets you the memory address. The cost of accessing a Cocoa NSArray is that (right at the end) + a number of Cocoa message calls (not just one as NSArray access is bounds checked) each of which equates to being slightly more expensive that a function call.

There is a (not very good test) showing the sort of speed difference here (http://memo.tv/node/824). I say this is not very good as it may actually be testing the performance of C floats vs NSNumber.

There is an interesting test here (http://www.formconstant.net/diagrams/?p=40) showing the sort of improvements that can be made by caching selectors (this is certainly the sort of thing I'd expect you to be doing).

ArtOfWarfare
Jul 18, 2011, 11:23 AM
Ok, thanks for that Robbie.

I'll change my NSMutableArrays to be C Arrays instead... but I'm curious as to how I change the size of a C Array while my app is running?

Maybe I should consult my reference book on ANSI C and see what info it gives on Arrays...

robbieduncan
Jul 18, 2011, 11:24 AM
I'll change my NSMutableArrays to be C Arrays instead... but I'm curious as to how I change the size of a C Array while my app is running?

Erm, basically you don't change the size of a C Array once you've created it.

ArtOfWarfare
Jul 18, 2011, 11:33 AM
Erm, basically you don't change the size of a C Array once you've created it.

Huh... but I can change the contents of the array, if I'm reading Apple's example code properly. If I make the array as large as it'll ever need to be, I can keep a separate int that says how many spaces in the array are actually filled, right?

robbieduncan
Jul 18, 2011, 11:40 AM
Huh... but I can change the contents of the array, if I'm reading Apple's example code properly. If I make the array as large as it'll ever need to be, I can keep a separate int that says how many spaces in the array are actually filled, right?

Sure, that is certainly possible.

seepel
Jul 23, 2011, 01:06 AM
If the levels need to get more complicated than just some lines that you can look at LevelSVG to create the levels. And if you are making a 2D game I can't recommend highly enough the Cocos2D framework, you should definitely check it out.