Swift 5 从两个方法中同时调用GameOver方法导致游戏崩溃

问题描述 投票:0回答:1

我正在学习代码,脱胎于一个 "颜色开关 "教程。我试图加强我的知识,并创建了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)
  }
swift physics contacts simultaneous
1个回答
1
投票

首先要明白的是,它不是同时进行的。 是叫两次,但一次叫一次。

所以,要解决这个问题,只需将代码添加到 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.boundsview.presentScene 因为在守卫之后,视图不能为零。

© www.soinside.com 2019 - 2024. All rights reserved.