问题 如何实现SpriteKit计时器?


我目前正在尝试为我的精灵套件游戏实现一个计时器,但我没有让它工作。计时器的初始值始终保持不变。

我假设我需要以某种方式/某处更新标签,但我不知道如何和在哪里:?我不明白这一点。有任何想法吗?

这是我的GameScene类中的代码

    let levelTimerLabel = SKLabelNode(fontNamed: "Chalkduster")
var levelTimerValue: Int  = 500

var levelTimer = NSTimer()

func startLevelTimer() {

    levelTimerLabel.fontColor = SKColor.blackColor()
    levelTimerLabel.fontSize = 40
    levelTimerLabel.position = CGPoint(x: size.width/2, y: size.height/2 + 350)
    addChild(levelTimerLabel)

    levelTimer = NSTimer.scheduledTimerWithTimeInterval(0.5, target: self, selector: Selector("levelCountdown"), userInfo: nil, repeats: true)

    levelTimerLabel.text = String(levelTimerValue)

}

func levelCountdown(){

    levelTimerValue--

}

8147
2018-02-01 20:52


起源

这是在主队列上运行吗?我假设是的,但只是为了确定...... - diatrevolo


答案:


我会坚持 SKActions 因为事实,SpriteKit中的这些任务 NSTimer 不受场景或视图暂停状态的影响,因此可能会导致您遇到麻烦。或者至少,它会 要求 从您实施暂停功能,以便在某些情况下暂停您的计时器,例如当用户暂停场景,或接听电话等时。阅读更多 这里 关于 SKAction VS NSTimer VS GCD 与SpriteKit中的时间相关的操作。

import SpriteKit

class GameScene: SKScene {

var levelTimerLabel = SKLabelNode(fontNamed: "ArialMT")

//Immediately after leveTimerValue variable is set, update label's text
var levelTimerValue: Int = 500 {
    didSet {
        levelTimerLabel.text = "Time left: \(levelTimerValue)"
    }
}

override func didMoveToView(view: SKView) {



levelTimerLabel.fontColor = SKColor.blackColor()
levelTimerLabel.fontSize = 40
levelTimerLabel.position = CGPoint(x: size.width/2, y: size.height/2 + 350)
levelTimerLabel.text = "Time left: \(levelTimerValue)"
addChild(levelTimerLabel)

    let wait = SKAction.waitForDuration(0.5) //change countdown speed here
    let block = SKAction.runBlock({
        [unowned self] in

        if self.levelTimerValue > 0{
            self.levelTimerValue--
        }else{
            self.removeActionForKey("countdown")
        }
    })
    let sequence = SKAction.sequence([wait,block])

    runAction(SKAction.repeatActionForever(sequence), withKey: "countdown")
}

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

    //Stop the countdown action

    if actionForKey("countdown") != nil {removeActionForKey("countdown")}
}
}

12
2018-02-02 00:11



谢谢您的意见。 - boehmatron
这有什么关键(“倒计时”)? - Confused
@Confused在此示例中,操作在具有“倒计时”键的场景上执行。 - Whirlwind
所以它删除了整个场景? - Confused
我读到的第一个10x,我认为这一行意味着“用这个名字找到行动,这个键,并运行它”,我错误地认为这是对某个同名行为的某种保护。但很明显(现在)这是动作键的赋值,对吗?... runAction(SKAction.repeatActionForever(sequence),withKey:“countdown”) - Confused


听起来你每次都需要更新标签 levelTimerValue 改变了。最简单的方法就是这样。

func levelCountdown(){
    levelTimerValue--
    levelTimerLabel.text = String(levelTimerValue)
}

4
2018-02-01 21:00