The root node for all Sprite Kit objects displayed in a view.
- iOS 7.0+
- macOS 10.9+
- tvOS 9.0+
- watchOS 3.0+
SKScene object represents a scene of content in SpriteKit. A scene is the root node in a tree of SpriteKit nodes (
SKNode). These nodes provide content that the scene animates and renders for display. To display a scene, you present it from an
Creating a Scene
A scene is presented by a view. The scene includes properties that define where the scene’s origin is positioned and the size of the scene. If the scene does not match the view’s size, you can also define how the scene is scaled to fit in the view.
A Scene’s Size Defines Its Visible Area
When a scene is first initialized, its
size property is configured by the designated initializer. The size of the scene specifies the size of the visible portion of the scene in points. This is only used to specify the visible portion of the scene. Nodes in the tree can be positioned outside of this area; those nodes are still processed by the scene, but are ignored by the renderer.
Using the Anchor Point to Position the Scene’s Coordinate System in the View
By default, a scene’s origin is placed in the lower-left corner of the view, as shown in the figure below. So, a scene initialized with a height of
1024 and a width of
768, has the origin
(0,0) in the lower-left corner, and the
(1024,768) coordinate in the upper-right corner. The
frame property holds
position property is ignored by Scene Kit because the scene is always the root node for a node tree. Its default value is
zero and you can’t change it. However, you can move the scene’s origin by setting its
anchor property. The anchor point is specified in the unit coordinate space and chooses a point in the enclosing view.
The default value for the anchor point is
zero, which places it at the lower-left corner. The scene’s visible coordinate space is
(width,height). The default anchor point is most useful for games that do not scroll a scene’s content.
The second-most common anchor point value is
(0, which centers the scene’s origin in the middle of the view as shown in the figure below. The scene’s visible coordinate space is
(width/2, height/2). Centering the scene on its anchor point is most useful when you want to easily position nodes relative to the center of the screen, such as in a scrolling game. However, this effect is better achieved using a
So, to summarize, the anchorPoint and size properties are used to compute the scene’s frame, which holds the visible portion of the scene.
A Scene’s Contents Are Scaled to Fit the View
After a scene is rendered, its contents are copied into the presenting view. If the view and the scene are the same size, then the content can be directly copied into the view. If the two differ, then the scene is scaled to fit in the view. The
scale property determines how the content is scaled.
When you design your game, you should decide on a strategy for handling the scene’s
scale properties. Here are the most common strategies:
Instantiate the scene with a constant size and never change it. Pick a scaling mode that lets the view scale the scene’s content. This gives the scene a predictable coordinate system and frame. You can then base your art assets and gameplay logic on this coordinate system.
Adjust the size of the scene in your game. Where necessary, adjust your game logic and art assets to match the scene’s size.
resize. SpriteKit automatically resizes the scene so that it always matches the view’s size. Where necessary, adjust your game logic and art assets to match the scene’s size.
Listing 1 shows a typical implementation for when you plan to use a constant-sized scene. This code specifies a method to be executed the first time that the scene is presented. It configures the scene’s properties, including its scaling mode, then adds content. In this example, the scale mode is set to
aspect, which scales the contents equally in both dimensions and ensures that all of the scene’s contents are visible. Where necessary, this mode adds letter-boxing.
If you expect a scene’s size to change at runtime, then the initial scene size should be used to determine which art assets to use, as well as any game logic that is dependent on the scene size. Your game should also override the scene’s
did method, which is called whenever the scene changes size. When this method is called, you should update the scene’s contents to match the new size.
How a Scene Processes Frames of Animation
The process of animating and rendering the scene is tied to the scene object,
SKScene. Scene and action processing runs only when the scene is presented. A presented scene runs a rendering loop that alternates between processing the scene’s node tree and rendering it. This model is similar to the rendering and processing loop used in most games.
SpriteKit will only render the scene when something within it has changed, improving energy efficiency and allowing your game or app to perform other operations in the background.
Figure 3 shows the steps used by a scene to execute the rendering loop.
Each time through the rendering loop, the scene’s contents are updated and then rendered. You can’t override the rendering behavior; instead you update the nodes in the scene. However, the scene includes methods you can override to customize scene processing, and you can use actions and physics to alter properties of nodes in the tree. Here are the steps in the rendering loop:
update(_:)method is called with the time elapsed so far in the simulation. This is the primary place to implement your own in-game simulation, including input handling, artificial intelligence, game scripting, and other similar game logic. Often, you use this method to make changes to nodes or to run actions on nodes.
The scene processes actions on all the nodes in the tree. It finds any running actions and applies those changes to the tree. In practice, because of custom actions, you can also hook into the action mechanism to call your own code. You cannot directly control the order in which actions are processed or cause the scene to skip actions on certain nodes, except by removing the actions from those nodes or removing the nodes from the tree.
didmethod is called after all actions for the frame have been processed.
The scene simulates physics on nodes in the tree that have physics bodies. Adding physics to nodes in a scene is described in
SKPhysics, but the end result of simulating physics is that the position and rotation of nodes in the tree may be adjusted by the physics simulation. Your game can also receive callbacks when physics bodies come into contact with each other, see
didmethod is called after all physics for the frame has been simulated.
The scene applies any constraints associated with nodes in the scene. Constraints are used to establish relationships in the scene. For example, you can apply a constraint that makes sure a node is always pointed at another node, regardless of how it is moved. By using constraints, you avoid needing to write a lot of custom code in your scene handling.
The scene calls its
The scene calls its
didmethod. This is your last chance to make changes to the scene.
The scene is rendered.
Working With Scene Delegates
Although subclassing the scene class is a common way to handle scene processing, you can avoid it by using a delegate object instead. All of the scene processing methods described above have related methods in the
SKScene protocol. If a delegate is provided to the scene and the delegate implements one of these methods, that method is called instead of the one on the scene. For example, an iOS app might use view controller as the delegate.
Post-Processing in Scenes
A scene can process the actions on the scene tree in any order. For this reason, if you have tasks that you need to run each frame and you need precise control over when they run, you should use the
did methods to perform those tasks. Typically, you make changes during post-processing that require the final calculated positions of certain nodes in the tree. Your post-processing can take these positions and perform other useful work on the tree.
Often, your game subclasses a scene to deliver gameplay. Your subclass usually:
Creates the scene’s initial content
Implements game logic that occurs each time a frame is processed
Implements responder methods to handle keyboard, mouse, or touch events
An alternative pattern to subclassing the
SKScene class is to use a delegate that implements most of the game logic. For example, in an iOS game, you can make your view controller the delegate for your scene. The view controller already participates in event handling and can perform all of the other necessary duties described above.