Reputation: 49
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
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
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
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