Kevin Dallian's Portfolio Website

What are SKSpriteNode, SKTexture, and SKLabelNode, and how to work around them?

Swift|SpriteKit|Apple|MacOS|Game Dev

01 Jun 2023

On Apple Academy, I have developed a SpriteKit game called Rock Typer, a game that tracks a user’s typing speed by counting rocks that are typed. In this article, I want to share my approach to how to create a Rock object with text above its surface by using SKSpriteNode, SKTexture, and SKLabelNode.

When working with SpriteKit Framework in Swift programming, coders will encounter SKTexture, SKSpriteNode, and SKLabelNode. All of them are children of SKNode and serve the same purpose, to render certain objects to the SKScene, but in their unique ways.

In this article, I will explain the definitions and how to use them all together with Rock Typer’s example.


SKSpriteNode

SKSpriteNode is a graphical element that can be added to a SKScene.
You can initialize a sprite node from an image or a solid color, specify its size, anchor point, and position.

Adding an SKSpriteNode to SKScene

The code below is an example of adding SKSpriteNode to SKScene. I have an image of rock named rock1 and a SKScene file named “GameScene”.

import SpriteKit
import GameplayKit
 
class GameScene: SKScene {
 
    override func didMove(to view: SKView) {
        let rock = SKSpriteNode(imageNamed: "rock1")
        rock.size = CGSize(width: 330, height: 300)
        rock.anchorPoint = CGPoint(x: 0.5, y: 0.5)
        rock.position = CGPoint(x: frame.midX, y: frame.midY)
        addChild(rock)
    }
 
    override func update(_ currentTime: TimeInterval) {
        // Called before each frame is rendered
    }
}

SKTexture

SKTexture is an image that can be applied to various SpriteKit objects such as SKSpriteNode, SKShapeNode, SKEmitterNode, and SKTileMapNode. SKTexture decoded the image into texture and graphic resource data for SpriteKit objects to use.

Difference between SKTexture’s role and SKSpriteNode’s

As mentioned, SKSpriteNode can be initialized with an image. So why bother making SKTexture first and then make SKSpriteNode with that SKTexture? Here is the catch, multiple SKSpriteNode can share the same SKTexture. By doing that multiple SKSpriteNode don’t need to initialize multiple images, they can share a single resource texture. Not only that, SKSpriteNode can change SKTextures programmatically, making it easier to animate SKSpriteNode’s movement.

Implementing SKTexture to multiple SKSpriteNode

The code below is an example to initialize a SKTexture of image rock1 for creating 4 SKSpriteNode objects.

import SpriteKit
import GameplayKit
 
class GameScene: SKScene {
    
    override func didMove(to view: SKView) {
        let rockTexture = SKTexture(imageNamed: "rock1")
        for idx in 0..<4{
            let rock = SKSpriteNode(texture: rockTexture)
            rock.size = CGSize(width: 330, height: 300)
            rock.anchorPoint = CGPoint(x: 0.5, y: 0.5)
            rock.position = CGPoint(x: frame.midX, y: frame.midY - rock.size.width * CGFloat(idx))
            addChild(rock)
        }
    }
    
    override func update(_ currentTime: TimeInterval) {
        // Called before each frame is rendered
    }
}

SpriteKit diagram Image 1.1: 4 SKSpriteNodes with 1 SKTexture

SKLabelNode

SKLabelNode is used for drawing a text into SKScene. Text created by SKLabelNode can be modified with its properties such as fontName and fontColor or using NSAttributedString with a property named attributedText.

Adding SKLabelNode to SKScene: Property Approach

The code below is an example of adding SKLabelNode to SKScene with its property modified. This code displays “Hello World” with white color in the middle of the screen.

import SpriteKit
import GameplayKit
 
class GameScene: SKScene {
    
    override func didMove(to view: SKView) {
        let label = SKLabelNode(text: "Hello World")
        label.fontName = "SF Pro"
        label.fontSize = 48
        label.fontColor = .white
        label.position = CGPoint(x: frame.midX, y: frame.midY)
        addChild(label)
    }
    
    override func update(_ currentTime: TimeInterval) {
        // Called before each frame is rendered
    }
}

Creating SKLabelNode with property approach Image 1.2: Creating SKLabelNode with property approach

Using SKSpriteNode, SKTexture, and SKLabelNode altogether in a Project

For example, I want to make a class that renders an image of rock with text above the surface of it on a SKScene. The code below is an example to implement SKSpriteNode, SKTexture, and SKLabelNode altogether.

import Foundation
import SpriteKit
 
class RockNode : SKSpriteNode {
    let textNode : SKLabelNode
    let rockString = "rock1"
    
    init(text: String){
        let rockTexture = SKTexture(imageNamed: rockString)
        let rockNode = SKSpriteNode(texture: rockTexture)
        
        rockNode.size = CGSize(width: 300, height: 240)
        
        textNode = SKLabelNode(fontNamed: "Skia")
        textNode.text = text
        textNode.fontSize = 48
        textNode.fontColor = .black
        textNode.zPosition = 1
        
        super.init(texture: nil, color: .clear, size: rockNode.size)
        addChild(rockNode)
        addChild(textNode)
    }
    
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

With the RockNode Class created, I can make a RockNode object by giving a text. The code below is the example to display 2 RockNode objects.

import SpriteKit
import GameplayKit
 
class GameScene: SKScene {
    
    override func didMove(to view: SKView) {
        let helloRock = RockNode(text: "Hello")
        let worldRock = RockNode(text: "World")
        helloRock.position = CGPoint(x: frame.midX, y: frame.midY + 150)
        worldRock.position = CGPoint(x: frame.midX, y: frame.midY + 150 - worldRock.size.height)
        addChild(helloRock)
        addChild(worldRock)
    }
    
    override func update(_ currentTime: TimeInterval) {
        // Called before each frame is rendered
    }
}

2 Rock Nodes with text Image 1.3: 2 Rock Nodes with text

Always refer more information on the Apple Developer Documentation, SKSpriteNode, SKTexture, and SKLabelNode.


Other than SKSpriteNode, SKTexture, and SKLabelNode. there are still more actions that you can do to SpriteKit like creating actions using SKAction, creating particles using SKEmitterNode, setup physics in SKScene, and many more. Please refer to Apple Developer Documentation for more information.