The problem with your code is that didBeginContact is called several times ... You can verify this by placing the print() if inside this if block.
As you already know, the SKPhysicsBody object has a node property. This is an optional property. It represents the node this body is associated with. In your case, it is a node mushroom.
So, when didBeginContact is called for the first time because you remove the node mushroom from your parent, bodyA.node becomes nil . The next time doing bodyA.node!.removeFromParent() will crash, because, as I said, bodyA.node now zero, but you use forced deployments to access the base cost optional.
Use forced deployment only when you are 100% sure that the base value is not zero (or if you intentionally want to cause an error at the design stage). Otherwise, use extra binding or extra chain. Like this:
func didBeginContact(contact: SKPhysicsContact) { var firstBody, secondBody: SKPhysicsBody //Do this to avoid double checking if contact.bodyA.categoryBitMask < contact.bodyB.categoryBitMask { firstBody = contact.bodyA secondBody = contact.bodyB } else { firstBody = contact.bodyB secondBody = contact.bodyA } //No need for double-checking now if ((firstBody.categoryBitMask & PhysicsCategory.Panda) != 0 && (secondBody.categoryBitMask & PhysicsCategory.Score != 0)) { //This will fail gracefully if node property is nil secondBody.node?.removeFromParent() } }
source share