通知和暂停模式

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,您也应该始终进入暂停菜单并让播放器在准备好后继续播放。

以上是关于通知和暂停模式的主要内容,如果未能解决你的问题,请参考以下文章

Facebook 聊天 API - XMPP 输入暂停通知

意图恢复先前暂停的活动(从通知中调用)

如何在 iOS 中安排可以暂停或删除的本地通知?

当应用程序进入暂停状态时取消本地通知。(从后台删除)

通知中的播放/暂停按钮图像,Android

打开应用程序或解除暂停时,警报或通知能否调出特定视图?