2

I am working on a small SpriteKit game.

I have a "Tips" section on the Home Screen that I want to pulse in and out, each time displaying different Tips.

I have a method that works, which I wrote myself, but it's messy and I'm sure there's an better way it could be done. I was hoping someone could show me a way that maybe I missed (or went a long way around doing).

This is how I currently do it:

func createTipsLabels(){
    //create SKLabelNodes
    //add properties to Labels

    //tip1Label... etc
    //tip2Label... etc
    //tip3Label... etc

    //now animate (or pulse) in tips label, one at a time...
    let tSeq = SKAction.sequence([
        SKAction.runBlock(self.fadeTip1In),
        SKAction.waitForDuration(5),
        SKAction.runBlock(self.fadeTip1Out),
        SKAction.waitForDuration(2),
        SKAction.runBlock(self.fadeTip2In),
        SKAction.waitForDuration(5),
        SKAction.runBlock(self.fadeTip2Out),
        SKAction.waitForDuration(2),
        SKAction.runBlock(self.fadeTip3In),
        SKAction.waitForDuration(5),
        SKAction.runBlock(self.fadeTip3Out),
        SKAction.waitForDuration(2),
    ])

    runAction(SKAction.repeatActionForever(tSeq))  //...the repeat forever

}

//put in separate methods to allow to be called in runBlocks above
func fadeTip1In() { tip1Label.alpha = 0; tip1Label.runAction(SKAction.fadeInWithDuration(1)) ;  print("1") }
func fadeTip1Out(){ tip1Label.alpha = 1; tip1Label.runAction(SKAction.fadeOutWithDuration(1));  print("2") }
func fadeTip2In() { tip2Label.alpha = 0; tip2Label.runAction(SKAction.fadeInWithDuration(1)) ;  print("3") }
func fadeTip2Out(){ tip2Label.alpha = 1; tip2Label.runAction(SKAction.fadeOutWithDuration(1));  print("4") }
func fadeTip3In() { tip3Label.alpha = 0; tip3Label.runAction(SKAction.fadeInWithDuration(1)) ;  print("5") }
func fadeTip3Out(){ tip3Label.alpha = 1; tip3Label.runAction(SKAction.fadeOutWithDuration(1));  print("6") }

How can I optimise this?

Eric Aya
  • 69,473
  • 35
  • 181
  • 253
Reanimation
  • 3,151
  • 10
  • 50
  • 88

1 Answers1

5

There is no need to create multiple labels nor do multiple actions, just create an array of what you want to do, and iterate through it.

func createTipsLabels()
{
   let tips = ["1","2","3","4","5"];
   var tipCounter = 0
   {
     didSet
     {
       if (tipCounter >= tips.count)
       {
         tipCounter = 0;
       }
     }
   }
   tipLabel.alpha = 0;
   let tSeq = SKAction.sequence([

        SKAction.runBlock({[unowned self] in self.tipLabel.text = tips[tipCounter]; print(tips[tipCounter]); tipCounter+=1;}),
        SKAction.fadeInWithDuration(1),
        SKAction.waitForDuration(5),
        SKAction.fadeOutWithDuration(1),

        SKAction.waitForDuration(2)

    ])


    tipLabel.runAction(SKAction.repeatActionForever(tSeq))  //...the repeat forever

}
Knight0fDragon
  • 16,609
  • 2
  • 23
  • 44
  • This looks great :D I seem to be getting an error with the runBlock though, as it's expecting a "," where the ";"... this is the reason I've always leaned towards calling a function from the runBlock... Any ideas? – Reanimation Apr 20 '16 at 19:14
  • Oh wowww! That is so handy! How did I never know you could use runBlocks this way. It was worth posting this question just to discover that :D It prompted for `self.tipLabel` but all good now. Super, thank you so much! – Reanimation Apr 20 '16 at 19:17
  • damn, forgot I added that in, hold on – Knight0fDragon Apr 20 '16 at 19:18
  • Awesome. Thanks so much. Really is beautiful code :D – Reanimation Apr 20 '16 at 19:24