绝对不要使用计时器。
SpriteKit 具有明确定义的更新周期,并且每种更新(逻辑、物理、图形)都应在明确定义的时间范围内发生。
如果您真的想在节点中编写更新逻辑,那么最好的解决方案是创建自己的 update 方法,然后从 GameScene 手动调用它。
让我们看看(可能的)结构化方法
协议
protocol Updatable: class {
func update(currentTime: NSTimeInterval)
}
使您的精灵/节点可更新
class Player: SKSpriteNode, Updatable {
func update(currentTime: NSTimeInterval) {
// your logic goes here
}
}
将更新从场景转发到节点
class GameScene: SKScene {
private var updatables = [Updatable]()
override func didMoveToView(view: SKView) {
let player = Player()
updatables.append(player)
self.addChild(player)
}
override func update(currentTime: NSTimeInterval) {
updatables.forEach { $0.update(currentTime) }
}
}
如您所见,我正在使用Updatables 的数组。在将新的Updatables 添加(或删除)到场景图中时,您还应该注意将它们添加(或删除)到数组中。
虽然肯定有可能每帧搜索整个场景图,但从性能的角度来看,这将是非常糟糕的。
这是正确的方法吗?
我个人不喜欢在SKNode 或SKSpriteNode 的子类中编写这种代码。
我通常创建一个Logic 类。此类是从 GameScene 接收 update 事件的类。它还接收其他“逻辑事件”,例如:
gameStarted
touchesBegan
touchesEnded
该类包含游戏的纯游戏逻辑。
它类似于您可以在棋盘游戏中找到的说明手册,它与游戏实体的图形表示完全无关。
在理想情况下,我可以从我的 SpriteKit 游戏中提取 Logic 类,并将其与另一个框架或什至与同一游戏的(非电子)棋盘游戏版本一起使用。