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.

gladoscc
Jul 23, 2011, 06:22 AM
If you are making a tile based game, divide your x and y by the size of the object and floor it. Check if that tile is walkable. That doesn't get more slower the more walls you have.

Tile based doesn't mean you can only move one square at a time, Super Mario Bros is tile based.

As you say you are making a 2d platforms game, depending on the situation you might want to make it tile based. Easier level design, gives a retro feel if you are aiming for that :)