# Calling a method only once in an updateScore function in SpriteKit

This works fine, but obviously it's messy and I'm thinking there has to be a better way to do this. Having to constantly remember to flip the bool back is a pain, is there anything else I can do here? I take it SpriteKit itself doesn't have any convenience method for calling something only once for example.

func updateScore() {

// MARK: Increase Difficulty
switch score {
case 0:
if !levelToggle {
showLevelGraphic(1)
levelToggle = true
}
case 1:
levelToggle = false
case 5:
if !lighteningToggle {
GameEffects.lightening(self, masterNode: worldNode, backgroundStringName: "background")
GameEffects.lightening(self, masterNode: worldNode, backgroundStringName: "foreground")
GameEffects.shakeScreen(worldNode)
lighteningToggle = true
}

if !rainToggle {
makeItRain()
rainToggle = true
}
break
case 6:
lighteningToggle = false
case 10:
if !rotateToggle {
GameEffects.rotateScreenAndHold(worldNode, finishAngle: 0.06, totalEffectDuration: 5.0)
rotateToggle = true
}
case 15:
rotateToggle = false
case 16:
if !rotateToggle {
GameEffects.rotateScreenAndHold(worldNode, finishAngle: -0.06, totalEffectDuration: 5.0)
rotateToggle = true
}
break
case 17:
rotateToggle = false
case 20:
stopRaining()
rainToggle = false
case 25:
if !rotateToggle {
GameEffects.rotateScreenAndHold(worldNode, finishAngle: -0.06, totalEffectDuration: 10.0)
rotateToggle = true
}
case 26:
rotateToggle = false
case 45:
break
case 50:
if !levelToggle {
showLevelGraphic(2)
levelToggle = true
}
kGroundSpeed = 200
break
case 55:
if !zoomToggle {
GameEffects.zoomIn(worldNode)
}
case 56:
zoomToggle = false
case 70:
if !rotateToggle {
GameEffects.rotateScreenAndHold(worldNode, finishAngle: 0.06, totalEffectDuration: 10.0)
rotateToggle = true
}

• Can we assume that the score can never decrease in this game? – 200_success Sep 21 '16 at 17:30
• Yes that is true – GarySabo Sep 21 '16 at 17:47

First, use properties, they are your best friend

var rotateToggle = false
{
didSet
{
if(rotateToggle)
{
GameEffects.rotateScreenAndHold(worldNode, finishAngle: -0.06, totalEffectDuration: 5.0)
}
else
{
//if you need something on false, do it here
}
}
}


do this for all of your other toggles.

Update for score property:

var score : UInt = 0
{
didSet
{
}
}


Now we have your case statement, chain them together

switch (score)
{
case 0:
levelToggle = true
case 1:
levelToggle = false
case 10,16,25:
rotateToggle = true
//...etc
}


of course, how you have toggle set up, this requires score increases by 1, and updateScore gets fired afterwards before score can increase by 1 again.

• Thanks so much, I still can't get my head around your code though..updateScore is called inside override func updateWithDeltaTime(seconds: NSTimeInterval)  in my app, so it's getting called constantly (not just when the score increases), so is your approach flipping the bool back to false after the effect is run, so that it won't run repeatedly as per my original code? – GarySabo Sep 22 '16 at 14:51
• if you do the updateScore logic inside a property, then the only time the function gets fired is when score changes, which is what you should be doing. Avoid doing things in the update loop unless you need it to update every frame, you only have 16ms to play with – Knight0fDragon Sep 22 '16 at 14:53
• "the only time the function gets fired is when score changes" but does it only fire once? – GarySabo Sep 22 '16 at 15:27
• it fires one time when score changes firing every update seems silly – Knight0fDragon Sep 22 '16 at 15:28
• right but that's what it was doing prior to my adding the bool/flag (because updateScore is being called inside updateWIthDeltaTime) – GarySabo Sep 22 '16 at 15:30