SITUTATION:
Already searched extensively, didn't find a solution.
For example, this does not help: Swift/SpriteKit Multiple Collision Detection?
PROBLEM:
My code works fine except when the player hits two different PhysicsCategory Objects at the same time (falls and hits exactly the ground and a wall at the same time for example). This makes my app crash.
CODE:
struct PhysicsCategory {
static let player: UInt32 = 0x1 << 1
static let ground: UInt32 = 0x1 << 2
static let wall: UInt32 = 0x1 << 3
static let scoreWall: UInt32 = 0x1 << 4
}
func didBeginContact(contact: SKPhysicsContact) {
let firstBody = contact.bodyA
let secondBody = contact.bodyB
if firstBody.categoryBitMask == PhysicsCategory.scoreWall && secondBody.categoryBitMask == PhysicsCategory.player || firstBody.categoryBitMask == PhysicsCategory.player && secondBody.categoryBitMask == PhysicsCategory.scoreWall {
score += 1
scoreLabel.text = "\(score)"
updatePlayerColor()
}
else if firstBody.categoryBitMask == PhysicsCategory.wall && secondBody.categoryBitMask == PhysicsCategory.player || firstBody.categoryBitMask == PhysicsCategory.player && secondBody.categoryBitMask == PhysicsCategory.wall {
lost = true
self.scene?.speed = 0
gameVC?.dismissViewControllerAnimated(false, completion: nil)
//playDeathAnimation with completion block self.dismiss(VC)
}
else if firstBody.categoryBitMask == PhysicsCategory.ground && secondBody.categoryBitMask == PhysicsCategory.player || firstBody.categoryBitMask == PhysicsCategory.player && secondBody.categoryBitMask == PhysicsCategory.ground {
lost = true
self.scene?.speed = 0
gameVC?.dismissViewControllerAnimated(false, completion: nil)
//playDeathAnimation with completion block self.dismiss(VC)
}
}
Debugger Error:
Fatal Error: Index out of range.
What I am looking for:
I just want to know if the double collision is accounted for in my code already or not. The debugger error refers to some other part of my code that is influenced by the collisions. But this would be too much code to add here. So please just answer on the following: how to account for double collisions in my SpriteKit game between ScoreWall and Wall ?
You don't have a double collision. You'll have 2 single collisions i.e. didBeginContact
will be called once for the collision between the player and the ground and again for the collision between the player and the wall. An SKPhysicsContact
can only have 2 bodies. Your crash is caused by something else, perhaps by the removal of the gameVC?
For an example of a 'cleaner' version of didBeginContact
, try this:
func didBeginContact(contact: SKPhysicsContact) {
let contactMask = contact.bodyA.categoryBitMask | contact.bodyB.categoryBitMask
switch contactMask {
// If the player and the scoreWall have collided:
case .player | .scoreWall :
score += 1
scoreLabel.text = "\(score)"
updatePlayerColor()
// If the player and the wall have collided:
case .player | .wall :
lost = true
self.scene?.speed = 0
gameVC?.dismissViewControllerAnimated(false, completion: nil)
// If the player and the ground have collided:
case .player | .ground :
lost = true
self.scene?.speed = 0
gameVC?.dismissViewControllerAnimated(false, completion: nil)
default :
print("Some other contact has occurred")
}