
The SKNode class
When developing a scene, we sometimes build what is called a scene hierarchy. This scene graph is a hierarchy of the nodes that are available on it.
We call them nodes because they inherit from the SKNode
class. For more information, visit https://developer.apple.com/library/ios/documentation/SpriteKit/Reference/SKNode_Ref, which is the main SpriteKit
class that renders visual elements.
The following diagram corresponds to the scene graph of the project. You can see that there is a parent SKScene
node with two children that correspond to the SKSpriteNode
and SKLabelNode
that we have added to the game:

The SKNode
class is a subclass of UIResponder
. This means that all the SKNode
instances and every subclass of SKNode
will be able to handle touches and other kind of events such as motion
events.
If you look at the SKNode
class hierarchy in the following diagram, you will realize the importance of this class, as it is the parent of several useful classes:

The SKNode class properties
In this section, we are going to have a look at the most important properties available in the SKNode
class in detail.
The position property
An important property of nodes is their position
, as we are going to manipulate this several times during the game's development. This property corresponds to the position of the node in the parent's coordinate system. Therefore, we need to take it into account when adding new elements to a scene
. Its default value is (0.0, 0.0)
.
The frame property
Another useful property is the frame
of a node, which makes a reference to the rectangle defined by its texture (the visual content). This property size
can be modified by applying a scaling factor on both the width and height by applying a value between 0
and 1
to the xScale
and yScale
attributes. The frame can also be rotated by modifying the zRotation
property, which will apply a counterclockwise rotation if the value is greater than 0
.
Note
As a node can be used to organize the content by storing other nodes, the scale
and rotation
modifiers will affect both the node and its descendants.
If we want to take into account a node's descendants when getting its frame, there is a function called calculateAccumulatedFrame()
that retrieves the rectangle containing the content of the parent and children while taking into account the scale
and rotation
factors.
We can, for instance, determine whether this whole frame is intersected by another node's frame thanks to this method.
The zPosition property
This property determines the height of the node related to its parent. Its value is 0.0
by default, but we can set positive or negative values so that, the bigger the zPosition
value, the closer the node will be to the user. This way, we will have full control over how the children are rendered.
The hidden property
Sometimes, we will need to keep a node invisible while it is in a scene. We can do this by setting the hidden
property to true
. It only affects the way the node and its descendants are rendered, as they will still be able to perform actions and collide with other nodes in the scene.
An alpha property
A property that provides a similar effect is the alpha
property of the node. It applies a modifier between 0.0
and 1.0
to the alpha
component of each pixel and allows us to make the node transparent.
The children node
This read-only array of the AnyObject
type contains all the node children
in an SKNode
object.
name
If a scene contains several nodes, we may need to identify them in order to handle collisions. In such cases, it is a good approach to provide a value to each node's name
property. We can use this property to give the same name to a group of nodes in order to differentiate them from the player's node and make collision detection tasks easy.
If we want to find a node by its unique name, we can make use of the childNodeWithName
method. On the other hand, if we have used a name to identify a collection of nodes, we can call enumerateChildNodesWithName:usingBlock
, which will search a node's children and execute a block of code once for each child that is found.
userInteractionEnabled
There is another property that is commonly used, userInteractionEnabled
. This determines whether a node can receive touch events. If its value is false
, the node won't react to user input.
Using SKNode to organize a scene
We have seen previously that an SKNode
instance can be used to contain other nodes in order to organize the scene content. The following are a few examples:
- You may want to group several nodes that need to be treated as a unique object to represent an army of alien ships, and you don't want any of the ships to be the root. Grouping them as
children
of a node will allow you to move them, while always keeping the line-up. - In a game, it is common to have a background, several characters, objects to collide, texts, and many more elements. You can create different layers to separate each of these different kind of elements by creating basic nodes and inserting them in the desired order into the scene.
In the preceding screenshot, you can see how we used three different layers, one for the background, another one for the ninja character, and the last one for the score.
By following the afore mentioned approaches, you will be able to add or remove entire groups of objects by deleting a single node. This will make the scene management more efficient. You can also configure the properties of several nodes by applying the configuration to the root
node. You can even take advantage of it when running actions or handling physics contacts.