Murturn
Murturn

Reputation: 49

didBeginContact not called

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()
}

Upvotes: 2

Views: 4025

Answers (3)

0x141E
0x141E

Reputation: 12753

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)

Upvotes: 0

Rasukaru
Rasukaru

Reputation: 131

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

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

Upvotes: 13

Nicklas Ridewing
Nicklas Ridewing

Reputation: 2451

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.

Upvotes: 12

Related Questions