Best Way to Check Collisions?

Discussion in 'iOS Programming' started by ArtOfWarfare, Jul 18, 2011.

  1. ArtOfWarfare, Jul 18, 2011
    Last edited: Jul 18, 2011

    macrumors 604

    ArtOfWarfare

    Joined:
    Nov 26, 2007
    #1
    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:

    Code:
    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...

    Code:
    UIImageView	*walls[NUMWALLS];
    whereas I have

    Code:
    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?
     
  2. Moderator emeritus

    robbieduncan

    Joined:
    Jul 24, 2002
    Location:
    London
    #2
    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. 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 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).
     
  3. thread starter macrumors 604

    ArtOfWarfare

    Joined:
    Nov 26, 2007
    #3
    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...
     
  4. Moderator emeritus

    robbieduncan

    Joined:
    Jul 24, 2002
    Location:
    London
    #4
    Erm, basically you don't change the size of a C Array once you've created it.
     
  5. thread starter macrumors 604

    ArtOfWarfare

    Joined:
    Nov 26, 2007
    #5
    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?
     
  6. Moderator emeritus

    robbieduncan

    Joined:
    Jul 24, 2002
    Location:
    London
    #6
    Sure, that is certainly possible.
     
  7. macrumors 6502

    seepel

    Joined:
    Dec 22, 2009
    #7
    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.
     
  8. macrumors 6502

    Joined:
    Jul 13, 2011
    #8
    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 :)
     

Share This Page