我正在学习代码,脱胎于一个 "颜色开关 "教程。我试图加强我的知识,并创建了2个开关和球落。
一旦球接触到开关,我就会出现问题。我有一个did begin contact方法的两个开关,如果错误,调用gameOver方法。但当两个开关都出错时,它们同时调用gameOver方法,导致我的游戏崩溃。我该如何解决这个问题?任何帮助都将非常感激,谢谢!
目前的代码。
extension GameScene: SKPhysicsContactDelegate {
func didBegin(_ contact: SKPhysicsContact) {
let contactMask = contact.bodyA.categoryBitMask | contact.bodyB.categoryBitMask
if contactMask == PhysicsCategories.ballCategory | PhysicsCategories.switchCategory {
if let ball = contact.bodyA.node?.name == "Ball" ? contact.bodyA.node as? SKSpriteNode : contact.bodyB.node as? SKSpriteNode {
if currentColourIndex == switchState.rawValue {
score += 1
updateScoreLabel()
ball.run(SKAction.fadeOut(withDuration: 0.15)) {
ball.removeFromParent()
self.spawnBall()
}
} else {
gameOver()
}
}
}
let contactMask2 = contact.bodyA.categoryBitMask | contact.bodyB.categoryBitMask
if contactMask2 == PhysicsCategories2.ballCategory2 | PhysicsCategories2.switchCategory2 {
if let ball2 = contact.bodyA.node?.name == "Ball2" ? contact.bodyA.node as? SKSpriteNode : contact.bodyB.node as? SKSpriteNode {
if currentColourIndex2 == switchState2.rawValue {
score += 1
updateScoreLabel()
ball2.run(SKAction.fadeOut(withDuration: 0.15)) {
ball2.removeFromParent()
self.spawnBall2()
}
} else {
gameOver()
}
}
}
}
}
func gameOver() {
UserDefaults.standard.set(score, forKey: "RecentScore")
if score > UserDefaults.standard.integer(forKey: "Highscore") {
UserDefaults.standard.set(score, forKey: "Highscore")
}
let menuScene = MenuScene(size: view!.bounds.size)
view!.presentScene(menuScene)
}
首先要明白的是,它不是同时进行的。 是叫两次,但一次叫一次。
所以,要解决这个问题,只需将代码添加到 gameOver()
以至于第二次调用会被忽略。 比如说
var gameIsOver = false
func gameOver() {
guard !gameIsOver else { return }
gameIsOver = true
UserDefaults.standard.set(score, forKey: "RecentScore")
if score > UserDefaults.standard.integer(forKey: "Highscore") {
UserDefaults.standard.set(score, forKey: "Highscore")
}
let menuScene = MenuScene(size: view!.bounds.size)
view!.presentScene(menuScene)
}
如果你重用这个对象,你需要重新设置 gameIsOver
回到false。
另一个解决方法是让它安全地调用一次以上。 也许 view
在第二个调用中为nil。
你不应该使用 view!
如果你能帮助它。 更好的办法是
guard let view = view else { return }
在开始的时候,如果view为nil,函数将立即返回。如果view为nil,函数将立即返回。 在其余的函数中,你可以使用 view.bounds
或 view.presentScene
因为在守卫之后,视图不能为零。