In continuing with my recent posts about SpriteKit, I thought I’d go through another useful aspect of the framework: SpriteKit actions. A SpriteKit action, represented by the
SKAction class, allows you to animate certain properties on an
SKNode object, such as position and velocity.
Creating an action
Unlike a lot of different SpriteKit objects, you don’t create an
SKAction using an initializer. Instead, you call one of the class methods corresponding to the action you want to perform.
In this example, the
moveBy method creates an action that moves a node 10 pixels to the right and 15 pixels down over the course of 800 milliseconds. Other action methods include
Running an action
To run this action on a node, call the
run(SKAction) method on the node you want the action to apply to.
Based on the previous example, this will update the player’s position over 800 ms by adding the values passed to the
moveBy call. A variant of the
run method takes a completion callback that is called after the action has been completed.
One useful thing about
SKActions is they are “copy-on-write”, which means that whenever the action is changed, the value is copied, therefore the same
SKAction can be used on multiple nodes.
Groups and Sequences
Sometimes, multiple actions need to be run at the same time or in sequence. To accomplish this, the methods
SKAction.sequence([SKAction]) create groups and sequences, respectively, of actions. For example, we need to both move and rotate our player node at the same time.
In the above example, we could change the
group call to
sequence, which would run the
moveAction first, wait until it completes, and then run the
Running an action multiple times is just as easy: call
SKAction.repeat(SKAction, count: Int) passing in the action to be repeated and the number of times it should be run. This is used just like any other action.
Now our player node moves right and down five times. To repeat an action forever, you can call
SKAction.repeatForever(SKAction) with the action which is to be repeated infinitely.
Almost every type of action has a duration parameter that is a
TimeInterval (a typealias for
Double) in seconds. This tells the engine to run the action for a certain number of seconds (or fraction of a second). There is also another type of action,
wait(forDuration: TimeInterval), which will wait for the duration of the action. This is useful in action sequences to have time in between actions.
Blocks and Custom Actions
There is also another class method
run(_: () -> Void) that executes a block of code. The parameter to
run is a function that does not take any arguments and returns
Void. This allows you to do things that are out of the scope of the regular
SKAction, such as update UI or change scores, for example.
A custom action is a little bit trickier. The method
customAction(withDuration: TimeInterval, actionBlock: @escaping (SKNode, CGFloat) -> Void) creates an action that runs over a specified duration, while continually calling the
actionBlock with the node (
SKNode) the action is running on and the elapsed time (
CGFloat) until the duration time.
This code snippet creates an action that changes a label node’s text counting up from
There are two basic ways to stop actions while they are running: calling
removeAction(forKey: String) on a node. The former will stop all actions currently running on the node, while the latter will remove an action based on a unique key given to the action when the
run(SKAction, withKey: String) is called.
In my recent SpriteKit game, Blueshift, I used
SKActions heavily to make tiles move around. Check it out in the App Store! Also, check out my other SpriteKit posts, the basics and physics. If you have any questions, comment here or tweet or PM me on Twitter. Happy SpriteKit-ing!