在swift中创建一个秒表

时间:2017-06-24 00:55:21

标签: swift timer sprite-kit

我尝试过搜索其他答案,但找不到适用于我的方案的答案。我正在快速编写游戏,并希望创建一个秒表来确定玩家玩的时间长短。当用户触摸时,秒表将启动,当某个动作发生时,计时器停止并重置。我想使用分钟,秒,毫秒(即00:00.00)。

目前,时间功能有点有效。它不会从0开始,它从当前的时间点开始(我知道当我启动时,但我不知道如何在0开始)。它也只在我触摸屏幕时更新,我需要它从00:00开始计数并自行更新,直到取消操作被触发。

感谢您的时间。

这是我到目前为止所做的:

class GameScene: SKScene {

var activeTimer = SKLabelNode()
//var bestTime = SKLabelNode()

var startTime = TimeInterval()
//var currentTime = TimeInterval()
//var countingTime = TimeInterval()
var updateTimerAction = SKAction()


override func didMove(to view: SKView) {

    activeTimer = self.childNode(withName: "active_timer") as! SKLabelNode
    //bestTime = self.childNode(withName: "best_time") as! SKLabelNode

    startTime = TimeInterval(Calendar.current.component(.second, from:Date()))
    updateTimerAction = SKAction.sequence([SKAction.run(updateTimer), SKAction.wait(forDuration: 1.0)])
}


func startGame() {
    // Other code
    startGameTimer()
}

func resetGame() {
    // Other code
    stopGameTimer()
}

func startGameTimer() {
    run(SKAction.repeatForever(updateTimerAction), withKey: "timer")
}

func updateTimer() {
    activeTimer.text = stringFromTimeInterval(interval: startTime) as String
}

func stringFromTimeInterval(interval: TimeInterval) -> NSString {

    let ti = NSInteger(interval)

    let ms = Int((interval.truncatingRemainder(dividingBy: 1)) * 1000)

    let seconds = ti % 60
    let minutes = (ti / 60) % 60

    return NSString(format: "%0.2d:%0.2d.%0.2d",minutes,seconds,ms)
}


func stopGameTimer() {
    removeAction(forKey: "timer")
}

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {

    startGame()

    for touch in touches {
        // other code
    }
}

override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {

    for touch in touches {
        // other code
    }
}


override func update(_ currentTime: TimeInterval) {

    updateTimer()

    if <action>  {
        // stop timer and reset game
        resetGame()
    }
}

3 个答案:

答案 0 :(得分:2)

最好不要使用TimeInterval对象,最好使用一个Timer对象来调用一个函数,该函数在每1秒后从0开始递增标签(或内部变量)的值(或者可以做得更小) )。要停止时钟,只需调用Timer对象的无效功能即可。 有关详细信息,请查看文档:{​​{3}}

答案 1 :(得分:2)

以下几行代码来自我3周前提交给Mac App Store的实际macOS游戏。它将数字倒数到0.在您的情况下,更改

self.currentSeconds -= 1

self.currentSeconds += 1

timeBackNode是一个空节点,它包含SKLabelNode对象timeNode0和timeNode1。因此,当游戏以didMove开始时创建它。

var currentSeconds = Int() // currentSeconds
var timeNode0 = SKLabelNode() // timeNode0
var timeNode1 = SKLabelNode() // timeNode1
func setupTimeGoal() {
    enumerateChildNodes(withName: "//TimerBack", using: { timeBackNode, _ in
        let goal = self.timeDict["num"] as! Int
        self.currentSeconds = goal // In your case, goal is 0 since you are going to count up.
        self.timeNode0 = SKLabelNode(fontNamed: "Your font's font name")
        self.timeNode0.text = self.makeTimeWithSeconds(secs: goal)
        self.timeNode0.fontSize = 26
        self.timeNode0.fontColor = SKColor.black
        self.timeNode0.horizontalAlignmentMode = .center
        self.timeNode0.position = CGPoint(x: 1, y: -22)
        timeBackNode.addChild(self.timeNode0)

        self.timeNode1 = SKLabelNode(fontNamed: "Your font's font name")
        self.timeNode1.text = self.makeTimeWithSeconds(secs: goal) // this function translate a counting number into a time code like 00:00:00
        self.timeNode1.fontSize = 26
        self.timeNode1.fontColor = SKColor.cyan
        self.timeNode1.horizontalAlignmentMode = .center
        self.timeNode1.position = CGPoint(x: 0, y: -23)
        timeBackNode.addChild(self.timeNode1)
    })
}

func repeatTime() {
    let waitAction = SKAction.wait(forDuration: 1.0)
    let completionAction = SKAction.run {
        if self.currentSeconds == 0 && self.gameState == .playing {
            self.removeAction(forKey: "RepeatTime")
            self.proceedLoss()
            return
        }
        self.currentSeconds -= 1
        self.timeNode0.text = self.makeTimeWithSeconds(secs: self.currentSeconds)
        self.timeNode1.text = self.makeTimeWithSeconds(secs: self.currentSeconds)
    }
    let seqAction = SKAction.sequence([waitAction, completionAction])
    let repeatAction = SKAction.repeatForever(seqAction)
    self.run(repeatAction, withKey: "RepeatTime")
}

答案 2 :(得分:0)

这是我最终做的事情。虽然El Tomato的答案似乎有效,但鉴于我的代码设置,我走了一条不同的路线。在与其他朋友交谈后,由于我的应用程序的设计,我选择使用计时器。如果我碰巧使用Timer对象遇到任何问题,我会更新这个问题。

以下代码将以触摸开始,以以下格式更新:&#34; 00:00.00&#34;当动作被触发时停止。此时间将暂停直到另一次触摸,然后定时器将从零开始。

class GameScene: SKScene {

var seconds = 0
var timer = Timer()
var timeStarted = Bool()
var activeTimer = SKLabelNode()
//var bestTime = SKLabelNode()

override func didMove(to view: SKView) {

    activeTimer = self.childNode(withName: "active_timer") as! SKLabelNode
    //bestTime = self.childNode(withName: "best_time") as! SKLabelNode
    timeStarted = false

}

func startGame() {

    startGameTimer()
    timeStarted = true
}

func resetGame() {

    timeStarted = false
    stopGameTimer()
    seconds = 0
}

func startGameTimer() {
    timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: (#selector(updateTimer)), userInfo: nil, repeats: true)
}

func updateTimer() {
    seconds += 1
    activeTimer.text = timeString(time: TimeInterval(seconds))
}

func timeString(time:TimeInterval) -> String {
    let hours = Int(time) / 3600
    let minutes = Int(time) / 60 % 60
    let seconds = Int(time) % 60
    return String(format:"%02i:%02i.%02i", hours, minutes, seconds)
}


func stopGameTimer() {
    timer.invalidate()
    removeAction(forKey: "timer")
}

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {

    if !timeStarted {
        startGame()
    }

    for touch in touches {
        // other code
    }
}

override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {

    for touch in touches {
        // other code
    }
}


override func update(_ currentTime: TimeInterval) {

    if timeStarted {
        updateTimer()
    }

    if <action>  {
    // stop timer and reset game
    resetGame()
    }
}
}