多次检测到单次碰撞
Single collisions being detected multiple times
我已阅读此处发布的类似问题,但其中 none 完全解决了我的问题。
我只使用 iOS 几个月。
我的碰撞在 90% 的时间里都有效,但偶尔我会与同一个物体发生碰撞。这永远不会发生,因为 2 个对象之一应该爆炸。
有时这会导致致命的崩溃,似乎是因为它试图 运行 已经执行的后续代码。
基本上当飞船有护盾时我希望小行星爆炸而不是飞船。我已放入 "if bonus == 0" 语句来完成此操作。
相关代码我已经贴出来了,如果你需要更多,请告诉我。
我是不是把代码弄得太复杂了?还是我应该采取另一种方法?
enum PhysicsCategory : UInt32 {
case None = 0
case objectGroup = 1
case birdGroup = 2
case shieldGroup = 4
case gapGroup = 8
case boundaryGroup = 16
case bonusGroup = 32
}
.....
func didBeginContact(contact: SKPhysicsContact) {
if bonus == 0 {
let contactMask = contact.bodyA.categoryBitMask | contact.bodyB.categoryBitMask
switch contactMask {
....
case PhysicsCategory.birdGroup.rawValue | PhysicsCategory.objectGroup.rawValue:
if contact.bodyA.categoryBitMask == PhysicsCategory.birdGroup.rawValue {
gameOverActions()
} else if contact.bodyB.categoryBitMask == PhysicsCategory.birdGroup.rawValue {
gameOverActions()
}
default:
fatalError("other collision: \(contactMask)")
}
} else if bonus > 0 {
println("Bonus > 0")
let contactMask = contact.bodyA.categoryBitMask | contact.bodyB.categoryBitMask
switch contactMask {
....
case PhysicsCategory.birdGroup.rawValue | PhysicsCategory.objectGroup.rawValue:
if contact.bodyA.categoryBitMask == PhysicsCategory.birdGroup.rawValue {
let secondBody = contact.bodyB.node
let asteroidExplosionNode = secondBody?.position
//asteroidExplosion()
let asteroidExplosionEmitter3 = SKEmitterNode(fileNamed: "explosionSmoke.sks")
asteroidExplosionEmitter3.position = asteroidExplosionNode!
asteroidExplosionEmitter3.name = "asteroidExplosionEmitter3"
asteroidExplosionEmitter3.zPosition = 25
asteroidExplosionEmitter3.targetNode = self
movingObjects.addChild(asteroidExplosionEmitter3)
secondBody?.removeFromParent()
bonus--
bonusUsed++
bonusIndicator.text = "x\(bonus)"
bonusIndicatorShadow.text = "x\(bonus)"
if bonus >= 1 {
shieldAnimate()
} else if bonus == 0 {
shield.removeFromParent()
}
} else if contact.bodyB.categoryBitMask == PhysicsCategory.birdGroup.rawValue {
let secondBody = contact.bodyA.node
let asteroidExplosionNode = secondBody?.position
//asteroidExplosion()
let asteroidExplosionEmitter3 = SKEmitterNode(fileNamed: "explosionSmoke.sks")
asteroidExplosionEmitter3.position = asteroidExplosionNode!
asteroidExplosionEmitter3.name = "asteroidExplosionEmitter3"
asteroidExplosionEmitter3.zPosition = 25
asteroidExplosionEmitter3.targetNode = self
movingObjects.addChild(asteroidExplosionEmitter3)
secondBody?.removeFromParent()
bonus--
bonusUsed++
bonusIndicator.text = "x\(bonus)"
bonusIndicatorShadow.text = "x\(bonus)"
if bonus >= 1 {
shieldAnimate()
} else if bonus == 0 {
shield.removeFromParent()
}
}
default:
fatalError("other collision: \(contactMask)")
}
}
}
由于您要删除碰撞时的 node
,您可以在执行其余代码之前检查 parent
是否为 nil
。
let secondBody = contact.bodyB.node
if secondBody?.parent != nil {
// Asteroid explosion and bonus code.
}
我已阅读此处发布的类似问题,但其中 none 完全解决了我的问题。 我只使用 iOS 几个月。
我的碰撞在 90% 的时间里都有效,但偶尔我会与同一个物体发生碰撞。这永远不会发生,因为 2 个对象之一应该爆炸。
有时这会导致致命的崩溃,似乎是因为它试图 运行 已经执行的后续代码。
基本上当飞船有护盾时我希望小行星爆炸而不是飞船。我已放入 "if bonus == 0" 语句来完成此操作。
相关代码我已经贴出来了,如果你需要更多,请告诉我。
我是不是把代码弄得太复杂了?还是我应该采取另一种方法?
enum PhysicsCategory : UInt32 {
case None = 0
case objectGroup = 1
case birdGroup = 2
case shieldGroup = 4
case gapGroup = 8
case boundaryGroup = 16
case bonusGroup = 32
}
.....
func didBeginContact(contact: SKPhysicsContact) {
if bonus == 0 {
let contactMask = contact.bodyA.categoryBitMask | contact.bodyB.categoryBitMask
switch contactMask {
....
case PhysicsCategory.birdGroup.rawValue | PhysicsCategory.objectGroup.rawValue:
if contact.bodyA.categoryBitMask == PhysicsCategory.birdGroup.rawValue {
gameOverActions()
} else if contact.bodyB.categoryBitMask == PhysicsCategory.birdGroup.rawValue {
gameOverActions()
}
default:
fatalError("other collision: \(contactMask)")
}
} else if bonus > 0 {
println("Bonus > 0")
let contactMask = contact.bodyA.categoryBitMask | contact.bodyB.categoryBitMask
switch contactMask {
....
case PhysicsCategory.birdGroup.rawValue | PhysicsCategory.objectGroup.rawValue:
if contact.bodyA.categoryBitMask == PhysicsCategory.birdGroup.rawValue {
let secondBody = contact.bodyB.node
let asteroidExplosionNode = secondBody?.position
//asteroidExplosion()
let asteroidExplosionEmitter3 = SKEmitterNode(fileNamed: "explosionSmoke.sks")
asteroidExplosionEmitter3.position = asteroidExplosionNode!
asteroidExplosionEmitter3.name = "asteroidExplosionEmitter3"
asteroidExplosionEmitter3.zPosition = 25
asteroidExplosionEmitter3.targetNode = self
movingObjects.addChild(asteroidExplosionEmitter3)
secondBody?.removeFromParent()
bonus--
bonusUsed++
bonusIndicator.text = "x\(bonus)"
bonusIndicatorShadow.text = "x\(bonus)"
if bonus >= 1 {
shieldAnimate()
} else if bonus == 0 {
shield.removeFromParent()
}
} else if contact.bodyB.categoryBitMask == PhysicsCategory.birdGroup.rawValue {
let secondBody = contact.bodyA.node
let asteroidExplosionNode = secondBody?.position
//asteroidExplosion()
let asteroidExplosionEmitter3 = SKEmitterNode(fileNamed: "explosionSmoke.sks")
asteroidExplosionEmitter3.position = asteroidExplosionNode!
asteroidExplosionEmitter3.name = "asteroidExplosionEmitter3"
asteroidExplosionEmitter3.zPosition = 25
asteroidExplosionEmitter3.targetNode = self
movingObjects.addChild(asteroidExplosionEmitter3)
secondBody?.removeFromParent()
bonus--
bonusUsed++
bonusIndicator.text = "x\(bonus)"
bonusIndicatorShadow.text = "x\(bonus)"
if bonus >= 1 {
shieldAnimate()
} else if bonus == 0 {
shield.removeFromParent()
}
}
default:
fatalError("other collision: \(contactMask)")
}
}
}
由于您要删除碰撞时的 node
,您可以在执行其余代码之前检查 parent
是否为 nil
。
let secondBody = contact.bodyB.node
if secondBody?.parent != nil {
// Asteroid explosion and bonus code.
}