Search code examples
iosswiftsprite-kitprogress

SKSpriteNode width increases with variable but won't decrease?


I have set up an SKSpriteNode as a progress/health bar. The width is set to a variable. This variable decreases with a timer however the width of the node doesn't decrease with it? If I set the variable to increase then the node width increases no problem however doesn't work if I set the variable to decrease. I fear I'm making a simple error here. Here is the code that works, but doesn't work if I change += to -=

class GameScene: SKScene, SKPhysicsContactDelegate {

var health = SKSpriteNode()
var healthTimer = Timer()
var progressValue = 350


func startHealthTimer() {

    progressValue += 20

}


override func didMove(to view: SKView) {

    healthTimer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(self.startHealthTimer), userInfo: nil, repeats: true)

}


override func update(_ currentTime: TimeInterval) {

    let healthTexture = SKTexture(imageNamed: "health.png")
    health = SKSpriteNode(color: .white, size: CGSize(width: progressValue, height: 30))
    health.position = CGPoint(x: -self.frame.width / 2 + healthTexture.size().width / 2, y: self.frame.height / 2)
    health.zPosition = 2
    self.addChild(health)

}

Solution

  • Each update you are adding a new sprite without removing the old one. After time, you have a number of sprites on top of each other. The new sprites will be shorter, but the old ones are still showing, so the bar does not appear to get shorter.

    class GameScene: SKScene, SKPhysicsContactDelegate {
    
        var health: SKSpriteNode?
        var healthTimer = Timer()
        var progressValue = 350
    
        func startHealthTimer() {
            progressValue += 20
        }
    
        override func didMove(to view: SKView) {
            healthTimer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(self.startHealthTimer), userInfo: nil, repeats: true)
        }
    
        override func update(_ currentTime: TimeInterval) {
            if let health = self.health {
                health.removeFromParent()
            }
    
            let healthTexture = SKTexture(imageNamed: "health.png")
            self.health = SKSpriteNode(color: .white, size: CGSize(width: progressValue, height: 30))
            self.health.position = CGPoint(x: -self.frame.width / 2 + healthTexture.size().width / 2, y: self.frame.height / 2)
            self.health.zPosition = 2
            self.addChild(self.health)
        }
    }