简体   繁体   中英

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"

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
}()

The reason this doesn't work, in my opinion, is because of the calculated value of "node" variable.

What you are doing is creating a new node whenever you reference the "node" variable. When you do addChild(node) you are doing 2 things: create a new Node then add it as a child of the scene.

So, if you do node.texture = SKTexture(imageNamed: "cyan") you are creating a new node and setting its texture, but this is NOT the same node you added to the scene.

to avoid this, save the created node in a variable and use the variable to set the new texture.

It worked for me :) hope this helps

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM