使用更新当前时间来跟踪游戏时间

时间:2019-08-20 13:03:23

标签: ios swift sprite-kit gameplay-kit

我很好奇是否有人能够找到一种方法来保持场景活跃多长时间。这对于我需要触发某些事件(例如说“在游戏开始前5分钟内生成武器”)时至关重要。

更新周期的问题在于,当前流逝的时间不仅是活跃的游戏时间,因此,如果您接到电话或切换应用程序,则返回时将获得X分钟的时间跳动。

当前,我使用SKAction.customAction来跟踪自己的时间,并且可以正常工作,但是我无法保证动作触发的顺序,因此我的事件最终可能会偏离1帧。

这是我现在正在做的事情,请让我知道您为保持时间一致所做的事情。

///注意:NodeComponent是用于快速访问GKSKNodeComponent节点的协议扩展

import GameplayKit
class ElapsedTimeComponent:GKComponent,NodeComponent
{
    var elapsedTime : TimeInterval = 0.0
    override func didAddToEntity() {
        node.scene?.addComponentToComponentSystem(self)
        self.node.run(SKAction.customAction(withDuration:330000000000000000000000000000000000000){node,seconds in
            elapsedTime = seconds
            (node as! SKLabelNode).text = "\(seconds)"
        })

    }
    override func update(deltaTime seconds: TimeInterval) {
    }
}

1 个答案:

答案 0 :(得分:0)

事实证明,SKView有一个委托协议,您可以在任何地方附加它。我已经设置了最新的测试,如下所示:

public class GameScene: SKScene,SKViewDelegate {
    var previousTime : TimeInterval = 0
    var gameTime : TimeInterval = 0
    public func view(_ view: SKView, shouldRenderAtTime time: TimeInterval) -> Bool
    {
        if !self.isPaused{
            gameTime += time - previousTime
        }

        print("GameTime: \(gameTime)")
        componentSystems.forEach({$0.update(deltaTime: gameTime)})
        self.previousTime = time
        return !self.isPaused
    }
    public override func didMove(to view: SKView) {
        view.delegate = self     
    }
}

https://developer.apple.com/documentation/spritekit/skviewdelegate

如果我正确地理解了这一点,那么我唯一需要注意的就是确保从游戏返回时,view.isPaused不会在相同的确切时间取消暂停我的场景(嗯,为什么要做您对苹果公司这样做),以允许发生1个渲染循环。

当然,此方法的缺点是,由于禁用了渲染,我创建的任何暂停屏幕都必须位于该场景之外。