ipadios7sprite-kitcollision-detectionpixel-perfect

Is there pixel perfect collision detection for Sprite Kit (iOS7)?


I need to spawn 8 random sprite objects on an iPad sprite game. The objects are fairly big, and with different sizes. They should not overlay. If one that is spawn on the scene overlays it will be removed (optional it removes the underlaying one). I have been looking for a pixel perfect collision detection framework or helper class for Sprite Kit. So far I haven't found a tutorial or something alike. Most people use normal collision detection which will not be of any help since my objects are big. I tested standard approach but it creates rectangles which make the sprite area in my case even bigger. This is my sprite kit template testing project:

#import "WBMMyScene.h"

static const uint32_t randomObjectCategory     =  0x1 << 0;

@interface WBMMyScene () <SKPhysicsContactDelegate>

@end

@implementation WBMMyScene

-(id)initWithSize:(CGSize)size
{
    if (self = [super initWithSize:size])
    {
        /* Setup your scene here */
        self.backgroundColor = [SKColor colorWithRed:0.15 green:0.15 blue:0.3 alpha:1.0];
        self.physicsWorld.gravity = CGVectorMake(0, 0);
        self.physicsWorld.contactDelegate = self;
    }
    return self;
}

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    /* Called when a touch begins */

    for (UITouch *touch in touches)
    {
        CGPoint location = [touch locationInNode:self];
        SKSpriteNode *spaceship = [SKSpriteNode spriteNodeWithImageNamed:@"Spaceship"];
        //SKSpriteNode *spaceship = [SKSpriteNode spriteNodeWithColor:[UIColor redColor] size:CGSizeMake(50, 50)];
        spaceship.position = location;
        [spaceship setSize:CGSizeMake(50, 50)];
        [spaceship.texture setFilteringMode:SKTextureFilteringNearest];
        //spaceship.texture setFilteringMode
        spaceship.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:spaceship.size];
        spaceship.physicsBody.dynamic = YES;
        spaceship.physicsBody.categoryBitMask = randomObjectCategory;
        spaceship.physicsBody.contactTestBitMask = randomObjectCategory;
        spaceship.physicsBody.collisionBitMask = 0;
        [self addChild:spaceship];
    }
}

- (void)didBeginContact:(SKPhysicsContact *)contact
{
    // 1
    SKPhysicsBody *firstBody, *secondBody;

    if (contact.bodyA.categoryBitMask < contact.bodyB.categoryBitMask)
    {
        firstBody = contact.bodyA;
        secondBody = contact.bodyB;
    }
    else
    {
        firstBody = contact.bodyB;
        secondBody = contact.bodyA;
    }

    // 2
    if (firstBody.categoryBitMask == secondBody.categoryBitMask)
    {
        [self projectile:(SKSpriteNode *) firstBody.node didColliteWithEachOther:(SKSpriteNode *) secondBody.node];
    }
}

- (void)projectile:(SKSpriteNode *)object1 didColliteWithEachOther:(SKSpriteNode *)object2
{
    NSLog(@"Hit");
    [object1 removeFromParent];
    [object2 removeFromParent];
}

-(void)update:(CFTimeInterval)currentTime {
    /* Called before each frame is rendered */
}

@end

Thanks for your time :)


Solution

  • As far as I'm aware iOS7 doesn't have per pixel physics, that is due to come with XCode 6 which is in its beta testing phase and available to developers now. Remember it is a beta and does have a few bugs, it's full release is likely to be in September with iOS8 and the new iPhone.

    In the mean time you have two options, you could download the XCode 6 beta and work within that for per pixel physics. Personally however I got a little sick of using a beta for full development and instead went back to XCode 5. Within iOS7 and XCode 5 you have the option of defining a physicsBody with a path, which gives an accurate depiction of a sprites physical shape.

    The tool I use is here and lets you drag and drop an image and then define path points graphically and returns the code, it really is handy.

    I hope this helps!