首页 > 解决方案 > Swift 5 从两种方法同时调用 GameOver 方法导致游戏崩溃

问题描述

我正在学习编码并学习“颜色切换”教程。我试图加强我的知识并创造了 2 个开关和落球。

一旦球与开关接触,我就会遇到问题。我有两个开关的开始联系方法,如果错误,调用 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)
  }

标签: swiftphysicscontactssimultaneous

解决方案


首先要了解的是,它不是同时发生的。它被调用两次,但一次调用一次。

因此,要解决它,只需添加代码以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在第二次通话中为零。

view!如果你能帮助它,你永远不应该使用它。更好的方法是

guard let view = view else { return }

一开始。如果 view 为 nil,该函数将立即返回。在其余的功能中,您可以使用view.bounds或者view.presentScene因为在守卫之后视图不能为零。


推荐阅读