I have a game where Falling Nodes fall down and hit the Base Number Sprite Node and game logic is run from there. When I set up a new game from scratch the collision detection works exactly how it should. My problem occurs when I create a game from a previous save using NSCoding. In both cases (new game and continue from save game) the physics bodies are the same - dynamic, same size body, same contactTestBitMask, same categoryBitMask. I have tested all of this so I know it is true. The physics contact delegate is also set to the right object. In a game continued from a save, however, the contacts are not registered and I cannot figure out why. The only thing I can think of, but am unable to figure out is object which is set as my physics contact delegate and is the parent of the objects I want collision detection for gets loaded/unarchived without me actually calling decodeObjectForKey for it.
Any help would be much appreciated
func initBaseNumberSpritePhysicsBody() {
baseNumberSprite.physicsBody = nil
baseNumberSprite.physicsBody = SKPhysicsBody(rectangleOfSize: baseNumberSprite.size)
baseNumberSprite.physicsBody!.categoryBitMask = baseNumberCategory
baseNumberSprite.physicsBody!.contactTestBitMask = fallingNodeCategory
baseNumberSprite.physicsBody!.collisionBitMask = 0
baseNumberSprite.physicsBody!.usesPreciseCollisionDetection = true
baseNumberSprite.physicsBody!.allowsRotation = false
}
func initPhysicsBodyForFallingNode(node: NumberNode) {
node.physicsBody = nil
node.physicsBody = SKPhysicsBody(rectangleOfSize: node.size)
node.physicsBody!.categoryBitMask = fallingNodeCategory
node.physicsBody!.contactTestBitMask = baseNumberCategory
node.physicsBody!.collisionBitMask = 0
node.physicsBody!.allowsRotation = false
node.physicsBody!.velocity = nodeVelocity
}
func didBeginContact(contact: SKPhysicsContact) {
if isContactBetween(fallingNodeCategory, and: baseNumberCategory, contact: contact) {
handleContactBetweenFallingNodeAndBaseNumber(contact)
} else {
print("\nUNKNOWN CONTACT OCCURED\n")
}
updateInternalState()
checkGameOverCondition()
}
required init?(coder aDecoder: NSCoder) {
// gameZone = aDecoder.decodeObjectForKey(gameZoneKey) as! GameZone
super.init(coder: aDecoder)
gameZone = self.children[0] as! GameZone //Not decoded by itself but somehow decoded with the this GameScene Object (the "self" object here)
gameZone.delegate = self
self.physicsWorld.contactDelegate = gameZone
}
override func encodeWithCoder(aCoder: NSCoder) {
super.encodeWithCoder(aCoder)
aCoder.encodeObject(gameZone, forKey: gameZoneKey) //Gets coded
}
I was able to figure out my own problem here. A fundamental understanding I was lacking is the SKNodes encode their own child nodes.
// gameZone = aDecoder.decodeObjectForKey(gameZoneKey) as! GameZone
The gameZone object is a child node. So I was encoding it as well as other key objects twice which was leading to my problem. The problem was had nothing to do with the physics world contact delegate or encoding/decoding.