My Hero / Player instance can get destroyed by either touching an enemy instance or a enemyBullet instance. This is my enemy:
physicsBody = SKPhysicsBody(rectangleOfSize: size)
physicsBody?.categoryBitMask = PhysicsCategory.enemy
physicsBody?.collisionBitMask = 0
physicsBody?.contactTestBitMask = PhysicsCategory.bullet
physicsBody?.affectedByGravity = false
physicsBody?.allowsRotation = false
physicsBody?.dynamic = true
This is my enemyBullet:
bullet.physicsBody = SKPhysicsBody(rectangleOfSize: bullet.size)
bullet.physicsBody?.categoryBitMask = PhysicsCategory.enemyBullet
bullet.physicsBody?.contactTestBitMask = PhysicsCategory.hero
bullet.physicsBody?.affectedByGravity = false
bullet.physicsBody?.dynamic = false
And this is my hero:
physicsBody = SKPhysicsBody(rectangleOfSize: size)
physicsBody?.affectedByGravity = false
physicsBody?.categoryBitMask = PhysicsCategory.hero
physicsBody?.contactTestBitMask = PhysicsCategory.enemy | PhysicsCategory.enemyBullet
physicsBody?.dynamic = false
My Player does properly contact with enemy instances, but does not contact with enemyBullets. Instead, there is a random SKPhysicsContact instantiated, when a enemy shoots. This is what my handling function looks like:
func didBeginContact(contact: SKPhysicsContact) {
// Enemy + bullet
if((contact.bodyA.categoryBitMask == PhysicsCategory.enemy && contact.bodyB.categoryBitMask == PhysicsCategory.bullet) || (contact.bodyA.categoryBitMask == PhysicsCategory.bullet && contact.bodyB.categoryBitMask == PhysicsCategory.enemy)) {
// TODO
}
// Hero + enemy
else if((contact.bodyA.categoryBitMask == PhysicsCategory.hero && contact.bodyB.categoryBitMask == PhysicsCategory.enemy) || (contact.bodyA.categoryBitMask == PhysicsCategory.enemy && contact.bodyB.categoryBitMask == PhysicsCategory.hero)) {
print("HERO AND ENEMY")
}
// Hero + enemyBullet
else if((contact.bodyA.categoryBitMask == PhysicsCategory.hero && contact.bodyB.categoryBitMask == PhysicsCategory.enemyBullet) || (contact.bodyA.categoryBitMask == PhysicsCategory.enemyBullet && contact.bodyB.categoryBitMask == PhysicsCategory.hero)) {
print("HERO AND BULLET")
}
else {
print("DEBUG: \(contact.bodyA.categoryBitMask) AND ˜\(contact.bodyB.categoryBitMask)")
}
}
So: What happens is that whenever an enemy shoots (shooting enemyBullet), it will run to the else in my handling function. This will print "DEBUG: 1 AND 6". 1 = enemy, 6 = enemyBullet.
Why should my enemy throw a contact when he shoots the bullet? How can i make my game detect when the hero is hit by enemyBullet?
EDIT: Thanks to @KnightOfDragon:
When using the ContactBitMask and CategoryBitMask make sure to not simply set them to 1,2,3,4,etc. Set them to:
static let environment: UInt32 = 0b00000000000000000000000000000001 static let powerup: UInt32 = 0b00000000000000000000000000000010 static let hero: UInt32 = 0b00000000000000000000000000100000 static let bullet: UInt32 = 0b00000000000000000000000001000000 static let enemy: UInt32 = 0b00000000000000000100000000000000 static let enemyBullet: UInt32 = 0b00000000000000001000000000000000
static let enemyAndEnemyBullet: UInt32 = 0b00000000000000001100000000000000
For the love of god: When using sprites where you expect contacts from aka SKPhysicsContact, always set them to
dynamic = true
. Otherwise it won't work.