user3433599
user3433599

Reputation:

Collision detection not working?

I'm trying to make a very simple SpriteKit app for iOS, but there's a problem:

#import "MyScene.h"

static const uint32_t laserCategory = 0x1 << 0;
static const uint32_t enemyCategory = 0x1 << 0;

@implementation MyScene

- (id) initWithSize: (CGSize) size
{
    if (self = [super initWithSize: size])
    {
        self.backgroundColor = [SKColor colorWithRed: 1.0 green: 1.0 blue: 1.0 alpha: 1.0];
        self.physicsWorld.gravity = CGVectorMake(0,0);

        SKSpriteNode *ship = [SKSpriteNode spriteNodeWithImageNamed: @"Ship"];
        ship.position = CGPointMake (CGRectGetMidX (self.frame), 50);
        [self addChild: ship];

        SKSpriteNode *enemy = [SKSpriteNode spriteNodeWithImageNamed: @"Enemy"];
        enemy.position = CGPointMake (CGRectGetMidX (self.frame), 440);
        [self addChild: enemy];

        enemy.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize: enemy.size];
        enemy.physicsBody.dynamic = YES;
        enemy.physicsBody.categoryBitMask = enemyCategory;
        enemy.physicsBody.contactTestBitMask = laserCategory;
        enemy.physicsBody.collisionBitMask = 0;

        SKAction *moveEnemy = [SKAction moveByX: 0.0 y: -500.0 duration: 5.0];
        [enemy runAction: moveEnemy];
    } return self;
}

- (void) touchesBegan: (NSSet *) touches withEvent: (UIEvent *) event
{
    SKSpriteNode *laser = [SKSpriteNode spriteNodeWithImageNamed: @"Laser"];
    laser.position = CGPointMake (CGRectGetMidX (self.frame), 100);
    [self addChild: laser];

    laser.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize: laser.size];
    laser.physicsBody.dynamic = YES;
    laser.physicsBody.categoryBitMask = laserCategory;
    laser.physicsBody.contactTestBitMask = enemyCategory;
    laser.physicsBody.collisionBitMask = 0;

    SKAction *moveLaser = [SKAction moveByX: 0.0 y: 2000.0 duration: 5.0];
    [laser runAction: moveLaser];
}

- (void) laser: (SKSpriteNode *) laser didCollideWithEnemy: (SKSpriteNode *) enemy
{
    [laser removeFromParent];
    [enemy removeFromParent];
}

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

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

    if ((firstBody.categoryBitMask & laserCategory) != 0 && (secondBody.categoryBitMask & enemyCategory) != 0)
    {
        [self laser: (SKSpriteNode *) firstBody.node didCollideWithEnemy: (SKSpriteNode *) secondBody.node];
    }
}

@end

This is my "MyScene.m" file, and everything works just fine. The only thing that doesn't work is the collision detection between the laser object and the enemy object. They just pass right through each other. Any solutions? Any other tips are welcome, as well.

Thanks.

Upvotes: 0

Views: 124

Answers (1)

Greg
Greg

Reputation: 25459

You have set the same bit mask for two different category:

static const uint32_t laserCategory = 0x1 << 0;
static const uint32_t enemyCategory = 0x1 << 0;

After that the if statement in didBeginContact: method is wrong:

if (contact.bodyA.categoryBitMask < contact.bodyB.categoryBitMask)

you should change one of those to 0x1 << 1:

static const uint32_t laserCategory = 0x1 << 0;
static const uint32_t enemyCategory = 0x1 << 1;

//Extended

You are also missing set up contact delegate to phasic world, add this code after you set up gravity in initWithSize:

self.physicsWorld.gravity = CGVectorMake(0,0);
self.physicsWorld.contactDelegate = self;

I assume you added delegate declaration to MyScene class:

<SKPhysicsContactDelegate>

Upvotes: 2

Related Questions