Reputation: 103
In my project I am trying to detect a collision between two SKSpriteNodes, but it will not work. Here is my code for the physics category :
struct PhysicsCategory {
static let enemy : UInt32 = 0x1 << 1
static let player : UInt32 = 0x1 << 3
static let neutral : UInt32 = 0x1 << 2
}
For the neutral, enemy and player bodies
neutral = SKSpriteNode(imageNamed: "Cave-Bottom")
neutral.size = CGSize(width: self.frame.width, height: self.frame.height / 8)
neutral.position = CGPoint(x: 0, y: self.frame.height / -2.5)
neutral.zPosition = 2
neutral.physicsBody?.categoryBitMask = PhysicsCategory.neutral
neutral.physicsBody?.collisionBitMask = PhysicsCategory.player
neutral.physicsBody?.contactTestBitMask = PhysicsCategory.player
neutral.physicsBody = SKPhysicsBody.init(rectangleOf: neutral.size)
enemy = SKSpriteNode(imageNamed: "spike")
enemy.size = CGSize(width: 40, height: 40)
enemy.position = CGPoint(x: 0, y: 0)
enemy.zPosition = 2
enemy.physicsBody = SKPhysicsBody.init(rectangleOf: enemy.size)
enemy.physicsBody?.categoryBitMask = PhysicsCatagory.enemy
enemy.physicsBody?.collisionBitMask = PhysicsCatagory.player
enemy.physicsBody?.contactTestBitMask = PhysicsCatagory.player
player = SKSpriteNode(imageNamed: "bob")
player.size = CGSize(width: 40, height: 40)
bob.zPosition = 3
player.physicsBody?.categoryBitMask = PhysicsCatagory.player
player.physicsBody?.collisionBitMask = PhysicsCatagory.enemy | PhysicsCatagory.neutral
player.physicsBody?.contactTestBitMask = PhysicsCatagory.enemy | PhysicsCatagory.neutral
player.physicsBody = SKPhysicsBody.init(rectangleOf: player.size)
And the code for my ContactHasBegan function:
func didBegin(_ contact: SKPhysicsContact) {
print("collided!")
if (contact.bodyA.categoryBitMask == PhysicsCatagory.enemy && contact.bodyB.categoryBitMask == PhysicsCatagory.player) {
print("player and enemy!")
}
if (contact.bodyB.categoryBitMask == PhysicsCatagory.enemy && contact.bodyA.categoryBitMask == PhysicsCatagory.player) {
print("player and enemy!")
}
if (contact.bodyA.categoryBitMask == PhysicsCatagory.neutral && contact.bodyB.categoryBitMask == PhysicsCatagory.player) {
print("neutral and player!")
}
if contact.bodyB.categoryBitMask == PhysicsCatagory.neutral && contact.bodyA.categoryBitMask == PhysicsCatagory.player{
print("neutral and player")
} }
For some reason it only detects a collision between the player and enemy and prints "Collided!" and none of the if statements in the didBeginContact function test out positive.
Upvotes: 1
Views: 58
Reputation: 8134
Because player's physicsBody
doesn't have it's category
and contactTest
bit masks set corrcetly.
You've created the player's physicsBody AFTER you tried to set the player's physicsBody's attributes:
player.physicsBody?.categoryBitMask = PhysicsCatagory.player
player.physicsBody?.collisionBitMask = PhysicsCatagory.enemy | PhysicsCatagory.neutral
player.physicsBody?.contactTestBitMask = PhysicsCatagory.enemy | PhysicsCatagory.neutral
player.physicsBody = SKPhysicsBody.init(rectangleOf: player.size)
In the first 3 lines of code, because player.physicsBody
is an optional, the rest of the line is ignored, as there is no physicsBody.
So the physics body is created with all properties set to default i.e. it collides with everything and contacts nothing.
You need to move the line :
player.physicsBody = SKPhysicsBody.init(....
to before the code where you set the physics body's attributes:
player.physicsBody = SKPhysicsBody.init(rectangleOf: player.size)
player.physicsBody?.categoryBitMask = PhysicsCatagory.player
player.physicsBody?.collisionBitMask = PhysicsCatagory.enemy | PhysicsCatagory.neutral
player.physicsBody?.contactTestBitMask = PhysicsCatagory.enemy | PhysicsCatagory.neutral
Upvotes: 4