在场景的 update() 之外更新 SKNodes

Updating SKNodes outside update() of scene

我很惊讶 SKScene class 中的更新方法实际上并不是从 SKNode 继承的。对我来说,所有 SKNode 都能够自我更新似乎是合乎逻辑的(例如,当它不再显示时将自己从场景中移除,等等)。我认为这将有助于使实例分离独立的实体(没有依赖性,没有意外行为)如果仅在场景中保持更新背后还有其他逻辑,请解释。

所以我想知道是否值得使用计时器(以 1/60 的时间间隔重复)来向我的自定义 SKNode 添加自定义更新(甚至可能是将其添加到所有 SKNode 的扩展)。但是,我想这会占用大量内存。所以我想问问有没有关于这个的'best practice'。如果计时器在每一帧都触发而不是强迫它每秒触发 60 次,也许计时器会起作用。

绝对不要使用计时器。

SpriteKit 有一个明确定义的更新周期,每一种更新(逻辑、物理、图形)都应该在一个明确定义的时间范围内发生。

如果您真的想在节点中编写更新逻辑,那么最好的解决方案是创建您自己的 update 方法,然后从 GameScene.

手动调用它

让我们看看(可能的)结构化方法

协议

protocol Updatable: class {
    func update(currentTime: NSTimeInterval)
}

使您的 sprite/node 可更新

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 { [=12=].update(currentTime) }
    }
}

As you can see I am using an Array of Updatables. You should also take care of adding (or removing) new Updatables to the Array when they are added (or removed) to the scene graph.

While it's definitely possible searching the whole scene graph every frame it would be very bad by a performance point of view.

这是正确的方法吗?

就我个人而言,我不喜欢在 SKNodeSKSpriteNode.

的子 class 中编写此类代码

我通常创建一个Logicclass。这个 class 是从 GameScene 接收 update 事件的。它还接收其他 "logic events",例如:

  1. gameStarted
  2. touchesBegan
  3. touchesEnded

这个class包含游戏的纯游戏逻辑

它类似于您可以在棋盘游戏中找到的使用手册,它完全不知道游戏实体的图形表示。

在理想情况下,我可以从我的 SpriteKit 游戏中提取 Logic class 并将其与另一个框架一起使用,甚至与相同的(非电子)棋盘游戏版本一起使用游戏。