Невозможно изменить текстуру SKSpriteNode

В моей игре я создаю объект Circle с определенной текстурой, но, например, если Circle сталкивается с определенной стеной, я хочу, чтобы его текстура изменилась. К сожалению, это не работает по какой-то причине, и я понятия не имею, почему. Это мой код для класса Circle:

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

Просто для целей тестирования я добавил этот фрагмент кода сразу после добавления узла в качестве дочернего узла.

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

При загрузке текстуры ошибки не возникает. Изображение определенно существует, и я могу создать из него SKTexture.

У вас есть идеи, почему текстура не меняется?

Вот как создается объект Circle:

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

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

    self.addChild(entity)
}

Этот код выполняется в методе didMoveTo со сцены.

Во время столкновения это мой код:

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

TXT создается здесь:

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

с является строкой со значением "голубой"

2 ответа

Решение

Проблема с этим битом...

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

    return node
}

каждый раз, когда вы обращаетесь к узлу, вы переназначаете текстуру "txtName"

это должно быть...

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

    return node
}()

Причина, по которой это не работает, на мой взгляд, заключается в вычисленном значении переменной "node".

Что вы делаете, это создаете новый узел всякий раз, когда вы ссылаетесь на переменную "node". Когда вы делаете addChild(node)вы делаете 2 вещи: создаете новый узел, затем добавляете его как дочерний элемент сцены.

Итак, если вы делаетеnode.texture = SKTexture(imageNamed: "cyan")Вы создаете новый узел и устанавливаете его текстуру, но это НЕ тот же самый узел, который вы добавили в сцену.

чтобы избежать этого, сохраните созданный узел в переменной и используйте переменную для установки новой текстуры.

У меня сработало:) надеюсь это поможет

Другие вопросы по тегам