user1114881
user1114881

Reputation: 751

play a sound when two nodes collide

I have an app with three sprite nodes, ball1, ball2, ball3. they move around the scene by tipping the device up, down, right, left. Everything is working fine. I would like to add an effect in which when any two balls touch (collide) a sound plays. I am using SpriteKit and have each ball with a physicalBody and they have a ball shape property, I have precisionCollision Yes, categoryBitMask set to ballCategory1, 2, and 3 for each ball. (or can I just use one category) I have tried various tutorials on how to do this but nothing seems to be working.

I have tried using Ray Wenderlich's example with a tweek for mine. but,

//here are my three categories

static const uint32_t ballCategory = 0x1 << 1;
static const uint32_t ballCategory2 = 0x1 << 2;
static const uint32_t ballCategory3 = 0x1 << 3;

//these are my three nodes

ball = [SKSpriteNode spriteNodeWithImageNamed:@"mankala piece"];
    ball.scale = 1;

    ball.position = CGPointMake(600, 500);
   ball.physicsBody =
    [SKPhysicsBody bodyWithCircleOfRadius:(ball.size.width/2)];
    ball.physicsBody.usesPreciseCollisionDetection = YES;
   ball.physicsBody.categoryBitMask = ballCategory;
    ball.physicsBody.collisionBitMask = ballCategory2|ballCategory|ballCategory3;
    ball.physicsBody.affectedByGravity = NO;
    [self addChild:ball];

    ball2 = [SKSpriteNode spriteNodeWithImageNamed:@"mankala piece"];
    ball2.scale = 1;

    ball2.position = CGPointMake(350, 200);
    ball2.physicsBody =
    [SKPhysicsBody bodyWithCircleOfRadius:(ball2.size.width/2)];
    ball2.physicsBody.usesPreciseCollisionDetection = YES;
    ball2.physicsBody.categoryBitMask = ballCategory2;
   ball2.physicsBody.collisionBitMask = ballCategory2|ballCategory|ballCategory3;
    ball2.physicsBody.affectedByGravity = NO;
    [self addChild:ball2];

    ball3 = [SKSpriteNode spriteNodeWithImageNamed:@"mankala piece"];
    ball3.scale = 1;

    ball3.position = CGPointMake(500, 400);
    ball3.physicsBody =
    [SKPhysicsBody bodyWithCircleOfRadius:(ball3.size.width/2)];
    ball3.physicsBody.usesPreciseCollisionDetection = YES;
    ball3.physicsBody.categoryBitMask = ballCategory3;
   ball3.physicsBody.collisionBitMask = ballCategory2|ballCategory|ballCategory3;
    ball3.physicsBody.affectedByGravity = NO;
    [self addChild:ball3];

// and here is my revised contact code

- (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 & ballCategory) != 0)
    {
        NSLog(@"click");
    }
    if ((firstBody.categoryBitMask & ballCategory2) != 0)
    {
        NSLog(@"click2");
    }

    if ((firstBody.categoryBitMask & ballCategory3) != 0)
    {
        NSLog(@"click3");
    }

}

but still nothing happens.
has anyone worked with collisions in spriteKit. Just want to have a sound play when two different sprite nodes come in contact.

Upvotes: 1

Views: 193

Answers (1)

Phoenix
Phoenix

Reputation: 1931

First, you do not have any contactTestBitMasks set up. Currently you're telling the physics delegate which nodes are set up to collide with one another, but nothing is set up to contact. Add this to each ball physicsBody:

ball2.physicsBody.contactTestBitMask = ballCategory | ballCategory2 | ballCategory3

This way, the physics delegate will understand that each ball can make contact with the others.

Your contact if statement is still incorrectly being used. ballCategory and ballCateogry2 are variables which you've equated to integers; this means that your categoryBitMask are now set equal to those integers.

What your if statement does is check to see if the physicsBody's category equals a specific integer, or just equals an integer greater than zero (it's up to you).

In this case, you will need to adjust your if statement to test the value of those categoryBitMasks you've set up:

if ((firstBody.physicsBody.categoryBitMask == ballCategory) &&
    (secondBody.physicsBody.categoryBitMask == ballCategory2))
{
    NSLog(@"click");
}

What you have is incorrect, as you're not testing the value of anything. You need to use your if statement to check if the firstBody and secondBody have a categoryBitMask set equal to specific ballCategory variable values.

Upvotes: 1

Related Questions