SITUTATION:
已经广泛搜索过,没有找到解决方案。
例如,这没有帮助:Swift/SpriteKit Multiple Collision Detection?
问题:
我的代码工作正常,除非玩家同时击中两个不同的PhysicsCategory对象(例如,同时击落并击中地面和墙壁)。这使我的应用程序崩溃。
CODE:
struct PhysicsCategory {
static let player: UInt32 = 0x1 << 1
static let ground: UInt32 = 0x1 << 2
static let wall: UInt32 = 0x1 << 3
static let scoreWall: UInt32 = 0x1 << 4
}
func didBeginContact(contact: SKPhysicsContact) {
let firstBody = contact.bodyA
let secondBody = contact.bodyB
if firstBody.categoryBitMask == PhysicsCategory.scoreWall && secondBody.categoryBitMask == PhysicsCategory.player || firstBody.categoryBitMask == PhysicsCategory.player && secondBody.categoryBitMask == PhysicsCategory.scoreWall {
score += 1
scoreLabel.text = "\(score)"
updatePlayerColor()
}
else if firstBody.categoryBitMask == PhysicsCategory.wall && secondBody.categoryBitMask == PhysicsCategory.player || firstBody.categoryBitMask == PhysicsCategory.player && secondBody.categoryBitMask == PhysicsCategory.wall {
lost = true
self.scene?.speed = 0
gameVC?.dismissViewControllerAnimated(false, completion: nil)
//playDeathAnimation with completion block self.dismiss(VC)
}
else if firstBody.categoryBitMask == PhysicsCategory.ground && secondBody.categoryBitMask == PhysicsCategory.player || firstBody.categoryBitMask == PhysicsCategory.player && secondBody.categoryBitMask == PhysicsCategory.ground {
lost = true
self.scene?.speed = 0
gameVC?.dismissViewControllerAnimated(false, completion: nil)
//playDeathAnimation with completion block self.dismiss(VC)
}
}
调试程序错误:
致命错误:索引超出范围。
我在寻找什么:
我只是想知道我的代码中是否已经考虑了双重碰撞。调试器错误是指我的代码中受冲突影响的其他部分。但这里添加的代码太多了。所以请回答以下问题:如何在ScoreWall和Wall之间的SpriteKit游戏中解决双重冲突?
答案 0 :(得分:1)
尝试这样的事情?它应该删除你的代码重复,并防止你的游戏超过逻辑发生两次。
func didBeginContact(contact: SKPhysicsContact) {
if (lost) {
return
}
var a = contact.bodyA.categoryBitMask
var b = contact.bodyB.categoryBitMask
if a > b {
swap(&a, &b)
}
if a == PhysicsCategory.player && b == PhysicsCategory.scoreWall {
score += 1
scoreLabel.text = "\(score)"
updatePlayerColor()
} else if a == PhysicsCategory.player && (b == PhysicsCategory.ground || b == PhysicsCategory.wall) {
lost = true
self.scene?.speed = 0
gameVC?.dismissViewControllerAnimated(false, completion: nil)
//playDeathAnimation with completion block self.dismiss(VC)
}
}
答案 1 :(得分:1)
你有什么样的错误?
无论如何,在删除重要部分之前,您可能必须等待物理模拟的结束(不知道应用程序的整个逻辑)。因此,在碰撞检测中设置lost
布尔条件是好的,但剩下的可能必须在didSimulatePhysics
或didFinishUpdate
中完成。
答案 2 :(得分:1)
你不会发生双重碰撞。您将有2次单次碰撞,即didBeginContact
将被调用一次,用于玩家与地面之间的碰撞,再次用于玩家与墙壁之间的碰撞。 SKPhysicsContact
只能有2个实体。您的崩溃是由其他原因造成的,可能是因为删除了游戏VC?
有关“清洁工”的例子。版本didBeginContact
,试试这个:
func didBeginContact(contact: SKPhysicsContact) {
let contactMask = contact.bodyA.categoryBitMask | contact.bodyB.categoryBitMask
switch contactMask {
// If the player and the scoreWall have collided:
case .player | .scoreWall :
score += 1
scoreLabel.text = "\(score)"
updatePlayerColor()
// If the player and the wall have collided:
case .player | .wall :
lost = true
self.scene?.speed = 0
gameVC?.dismissViewControllerAnimated(false, completion: nil)
// If the player and the ground have collided:
case .player | .ground :
lost = true
self.scene?.speed = 0
gameVC?.dismissViewControllerAnimated(false, completion: nil)
default :
print("Some other contact has occurred")
}