2

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?

Astrum
  • 375
  • 6
  • 21

1 Answers1

2

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..

Alessandro Ornano
  • 34,887
  • 11
  • 106
  • 133
  • Will this achieve what I want in terms of adding to the amount variable and updating the text? – Astrum Dec 07 '16 at 13:38
  • In the exact moment you get achievements, you can also launch achievements.UpdateText() and access to amount var – Alessandro Ornano Dec 07 '16 at 13:42
  • So I just access it after the let statement and after the casting as the class? – Astrum Dec 07 '16 at 13:45
  • Thanks for your help Alessandro i have another question about saving the achievements here if you wouldn't mind having a look at it for me here, if not thanks for your help once again. http://stackoverflow.com/questions/41038237/accessing-element-in-array-saving-it-and-overwriting-it – Astrum Dec 08 '16 at 11:25