swiftsprite-kitskspritenodesktexture

Changing texture for subclass of SKSpriteNode?


The update function in the class below, which is a subclass of SKSpriteNode, is supposed to change the texture of the class. According to this SO answer, updating the texture property is sufficient for changing a SKSpriteNode's texture. However, this code doesn't work.

Any ideas why?

class CharacterNode: SKSpriteNode {       
    let spriteSize = CGSize(width: 70, height: 100)

    var level = 0

    init(level: Int) {
        self.level = level
        super.init(texture: nil, color: UIColor.clear, size: spriteSize)
    }


    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }


    func update(level: Int) {
        self.level = level            
        self.texture = textureForLevel(level: level)
    }


    func textureForLevel(level: Int) -> SKTexture {
        return SKTexture(imageNamed: "TestTexture")
    }

Solution

  • Your code works well. In fact this SO answer is correct.

    About SKSpriteNode subclass, the update method is a new custom function added by you, because the instance method update(_:) is valid only for SKScene class, this just to say that this function is not performed if it is not called explicitly.

    To make a test about your class you can change your code as below( I've changed only textureForLevel method only to make this example):

    class CharacterNode: SKSpriteNode {
        let spriteSize = CGSize(width: 70, height: 100)
        var level = 0
        init(level: Int) {
            self.level = level
            super.init(texture: nil, color: UIColor.clear, size: spriteSize)
        }
        required init?(coder aDecoder: NSCoder) {
            fatalError("init(coder:) has not been implemented")
        }
        func update(level: Int) {
            self.level = level
            self.texture = textureForLevel(level: level)
        }
        func textureForLevel(level: Int) -> SKTexture {
            if level == 3 {
                return SKTexture(imageNamed: "TestTexture3.jpg")
            }
            return SKTexture(imageNamed: "TestTexture.jpg")
        }
    }
    
    class GameScene: SKScene {
        override func didMove(to view: SKView) {
            let characterNode = CharacterNode(level:2)
            characterNode.update(level:2)
            addChild(characterNode)
            characterNode.position = CGPoint(x:self.frame.midX,y:self.frame.midY)
            characterNode.run(SKAction.wait(forDuration: 2.0), completion: {
                characterNode.update(level:3)
            })
        }
    }
    

    As you can see when you launch GameScene a characterNode sprite will be shown in the center of the screen. After 2 seconds, the texture will change.