IPhone SDK: collision detection, should it be a rectangle?

I am doing a basic platform for iPhone and I am having a problem with collision detection.

if (CGRectIntersectsRect(player.frame, platform.frame))
    pos2 = CGPointMake(0.0, +0.0);
    pos2 = CGPointMake(0.0, +10.0);


Collision detection is to stop the gravity in the game that exists when the player is on the platform, the problem is that the collision detection is a rectangle around the player, is there anyway collision detection for the actual shape of the image (with transparency) rather than a rectangle around it?


source to share

1 answer

You'll have to program this yourself, and beware that staged collision is probably too expensive for an iPhone. My recommendation is to write a Collidable protocol (called an interface in any other programming language), give it a collidedWith: (Collidable *) c function, and then just implement that for whatever object you want to resolve the conflict for. Then you can write the random case logic. Likewise, you can create a large superclass that has all the information you need to collide (in your case either X, Y, width and height, or an X, Y array and a pixel array), and a collidesWith method.Anyway, you can write a bunch of different collision techniques - if you only do pixel collisions for a few things it won't be a big hit. However,it is generally best to do a bounding box collision or other geometry based collision as it is significantly faster.

The folks at metanetsoftware have made some great tutorials on collision techniques, including axial split and mesh collision, the last of which sounds like it would be more viable for your game. However, if you want to use brute force collision detection (checking every object against every other object) then creating a bounding box that's just smaller than the image is usually the right way to go. There have been so many successful plugins, including Super Mario Brothers. You might as well consider weighted bounding boxes, i.e. You have one bounding box for one type of object and a different size for others. For example, in Mario, you have a large box that you can put coins into than enemies.

Now, although I warned you otherwise, I will oblige you and post how to do pixel based collision. You will want to access the pixel data of your CGImage and then loop through all the pixels to see if this image shares a location with any other image. Here's the code for it.

for (int i = 0; i < [objects count]; i++)
    MyObject *obj1 = [objects objectAtIndex:i];

    //Compare every object against every other object.
    for (int j = i+1; j < [objects count]; j++)
        MyObject *obj2 = [objects objectAtIndex:j];

        //Store whether or not we've collided.
        BOOL collided = NO;

        //First, do bounding box collision. We don't want to bother checking
        //Pixels unless we are within each others' bounds.
        if (obj1.x + obj1.imageWidth >= obj2.x &&
            obj2.x + obj2.imageWidth >= obj1.x &&
            obj1.y + obj1.imageHeight >= obj2.y &&
            obj2.y + obj2.imageGeight >= obj1.y)
            //We want to iterate only along the object with the smallest image.
            //This way, the collision checking will take the least time possible.
            MyObject *check = (obj1.imageWidth * obj1.imageHeight < obj2.imageWidth * obj2.imageHeight) ? obj1 : obj2;

            //Go through the pixel data of the two objects.
            for (int x = check.x; x < check.x + check.imageWidth && !collided; x++)
                for (int y = check.y; y < check.y + check.imageHeight && !collided; y++)
                    if ([obj1 pixelIsOpaqueAtX:x andY:y] && [obj2 pixelIsOpaqueAtX:x andY:y])
                        collided = YES;


I made it so that pixelIsOpaque takes a global coordinate and not a local coordinate, so when you program this part you have to be careful to subtract x and y from that again or you will be checking the limits of your image.



All Articles