Swift 5 Вызов метода GameOver одновременно из двух методов, вызывающих сбой игры - PullRequest
2 голосов
/ 01 мая 2020

Я учусь кодировать и изучаю учебник "Переключатель цвета". Я попытался укрепить свои знания и создал 2 переключателя и падающие шары.

У меня проблемы с контактами шаров с переключателями. У меня есть метод начала контакта для обоих коммутаторов, и, если он неправильный, вызывает метод gameOver Но когда оба переключателя неверны, они оба вызывают метод gameOver одновременно, в результате чего моя игра выдает cra sh. Как я могу решить это? Любая помощь будет высоко ценится, спасибо!

Текущий код:

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)
  }

1 Ответ

1 голос
/ 01 мая 2020

Первое, что нужно понять, это то, что оно не одновременное. Он вызывается дважды, но по одному.

Итак, чтобы решить эту проблему, просто добавьте код к 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 равен нулю, функция немедленно вернется. В остальных случаях вы можете использовать view.bounds или view.presentScene, потому что вид не может быть нулевым после охраны.

...