在我基于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
时,设置SKTransition
的pausesOutgoingScene
和pausesIncomingScene
属性。 - 引入
timerNode
作为子对象添加到场景中,然后输入timerNode.run
并设置其isPaused
属性。 - 使用
.speed
而不是.isPaused
。
所有这些都导致相同的结果:即使游戏被暂停并重新开始,计时器也会像从未暂停一样运行,因此在应该结束之前结束关卡。由于我还在学习SpriteKit,我对isPaused
属性的理解是,它用于确定是否执行操作,所以我认为已经运行的操作将被暂停,这可能是我的一部分错误,也许是这样。
我知道有个极端的解决办法我可以在暂停时调用removeAction(forKey: "timer")
,同时存储它被删除的时间,通过一些计算,我可以设置另一个计时器,其中包含游戏恢复后剩余的时间。这看起来并不漂亮,而且过于复杂,我不敢相信苹果没有实现一些更容易的东西。
1条答案
按热度按时间j5fpnvbx1#
经过调试,我发现问题在于当用户点击暂停按钮时,我正在呈现另一个场景,并且我在
ViewController
中将gameScene.isPaused
设置为true。如果我在GameScene
中设置isPaused
属性,而不显示其他场景,场景实际上会暂停。这种行为的原因我还不清楚。一个重要的注意事项是,
SKAudioNodes
必须使用SKAction.pause
单独暂停和恢复,否则背景音乐将暂停,但在恢复时,音频播放器状态和场景状态之间将存在(小)偏移。