0

I'm trying to figure out how to detect when the contact between two bodies ends. I'm working on a car game something like alpine crawler and only when the rear wheel is touching the ground the car is able to accelerate.

This is my code for now but it doesn't work proper:

- (void) didBeginContact:(SKPhysicsContact *)contact
{
    if (([contact.bodyB.node.name isEqualToString:@"rearWheel"] &&
         [contact.bodyA.node.name isEqualToString:@"ground"])) {
        isWheelOnGround = YES;
    }
}

-(void) didEndContact:(SKPhysicsContact *)contact {

        if (([contact.bodyB.node.name isEqualToString:@"rearWheel"] &&
             [contact.bodyA.node.name isEqualToString:@"ground"])) {
            isWheelOnGround = NO;
        }
    }
Banjalucan
  • 115
  • 1
  • 9

1 Answers1

2

You need to implement the contact delegate correctly and set bitmasks on bodies for the contact notifications to fire up. To do that, put this beneath your imports:

typedef NS_OPTIONS(uint32_t, CNPhysicsCategory) {
    CNPhysicsCategoryWheel   = 1 << 0, // 0001 = 1
    CNPhysicsCategoryGround  = 1 << 1, // 0010 = 2
};

@interface YourSceneNameHere() <SKPhysicsContactDelegate>
@end


Then, as you initialize, add the scene as the contact delegate:

self.physicsWorld.contactDelegate = self;


Now, to apply those masks to your bodies - the category they are in, and what category of bodies they will be sending contact notifications for:

wheel.physicsBody.categoryBitMask = CNPhysicsCategoryWheel;
wheel.physicsBody.contactTestBitMask = CNPhysicsCategoryGround;

ground.physicsBody.categoryBitMask = CNPhysicsCategoryGround;
ground.physicsBody.contactTestBitMask = CNPhysicsCategoryWheel;


In the contact method, you have no control over which body is bodyA, and which bodyB:

- (void) didBeginContact:(SKPhysicsContact *)contact {
    uint32_t contactTest = (contact.bodyA.categoryBitMask | contact.bodyB.categoryBitMask);
    if (contactTest == (CNPhysicsCategoryWheel | CNPhysicsCategoryGround)) {
        isWheelOnGround = YES;
    }   
}

Similarly for didEndContact. Good luck!

For another example of this and a thorough explanation, refer to the 'Working with collisions and contacts' section of the SK Programming Guide.

Batalia
  • 2,425
  • 1
  • 17
  • 18
  • Thank you very much. But it didn't work better. The contact detection is still non-reliable. Often the scene doesn't detect when the wheel is touching the ground. – Banjalucan Jan 17 '14 at 17:38
  • Check if your physics bodies match your sprites exactly. How are you creating them? – Batalia Jan 17 '14 at 18:08
  • And perhaps set the usesPreciseCollisionDetection property of the body to YES. Either way, the code works flawlessly on my end. Set up logs/breakpoints to find the missing link. – Batalia Jan 17 '14 at 20:22
  • Banjaluchanine :) Sta se radi? ;) I have the same problem and find that the didBeginContact and didEndContact events are completely unreliable. Maybe, just maybe, they work as they should be working with rectangular based physics bodies, not any of the other types of physicsBody. Problem is not in the setting for delegate, I set up everything and sometimes the events DO ACTUALLY TRIGGER! - But not consistently and not all the time. If you don't connect the protocol to delegate and delegate contact handling to delegate, you don't get anything. So this is a non-issue. – Vladimir Despotovic Feb 19 '16 at 17:58