swift 如何在SpriteKit中暂停通过SKAction运行的计时器

mklgxw1f  于 2023-06-21  发布在  Swift
关注(0)|答案(1)|浏览(116)

在我基于SpriteKit构建的游戏中,玩家有一定的时间来完成每一关,到期时会调用一个game over方法或下一关的方法。
因为我知道从不同的Angular 来看,使用NSTimer和SpriteKit是不好的,所以我在GameScene中所做的是将计时器构建为SKActions序列,如下所示:

private func runTimer(duration: TimeInterval) {
       let wait = SKAction.wait(forDuration: duration)
       let endLevel = SKAction.run { [weak self] in
          self?.handleEndLevel()
       }
       run(SKAction.sequence([wait, endLevel]), withKey: "timer")
}

因为我还有一个暂停按钮,它显示一个MenuScene,还有一个恢复按钮,我试图实现的是暂停/取消暂停计时器。实现这一点的正确方法是什么?
以下是我已经尝试过的,但没有成功:

  • GameScene属性isPaused设置为true
  • GameViewController中,显示GameScene/MenuScene时,设置SKTransitionpausesOutgoingScenepausesIncomingScene属性。
  • 引入timerNode作为子对象添加到场景中,然后输入timerNode.run并设置其isPaused属性。
  • 使用.speed而不是.isPaused

所有这些都导致相同的结果:即使游戏被暂停并重新开始,计时器也会像从未暂停一样运行,因此在应该结束之前结束关卡。由于我还在学习SpriteKit,我对isPaused属性的理解是,它用于确定是否执行操作,所以我认为已经运行的操作将被暂停,这可能是我的一部分错误,也许是这样。
我知道有个极端的解决办法我可以在暂停时调用removeAction(forKey: "timer"),同时存储它被删除的时间,通过一些计算,我可以设置另一个计时器,其中包含游戏恢复后剩余的时间。这看起来并不漂亮,而且过于复杂,我不敢相信苹果没有实现一些更容易的东西。

j5fpnvbx

j5fpnvbx1#

经过调试,我发现问题在于当用户点击暂停按钮时,我正在呈现另一个场景,并且我在ViewController中将gameScene.isPaused设置为true。如果我在GameScene中设置isPaused属性,而不显示其他场景,场景实际上会暂停。这种行为的原因我还不清楚。
一个重要的注意事项是,SKAudioNodes必须使用SKAction.pause单独暂停和恢复,否则背景音乐将暂停,但在恢复时,音频播放器状态和场景状态之间将存在(小)偏移。

相关问题