Reputation:
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
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