2

I have the following code:

in my scene:

static const uint32_t enermyCategory    =  0x1 << 0;
static const uint32_t fatherCategory    =  0x1 << 1;

self.physicsWorld.contactDelegate = self;

    //init ship
Ship *ship = [Ship getFather];
ship.position = CGPointMake(CGRectGetMaxX(self.frame) - ship.frame.size.width , ship.frame.size.height);
[self addChild: ship];

    //init enermy
    Enermy *ene = [[Enermy alloc] initWithImageNamed:enermyName gameScene:self];
ene.position = ship.position;
[self addChild:ene];

#pragma mark - Physics Delegate Methods
- (void)didBeginContact:(SKPhysicsContact *)contact{
    NSLog(@"contact detected");
}

As you can see, I set both ship and energy at the same location to start with, so they will always collide.

For both classes, I have the following code in their init method:

//setup physics body
self.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:self.size];
self.physicsBody.dynamic = NO;
self.physicsBody.categoryBitMask = enermyCategory; #shipCategory for ship
self.physicsBody.collisionBitMask = 0;
self.physicsBody.contactTestBitMask = shipCategory; #enermyCategory for ship

What I found is that the NSLog is never get called, so that the physical collision detection never works, I've read a lot from apple developer tutorials and it seems all the same of what they had, not sure why is not working. I can see the ship and energy images on screen collide each other.

phil88530
  • 1,499
  • 3
  • 19
  • 27

2 Answers2

5

Having the physicsBody set to dynamic = NO doesn't affect contacts. The more likely case is that you are setting the same contactBitMask and categoryBitMask for both nodes. You should be setting the ship to have the following:

self.physicsBody.categoryBitMask = shipCategory;
self.physicsBody.collisionBitMask = 0;
self.physicsBody.contactTestBitMask = enermyCategory;

The enemy should have the following:

self.physicsBody.categoryBitMask = enermyCategory;
self.physicsBody.collisionBitMask = 0;
self.physicsBody.contactTestBitMask = shipCategory;

Bottom line: they should be swapped in the ship.

joshd
  • 1,626
  • 14
  • 17
  • Also, make sure you define the shipCategory. I didn't see that above (just fatherCategory). – joshd Jan 20 '14 at 05:52
4
self.physicsBody.dynamic = NO;

Static (non-dynamic) bodies do not generate contact events. Make them dynamic.

Also, I see you're passing gameScene to an instance of Enemy. If Enemy has a strong reference to game scene (an ivar) then you may be creating a retain cycle here (enemy retains scene, scene retains enemy).

In Sprite Kit you can simply use self.scene to access the scene and if you need the scene during init, move that code into a setup method and call [ene setup] right after adding it as child to perform setup steps involving the scene.

CodeSmile
  • 64,284
  • 20
  • 132
  • 217
  • 2
    Hey, It seems dynamic NO is ok, I now use the beta version of Xcode, it can detect. However, ofc they push each other positions because of the real physics work. it there anyway you can make it only detect but not apply physical "push" works on each other? – phil88530 Jan 17 '14 at 20:44
  • 2
    One of the two contacting bodies can be non-dynamic and the contact event will still trigger. It just has to be at least one. – Batalia Jan 17 '14 at 20:49
  • When they "push" each other then they are colliding, indicating that the collisionBitMask isn't the way you want it to be. Contact = overlap, collision = move overlapping bodies so they don't overlap and apply forces to contacting bodies. – CodeSmile Jan 17 '14 at 21:01