Usually you would do this
First you would store your bit mask categories if you are not doing it already.
enum PhysicsCategory {
static let ball: UInt32 = 0x1 << 0
static let wall: UInt32 = 0x1 << 1
static let enemy: UInt32 = 0x1 << 2
}
and than assign them like so to your sprites
ball.physicsBody?.categoryBitMask = PhysicsCategory.ball
ball.physicsBody?.contactTestBitMask = PhysicsCategory.wall | PhysicsCategory.enemy
wall.physicsBody?.categoryBitMask = PhysicsCategory.wall
wall.physicsBody?.contactTestBitMask = 0
enemy.physicsBody?.categoryBitMask = PhysicsCategory.enemy
enemy.physicsBody?.contactTestBitMask = 0
Note: Because ball checks for contacts with both wall and enemy in this example you would not need to tell wall or enemy to check contacts with ball.
Its fine to do it on 1 physics body so you can set it to 0 on the others unless they have other specific contacts to look for.
Than you can check for them in the contact method like so without the double if statements.
func didBegin(_ contact: SKPhysicsContact) {
let firstBody: SKPhysicsBody
let 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 == PhysicsCategory.ball) && (secondBody.categoryBitMask == PhysicsCategory.wall) {
}
if (firstBody.categoryBitMask == PhysicsCategory.ball) && (secondBody.categoryBitMask == PhysicsCategory.enemy) {
}
}
Also do not forget to set the delegate in didMoveToView of your scene for this to work.
physicsWorld.contactDelegate = self
Hope this helps