I was quite surprised that the update method in the SKScene class isn't actually inherited from SKNode. To me, it seems logical for all SKNodes to be able to update themselves (for instance to remove itself from the scene when it's no longer on display, among other things). I think this would help in making the instances separate independent entities (no dependencies, no unexpected behavior) If there is other logic behind keeping the updates in the scenes only, please explain.
So I'm wondering if it's worth using a timer (repeating with a 1/60 time interval) to add a custom update to my custom SKNodes (perhaps even an extension that will add this to all SKNodes). However, I imagine this will be quite memory intensive. So I would like to ask if there is some 'best practice' regarding this. Perhaps the timer would work if it fired at each frame rather forcing it to fire 60 times a second.
SpriteKit has a well defined update cycle and every kind of update (logic, physics, graphics) should happen into a well defined time frame.
If you really want to write the update logic inside your nodes then the best solution is creating your own update
method and then manually invoking it from the GameScene
.
Let's see a (possible) structured approach
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) }
}
}
As you can see I am using an Array of
Updatables
. You should also take care of adding (or removing) newUpdatables
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.
Personally I don't like writing this kind of code inside my subclasses of SKNode
or SKSpriteNode
.
I usually create a Logic
class. This class is the ones that receives the update
events from GameScene. It also receives other "logic events" like:
gameStarted
touchesBegan
touchesEnded
This class contains the pure game logic of the game.
It is something like the Instruction Manual you can find into a board game and it is totally agnostic about the graphics representation of the game entities.
In an ideal scenario I would be able to extract the Logic
class from my SpriteKit game and use it with another framework or even with a (non electronic) board game version of the same game.