通知和暂停模式
Posted
技术标签:
【中文标题】通知和暂停模式【英文标题】:Notifications and pause mode 【发布时间】:2016-09-24 16:06:06 【问题描述】:我正在使用 Swift 和 SpriteKit 制作一些游戏。 当我的应用程序进入后台时,它会调用一个函数 pause,但它会在游戏恢复时自动取消暂停。
func pauseTheGame()
self.scene?.isPaused = true
AppDelegate
func applicationWillResignActive(_ application: UIApplication)
NotificationCenter.default.post(name: NSNotification.Name(rawValue: "goToBackground"), object: self)
游戏场景
NotificationCenter.default.addObserver(self, selector: #selector(GameScene.pauseTheGame), name: NSNotification.Name("goToBackground"), object: nil)
我该如何解决?
【问题讨论】:
这可能是您正在寻找的(注意:未使用更新的 ios 版本进行测试)***.com/questions/26317553/… 如果它立即取消暂停,则可能您的暂停游戏函数实际上并未被调用。在SpriteKit
中,离开应用程序时场景会自动暂停,返回游戏时会自动取消暂停。将fatalError()
添加到您的函数以检查它是否正在运行
有一个错误,游戏会取消暂停,只需在场景类中添加一个名为CBApplicationDidBecomeActive
的空方法,这将删除自动取消暂停
如果你的目标是 iOS 10,试试这个 ***.com/questions/26317553/…
【参考方案1】:
我认为暂停整个场景并不理想,最好有一个 worldNode 并暂停该节点。这也将使您更轻松地覆盖菜单节点等。 Apple 在他们的示例游戏 DemoBots 中也这样做了。
在场景中创建一个世界节点和一个 isGamePause 属性
var isGamePaused = false
let worldNode = SKNode()
并将其添加到 didMoveToView
addChild(worldNode)
将所有精灵添加到该节点
worldNode.addChild(someSprite1)
worldNode.addChild(someSprite2)
比你说的暂停功能
func pauseTheGame()
isGamePaused = true
worldNode.paused = true
physicsWorld.speed = 0
/// show pause menu
你的简历功能应该说
func resumeTheGame()
isGamePaused = false
worldNode.paused = false
physicsWorld.speed = 1
// remove pause menu
为了额外确保您的游戏在暂停时不会继续,我在更新方法中添加了一个检查以保持游戏暂停。
override func update(_ currentTime: TimeInterval)
guard !isGamePaused else
worldNode.paused = true
physicsWorld.speed = 0
return
...
作为提示,您应该始终将字符串键组织到属性中以避免拼写错误,例如通知中心名称、UserDefaults 键、SKAction 键等。 使用通知中心名称的 Swift 3,您现在可以创建一个扩展并以非常简洁的方式处理它们。
extension NSNotification.Name
static let goToBackground = Notification.Name(rawValue: "goToBackground")
现在你可以说
NotificationCenter.default.post(name: .goToBackground, object: self)
NotificationCenter.default.addObserver(self, selector: #selector(pauseTheGame), name: .goToBackground, object: nil)
希望对你有帮助
【讨论】:
有时可能需要暂停整个场景,主要是在处理游戏经过的时间时。顺便说一句,当应用程序进入后台/前台时已经触发了通知,因此添加另一个观察者效率不高。不幸的是,获得这些列表很困难,因此您可能只需要进入 api 标头。将UIApplicationWillResignActiveNotification
添加到您的代码中并单击它,它应该会将您带到所有这些的标题。
我的游戏也是这样,进入后台时需要手动暂停游戏,恢复时保持暂停。让 sprite kit 做暂停和恢复是不好的。我见过太多这样的游戏,而且用户体验很差。当您在玩游戏时最小化应用程序时,您希望游戏进入暂停菜单,并且在 applicationWillResignActive 中有一个 NotificationObserver 是调用暂停方法的便捷方式。不需要暂停整个场景,在尝试覆盖菜单节点或运行 SKActions 时尤其困难。
我已经通知苹果工程师他们的暂停设计不好,应该有 2 个暂停变量,一个在 API 内部,一个在用户外部。在两者都为假的情况下,节点运行。这允许苹果在他们认为合适时暂停节点,同时保留用户预期的暂停状态。当然,他们只是不理我,说他们不会改变暂停的工作方式,哈哈,所以我们都必须处理变通方法。
同意暂停设计。 pause 场景或 skView 方法基本没用。我从一开始就一直在使用 worldNode,这是我做的第一件事,因为暂停场景让我非常头疼。它也往往会给你这种令人不快的混蛋,而且看起来不太好。如果你正在玩,你必须从 willResignActive 调用你的暂停菜单代码。通知中心或委托是最简单的方法。我讨厌当你打开应用程序时游戏自动恢复。目前流行的游戏《火星:火星》也是如此,至少在 Apple TV 上也是如此,而且很糟糕。
即使您只是收到消息或通知警报或 AlertControllers,您也应该始终进入暂停菜单并让播放器在准备好后继续播放。以上是关于通知和暂停模式的主要内容,如果未能解决你的问题,请参考以下文章