Astrum
Astrum

Reputation: 375

Updating SKLabel text through an SKNode subclass

My Goal: add one to the amount variable of the Achievements Class and then update the text so it shows on the SKLabelNode called "AmountLabel"

So I have a subclass of SKNode that shelters my SKSpriteNode that shows the emblem of the achievement and the SKLabelNodes of the title of the achievement and the amount needed to unlock the achievement As seen below:

class Achievements: SKNode {

var achievementLabel = SKLabelNode()
var achievementTitleLabel = SKLabelNode()
var achievementNode = SKSpriteNode()

var amount = 0
var neededAmount = 0

var Image: String = "locked" {
    didSet {
       var texture = SKTexture(imageNamed: Image)
    }
}

func createAchievement() {

    let tex:SKTexture = SKTexture(imageNamed: Image)

    achievementNode = SKSpriteNode(texture: tex, color: SKColor.black, size: CGSize(width: 75, height: 75))  //frame.maxX / 20, height: frame.maxY / 20))
    achievementNode.zPosition = -10
    achievementNode.name = "AchievementNode"

    amount = 0
    neededAmount = 10

    self.addChild(achievementNode)
    self.zPosition = -11
    Achievements3.append(achievementNode)

    createAchievementLabels()
}

func createAchievementLabels() {

    achievementTitleLabel = SKLabelNode(fontNamed: "Avenir-Black")
    achievementTitleLabel.fontColor = UIColor.black;
    achievementTitleLabel.fontSize = 13 //self.frame.maxY/30
    achievementTitleLabel.position = CGPoint (x: 0, y: 45)
    achievementTitleLabel.text = "COLLECTOR"
    achievementTitleLabel.zPosition = -9
    addChild(achievementTitleLabel)

    achievementTitleLabel.name = "AchievementTitleLabel"

    achievementLabel = SKLabelNode(fontNamed: "Avenir-Black")
    achievementLabel.fontColor = UIColor.black;
    achievementLabel.fontSize = 13 //self.frame.maxY/30
    achievementLabel.position = CGPoint (x: 0, y: -50)
    achievementLabel.text = ("\(amount) / \(neededAmount)")
    achievementLabel.zPosition = -9
    addChild(achievementLabel)

    achievementLabel.name = "AmountLabel"
    AchievementLabels.append(achievementLabel)

}

func UpdateText() {

    achievementLabel.text = ("\(amount) / \(neededAmount)")

   }

}

they're are then added in another class called AchievementMenu like so:

for 0...12 {

     let Achievement = Achievements()
     Achievement.createAchievement()
     Achievement.position = CGPoint(x: self.frame.midX, y: self.frame.midY)
     Achievement.zPosition = 100
     moveableArea.addChild(Achievement)
}

Then in another function in the AchievementMenu class I'm trying to enumerate through the the node tree to be able to update the label to add one to its amount variable and then updates its text like so:

 func addOneToAchievementAndUpdateText() {

    moveableArea.enumerateChildNodes(withName: "SKNode") {
        node, stop in

        let LabelAmount:Achievements = node as! Achievements

        node.enumerateChildNodes(withName: "AmountLabel") {
            node, stop in

            LabelAmount.amount += 1
            LabelAmount.UpdateText()

        }
    }
}

but every time i try and cast a variable as an actual class it gives me an error:

Could not cast value of type 'SKLabelNode' (0x10e5edb08) to 'Astrum.Achievements' (0x10c899438).

How do I add one to the amount variable and then update the text so it shows the new amount on the screen?

Upvotes: 2

Views: 322

Answers (1)

Alessandro Ornano
Alessandro Ornano

Reputation: 35382

To avoid the casting error you can check the node type as:

func addOneToAchievementAndUpdateText() {

    moveableArea.enumerateChildNodes(withName: "SKNode") {
        node, stop in
        print("- node type is: \(type(of: node))")
        if node is Achievements {
            let achievements = node as! Achievements
            achievements.amount += 1
            achievements.UpdateText()
        }
    }
}

Your mistake would not have appeared if you put after the line:

Achievement.zPosition = 100

this line:

Achievement.name = "SKNode"

P.S. Don't forget to use lowercase for variables to don't confused these one with class types: generally it's considered as a bad attitude..

Upvotes: 2

Related Questions