Не уверен, почему вы создаете пулю так, как вы делаете. Я думаю, что это должно выглядеть больше по линии. При создании подкласса SKSpriteNode вы должны переопределить инициализатор, чтобы добавить свои собственные настройки.
class Bullet: SKSpriteNode {
init() {
let size = CGSize(width: 2, height: 10)
super.init(texture: nil, color: .white, size: size)
self.name = "bullet"
self._setupBody(size: size)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
//Prefix private methods with an underscore
private func _setupBody(size: CGSize) {
self.physicsBody = SKPhysicsBody(rectangleOf: size)
self.physicsBody?.isDynamic = true
self.physicsBody?.allowsRotation = false
self.physicsBody?.pinned = false
self.physicsBody?.affectedByGravity = false
self.physicsBody?.categoryBitMask = PhysicsCategory.Bullet
self.physicsBody?.collisionBitMask = PhysicsCategory.Enemy
self.physicsBody?.contactTestBitMask = PhysicsCategory.Enemy
}
}
Причина, по которой при попытке приведения в качестве Bullet создается ноль, заключается в том, что вы создаете SKSpriteNode при вызове newBullet.CreateBullet()
вместо экземпляра класса Bullet.
Наконец, в физикаКонтакт, в контакте два тела. Мы не знаем, кто враг, а кто пуля. Таким образом, мы можем написать код для обоих случаев, хотя, если вы проверяете больше коллизий, есть лучшие способы, такие как этот ответ: Определение тел контакта
class BulletScene:SKScene, SKPhysicsContactDelegate {
func didBegin(_ contact: SKPhysicsContact) {
//Case #1: Bullet = bodyA and Enemy = bodyB
if let bullet = contact.bodyA.node as? Bullet, let enemy = contact.bodyB as? Enemy {
print("Bullet was BodyA!")
//Case #2: Bullet = bodyB and Enemy = bodyA
}else if let enemy = contact.bodyA as? Enemy, let bullet = contact.bodyB.node as? Bullet {
print("Bullet was BodyB!")
}
}
}