1

Whats the best way to have a label with kills, health or a score that updates as the variables connected with it change? Currently I'm just using a SKLabelNode and assigning text to it with a variable, but the text property is not computed, so it remains static after initialization. I could every time I change the monsteredDestroyed variable, update the text, but I have a feeling there is a better way to do this.

let label = SKLabelNode(fontNamed: "CoolFont")
label.text = "Kills: \(monstersDestroyed)"
Unome
  • 6,750
  • 7
  • 45
  • 87

4 Answers4

4

There is not better way to do this. You cannot make a SKLabelNode 'listen' for changes on a variable (actually there is a system called Key-Value Observing, but in this case it would be overkill). I would suggest setting up a method which would manage the score as well as update it on the screen. It would be a simple matter of calling that function to update as well as keep track of the score, or any other variable which is to be displayed on the screen.

let lblScore = SKLabelNode() //Label with global scope.
var score:Int = 0 //The variable holding the score.

func updateScoreWithValue (value: Int) {
    score += value
    lblScore.setText("\(score)")
}

You can simply call this method with the value to increment/decrement the score.

self.updateScoreWithValue(10) //Adds 10 and updates it on screen.
self.updateScoreWithValue(-10) //Subtracts 10.
0x141E
  • 12,613
  • 2
  • 41
  • 54
ZeMoon
  • 20,054
  • 5
  • 57
  • 98
  • Code and tag are Swift not Obj-C – 0x141E Nov 15 '14 at 08:08
  • So to do this, my label needs to have global scope, looking back this is one of the reasons why I avoided this implementation. – Unome Nov 16 '14 at 07:29
  • You could also add a property observer onto score to set the lblScore. var score:Int = 0 { didSet { lblScore.setText("\(score)") } }. The advantage of this is if you ever explicitly set score, then the label will be updated. However, on init, the property observer will not be called. – Mobile Ben Nov 17 '14 at 01:29
1

I could every time I change the monsteredDestroyed variable, update the text, but I have a feeling there is a better way to do this.

There's no better way than that, you're on the right track.

EmilioPelaez
  • 18,758
  • 6
  • 46
  • 50
1

As ZeMoon mentioned, you can always use something like KVO to update the value. Myself, I prefer a bit more explicit control on when the changes are made and hence will set the values myself versus KVO. What I typically do is let all the values aggregate and then have a HUD manager figure out if values are dirty and then update values accordingly. In other words, the HUD manager is more or less a "view controller", bridging items like score, health, etc to the view, which is your node tree.

Also note that I'd typically wrap my SKLabelNode into another object which hides the implementation. This allows me to still have a text property, but if I want to, I can change how I'm actually doing the text.

Mobile Ben
  • 7,121
  • 1
  • 27
  • 43
  • 1
    Key-Value Observing. Although depending on how you structure your code, you could use property observers. Here's a link which hopefully helps out. http://stackoverflow.com/questions/24092285/is-key-value-observation-kvo-available-in-swift – Mobile Ben Nov 17 '14 at 01:22
1

A better way to do this is maybe using property observers.

var shots: Int = 0 {
didSet {
shotsLabel.text = "\(shots)"
}

This way, whenever you set the shots value, the label text will change automatically.

EDIT: I forgot to mention that you should check first if the shotsLabel is not nil, because you can set the shots variable before the view loads.

Marin Bencevic
  • 301
  • 3
  • 6