如何避免在SpriteKit中传递currentTime?

时间:2015-04-14 09:49:02

标签: ios swift time sprite-kit

我在开发我的应用程序时发现,为了实现业务逻辑,我的一些节点需要访问传递给update方法的currentTime。

将此作为参数传递给可能需要它的所有初始化程序和方法似乎很麻烦。

我想知道其他开发人员可能对这个问题有什么解决方案(有没有标准模式)。访问系统时间是一种选择,但可能存在一些开销,并且每次调用它时都会有所不同。

也许可以使用全局,但我想知道在闭包中是否存在任何线程问题或问题。

选项?

3 个答案:

答案 0 :(得分:2)

好吧,我想你可以创建某种全局变量,例如:

static var _currentTime: CFTimeInterval = 0

然后在您的更新功能中,您可以将当前时间分配给该变量:

override func update(currentTime: CFTimeInterval) {
    _currentTime = currentTime
}

只要您在任何范围之外声明全局变量,您就应该能够从游戏中的任何位置访问它。

答案 1 :(得分:1)

我开始使用全局变量方法,这是一个明显的答案和一个上升的方法。这很简单,但我并不满意。最后,我采用了以下看似清洁的方法。

我现在直接或间接地从SKAction.runBlockSKAction.customActionWithDuration开始的操作块运行我的所有自定义定时操作。

如果我想知道特定事件的时间,我会在我的行动列表中插入如下操作:

SKAction.customActionWithDuration(level.duration, actionBlock : {(node, elapsedTime) in
    self.elapsedTime = elapsedTime
})

如果我需要与此计时器并行执行其他操作,我只需使用SKAction.group同时运行所有内容。

唯一的小问题是该块引用self,我从不喜欢它,因为它使得它依赖于作为节点的动作的创建者,但是你总是可以将node强制转换为实际节点类型并使用它。

更新:

我发现SpriteKit中的操作执行并不是那么可靠,就实际开始和结束的时间而言。似乎有一些可能的漂移 - 也许一个动作的开始可以被框架延迟,或者可能在序列期间发生漂移。在前一种情况下,当您认为时钟时,时钟可能不会开始滴答作响。因此,对于恒定的参考时间,使用全局变量方法可能更好。

答案 2 :(得分:1)

在我正在制作的应用中,我实现了以下功能:

protocol Updatable {
    func update(currentTime: NSTimeInterval)
}

Updatable将由您希望根据当前时间更新的任何节点实现。

然后您需要一个自定义SKScene,它将更新符合Updatable的所有子节点。对于Swift 2:

class MyScene: SKScene {
    public override func update(currentTime: NSTimeInterval) {
        super.update(currentTime)

        for case let child as Updateable in children {
            child.update(currentTime)
        }
    }
}

或者,对于Swift 1使用:

for child in children {
    if let updateableNode = child as? Updateable {
        updateableNode.update(currentTime)
    }
}

完成后,您只需要确保SKScene个子类都是MyScene的子类。