如何捕捉 SKScene 暂停或 audioEngine 停止的时刻?
Posted
技术标签:
【中文标题】如何捕捉 SKScene 暂停或 audioEngine 停止的时刻?【英文标题】:How can I catch moment SKScene became paused or audioEngine became stopped? 【发布时间】:2016-08-23 16:38:04 【问题描述】:我有两个SKScene:GameScene 和EndScene,我在游戏过程中使用GameScene 的audioEngine 属性播放声音(该属性包含AVAudioEngine 对象)。游戏结束后,场景从 GameScene 变为 EndScene:
self.view?.presentScene(EndScene())
之后,当用户点击«Restart»时,游戏重新开始,场景从EndScene变回GameScene:
self.view?.presentScene(GameScene(), transition: SKTransition.crossFadeWithDuration(1.0))
当场景从 EndScene 切换到 GameScene 时,GameScene 会暂停一秒钟(因为参数值 SKTransition.crossFadeWithDuration(1.0))。由于 GameScene 被暂停,audioEngine 也被停止。在此之后,GameScene 会自动启动,但 audioEngine 不会启动并保持停止状态。然后,游戏在第一次尝试播放声音时崩溃,很明显:因为 audioEngine 已停止。 为了避免这种情况,我需要在它停止后启动audioEngine,但是在它发生的那一刻有一个问题要捕捉:我试图在GameScene的didMoveToView()中捕捉它,但是GameScene没有暂停,它后来暂停了,在 didMoveToView() 已经完成之后。 这是我的问题: 是否有适合这种情况的通知或事件处理程序?
【问题讨论】:
【参考方案1】:最后,我放弃了寻找一些合适的通知或事件的尝试,并决定每次在声音播放之前检查 audioEngine 状态,在函数中播放声音。我认为这种方式相当有效:
func playSound(soundType: Sounds)
if !audioEngine.running
do
try audioEngine.start()
catch
var soundNode = SKAudioNode()
var waitingDuration = Double()
switch soundType
case .enemyDestroyed:
soundNode = SKAudioNode(fileNamed: "Blip001.wav")
waitingDuration = 3
case .playerDestroyed:
soundNode = SKAudioNode(fileNamed: "Noise002.wav")
waitingDuration = 5
soundNode.autoplayLooped = false
self.addChild(soundNode)
soundNode.runAction(SKAction.changeVolumeTo(0.5, duration: 0))
soundNode.runAction(SKAction.changeReverbTo(0.5, duration: 0))
soundNode.runAction(SKAction.sequence([SKAction.play(), SKAction.waitForDuration(waitingDuration), SKAction.removeFromParent()]))
【讨论】:
【参考方案2】:每次调用帧(每秒 60 次)时,使用 update
函数检查这一点。在其中放置一个条件语句(if、while 等)来检查您想要的条件。例如,使用它来检查场景是否暂停:
override func update(currentTime: CFTimeInterval)
if isPaused == true
// Code to run when scene is paused
请注意,这是在 Swift 3 和更低版本中,isPaused
只是 paused
另一种选择是使用像 while
和 do-while
这样的循环来不断检查条件
【讨论】:
在问我的问题之前,我已经考虑过使用 update() 事件来捕捉这个,但在我看来这是一种相当粗糙的方式。使用 do-while 的方式(在 didMoveToView 结束时,正如我建议的那样)看起来更有效,感谢您的建议。但是,最后,我决定每次在播放声音之前检查 audioEngine 状态,在函数中播放声音。我认为这种方式相当有效。我已将其发布为下面我自己的问题的答案。以上是关于如何捕捉 SKScene 暂停或 audioEngine 停止的时刻?的主要内容,如果未能解决你的问题,请参考以下文章
在SKScene暂停时动画SKSpriteNode的alpha
如何在 MyScene(SKScene 的子类)中打开 xib 或故事板窗口?
呈现 SKScene 后取消隐藏 UIButtons 时延迟?