0

The timeLabel should count down from 60 to 0 but I have yet to implement a duration. For instance timeLabel.text = String(i) //implement every 1 second So that it will resemble a real count down timer. How would I do that. The other issue is that the game won't start in the simulator when running this code. I get an error and I am redirected to the AppDelegate.swift file: class AppDelegate: UIResponder, UIApplicationDelegate { //error: Thread 1: signal SIGABRT

class GameScene: SKScene {

var timeLabel = SKLabelNode()

override func didMoveToView(view: SKView) {   

    for var i = 60; i > 0; i-- {

        timeLabel.text = String(i)
        timeLabel.position = CGPointMake(frame.midX, frame.midY)
        timeLabel.fontColor = UIColor.blackColor()
        timeLabel.fontSize = 70
        timeLabel.fontName = "Helvetica"
        self.addChild(timeLabel)

    }

  }

}
Miles Militis
  • 147
  • 1
  • 7

1 Answers1

1

You can do this in a few ways, and here is an example on how to update label text (counter) using SKAction:

  import SpriteKit

  class GameScene: SKScene {

    let timeLabel = SKLabelNode(fontNamed: "Geneva")
    var counter = 60

    override func didMoveToView(view: SKView) {

        timeLabel.text = "60"
        timeLabel.position = CGPointMake(frame.midX, frame.midY)
        timeLabel.fontColor = UIColor.blackColor()
        timeLabel.fontSize = 40

        self.addChild(timeLabel)
    }


    func countdown(){

        let updateCounter = SKAction.runBlock({

            self.timeLabel.text = "\(self.counter--)"

            if(self.counter == 0){
                self.counter = 60
            }

        })



        timeLabel.text = "60"
        timeLabel.position = CGPointMake(frame.midX, frame.midY)
        timeLabel.fontColor = UIColor.blackColor()
        timeLabel.fontSize = 40


        let countdown = SKAction.repeatActionForever(SKAction.sequence([SKAction.waitForDuration(1),updateCounter]))


        //You can run an action with key. Later, if you want to stop the timer, are affect in any way on this action, you can access it by this key
        timeLabel.runAction(countdown, withKey:"countdown")

    }

    func stop(){

        if(timeLabel.actionForKey("countdown") != nil){


            timeLabel.removeActionForKey("countdown")

        }

    }


    override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {


        if(timeLabel.actionForKey("countdown") == nil){
            self.countdown()
        }

    }

  }

What I am doing here is updating a label's text property each second. To achieve that, I've created a block of code which updates a counter variable. That block of code is called each second using the action sequence.

Note that your current code trying to add label in each loop. Node can have only one parent, and like the app will crash with following error message :

Attemped to add a SKNode which already has a parent

Also you are not running updating label's text property once in a second. You are executing the whole for loop at once (which is done in much less time then a second).

Whirlwind
  • 14,286
  • 11
  • 68
  • 157
  • What code would I have to move and/or add so that the countdown starts when the user taps the screen. So when the game runs the countdown does nothing until the user taps the screen. I have been trying to use `override func touchesBegan(touches: Set, withEvent event: UIEvent) {` but I can't seem to get it to work properly. – Miles Militis Jul 26 '15 at 15:41
  • @MilesMilitis You can do that by starting an action inside touches began method. You can check the edit. – Whirlwind Jul 26 '15 at 16:01
  • `if(timeLabel.actionForKey("countdown") == nil){` `self.countdown() }` I get the error: GameScene does not have a member named countdown – Miles Militis Jul 26 '15 at 16:12
  • @MilesMilitis Actually it works on my side... It's probably related to Swift version (your version of Swift is probably newer than mine :) Anyways, you can use the same logic, just modify the Swift code to follow the standards of your Swift version. The important thing is to start an action inside touchesBegan instead of inside didMoveToView method. – Whirlwind Jul 26 '15 at 16:18
  • My fault there was some code badly set up. We are probably using the same swift version now it works. – Miles Militis Jul 26 '15 at 16:24
  • One question in the stop function `if(timeLabel.actionForKey("countdown") != nil){` what does != nil mean here. From what I understand if timeLabel is not not nothing then execute next code. But what exactly is it checking for not not nothing. I'm new to programming. – Miles Militis Jul 26 '15 at 16:48
  • You are right, code is executed if result is not nil.That code checks if there is an action for certain key. Result returned by actionForKey method can be nil or SKAction. Read this about != nil part (testing optionals for nil). http://stackoverflow.com/q/25097727/3402095 – Whirlwind Jul 26 '15 at 16:56