Search code examples
swiftsprite-kitskspritenodesktexture

Unable to change the texture of SKSpriteNode


In my game I am creating a Circle object with a certain texture but for example if the Circle hits a certain wall, I want its texture to change. Unfortunately that does not work for some reason and I have no idea why. This is my code for the Circle class:

class Circle: SKNode, GKAgentDelegate{
    let txtName = "farblos"

    var node: SKSpriteNode {
        let node = SKSpriteNode(imageNamed: txtName)
        node.size = CGSize(width: 30, height: 30)
        node.name = "circle"

        return node
    }

    let agent: GKAgent2D

    init(position: CGPoint) {
        agent = GKAgent2D()
        agent.position = vector_float2(x: Float(position.x), y: Float(position.y))
        agent.radius = Float(15)
        agent.maxSpeed = 50.0
        agent.maxAcceleration = 20.0
        super.init()

        self.position = position
        agent.delegate = self
        addChild(node)
    }

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

Just for testing purposes I added this piece of code directly after adding the node as a child node.

node.texture = SKTexture(imageNamed: "cyan")

There is no error when loading the texture. The image definitely exists and I can create a SKTexture from it.

Do you have any idea why the texture doesn't change?

This is how the Circle object is created:

for _ in 1...i {
    let entity = Circle(position: CGPoint.randomPoint(inBounds: b, notCollidingWith: allBoundaries))

    agentSystem.addComponent(entity.agent)
    allCircles.append(entity)

    self.addChild(entity)
}

This code is being executed in the didMoveTo method from the scene.

At collision time, this is my code:

override func didBegin(_ contact: SKPhysicsContact, with circle: Circle) {
    circle.physicsBody?.collisionBitMask = CollisionCategoryBitmask.allExcept(c).rawValue
    circle.node.texture = txt
}

txt is created here:

var txt: SKTexture{
        get{
            return SKTexture(imageNamed: c)
        }
    }

c is a String with the value "cyan"


Solution

  • the problem is with this bit...

    var node: SKSpriteNode {
        let node = SKSpriteNode(imageNamed: txtName)
        node.size = CGSize(width: 30, height: 30)
        node.name = "circle"
    
        return node
    }
    

    every time you access node you are reassigning the texture "txtName"

    it needs to be...

    lazy var node: SKSpriteNode = {
        let node = SKSpriteNode(imageNamed: txtName)
        node.size = CGSize(width: 30, height: 30)
        node.name = "circle"
    
        return node
    }()