swift - 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)
}
解决方案
首先要了解的是,它不是同时发生的。它被调用两次,但一次调用一次。
因此,要解决它,只需添加代码以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
因为在守卫之后视图不能为零。
推荐阅读
- python - 如何使用 SCPClient 创建目录
- java - 有没有办法在 Java 控制台中对 MineSweeper 游戏的行和列进行编号?
- amazon-web-services - AWS Cloudfront:是否可以使用一个 HTTPS 证书来覆盖 example.com 和 www.example.com?
- android - 当通知出现在颤动中时如何启动特定屏幕
- python - 在 Python 中比较和选择两个不同 CSV 文件中的数据
- flutter - 颤动:用列表视图填充屏幕的剩余空间
- kotlin - 如何在特定时区将即时时间 UTC 转换为 EpochMilli
- c# - C# 实体框架/ASP.NET REST 和模型设计模式或解决方案架构
- terminal - 配置热键窗口后,波浪号在 iTerm 中没有响应
- amazon-web-services - 不同的 Pod 使用相同的 socket