2
votes

I am making a game in which I need my spriteNodes to collide. I followed a tutorial but it just isn't working for me.

When I run my game and two objects collide, there is no println("beginContact") in the output monitor, so the didBeginContact function isn't called.

override init(size:CGSize) {
    super.init(size: size)
    player.planeSprite = SKSpriteNode(imageNamed: "plane5")

    player.planeSprite.physicsBody? = SKPhysicsBody(rectangleOfSize: player.planeSprite.size)
    player.planeSprite.physicsBody?.dynamic = true;
    player.planeSprite.physicsBody?.categoryBitMask = playerCategory;
    player.planeSprite.physicsBody?.contactTestBitMask = noteCategory;
    player.planeSprite.physicsBody?.collisionBitMask = 0;
    player.planeSprite.physicsBody?.usesPreciseCollisionDetection = true;

    player.planeSprite.position = CGPointMake(player.legalPositions[1], player.planeSprite.size.height/2)

    self.addChild(player.planeSprite)
}

func addNote() {
    var note:SKSpriteNode = SKSpriteNode(imageNamed: "note")
    note.physicsBody? = SKPhysicsBody(rectangleOfSize: note.size)
    note.physicsBody?.dynamic = true
    note.physicsBody?.categoryBitMask = noteCategory
    note.physicsBody?.contactTestBitMask = playerCategory
    note.physicsBody?.collisionBitMask = 0

    let minX = note.size.width/2
    let maxX = self.frame.size.width - note.size.width/2
    let rangeX = maxX - minX
    let position = Int(arc4random_uniform(3))

    note.position = CGPointMake(player.legalPositions[position], self.frame.size.height + note.size.height)

    self.addChild(note)
}

func didBeginContact(contact: SKPhysicsContact!) {
    println("beginContact")

    var firstBody:SKPhysicsBody
    var secondBody:SKPhysicsBody

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

    if((firstBody.categoryBitMask & noteCategory) != 0 && (secondBody.categoryBitMask & playerCategory) != 0 ) {
        println("if statement")
        playerDidCollideWithNote(firstBody.node as SKSpriteNode, note: secondBody.node as SKSpriteNode)
    }
}

func playerDidCollideWithNote(plane:SKSpriteNode, note:SKSpriteNode) {
    println("hit")
    note.removeFromParent()
}
3
Usually issues where functions are not called is because the .delegate property is not set.JMFR
yup you need to set the scene as the physics world delegateLearnCocos2D
Do you mean like this: class GameScene: SKScene, SKPhysicsContactDelegate{Murturn
Yes, and add "self.physicsWorld.contactDelegate = self" to your didMoveToView method.0x141E
I did that and it still wont workMurturn

3 Answers

13
votes

If you use Xcode8.0 Swift3.0, You cannot use
func didBeginContact(contact: SKPhysicsContact!) {}

So you should use this. func didBegin(_ contact: SKPhysicsContact) {}

12
votes

Done this misstake several times.

You first need to inherit from SKPhysicsContactDelegate :

class GameScene: SKScene, SKPhysicsContactDelegate { ... }

And then in your didMoveToView method, add:

override func didMoveToView(view: SKView) {
    self.physicsWorld.contactDelegate = self
}

To set your GameScene instance as the contactDelegate for the physicsWorld.

0
votes

From the docs,

An object that implements the SKPhysicsContactDelegate protocol can respond when two physics bodies with overlapping contactTestBitMask values are in contact with each other in a physics world. To receive contact messages, you set the contactDelegate property of a SKPhysicsWorld object. The delegate is called when a contact starts or ends.

Consequently, you'll need to adopt the SKPhysicsContactDelegate protocol and set the physicsWorld's contactDelegate property to the SKScene by

class GameScene: SKScene, SKPhysicsContactDelegate {
    override func didMove(to view: SKView) {
        physicsWorld.contactDelegate = self
    }
}

Also, you should remove the ? from the following statements

player.planeSprite.physicsBody? = SKPhysicsBody(rectangleOfSize: player.planeSprite.size)

note.physicsBody? = SKPhysicsBody(rectangleOfSize: note.size)