如何在 swift 中制作倒数计时器或正数计时器?

How to make a reversed countdown or a count up timer in swift?

我正在开发一款 2d 平台游戏,我需要的是一个计数计时器,也就是进度条或进度计数节点。它应该像倒计时一样工作,除了它应该从 0 开始并无休止地上升。我将根据该数字的高低来确定游戏 speed/difficulty。我知道在 SO 中提问你应该总是提供一些代码,但我知道如何进行倒计时。现在有人如何创建如下面的屏幕截图所示的内容吗?

编辑

我已经设法实现了我想要的。我刚刚创建了一个 SKLabelNode,它有一个 int 变量作为文本,并且在更新方法中增加了 int 变量,就像 --score++--。但是分数标签的值增加得非常快,有人知道如何减慢一点,然后随着游戏的进行,一段时间后让它慢慢变快吗?

提前谢谢你。

您可以使用 NSTimer 并每 x 秒更新一次值。在游戏开始时创建你的 NSTimer

var timer = NSTimer.scheduledTimerWithTimeInterval(0.4, target: self, selector: #selector(MyGame.countUp), userInfo: nil, repeats: true)

然后在同一个 class 中创建一个函数来计算值,例如1

func countUp() {
    self.myCountLabel.text == "\(1 + self.myCountLabel.text ?? 0)"
}

也许是这样的:

import SpriteKit

class Player:SKSpriteNode {

    override init(texture: SKTexture?, color: UIColor, size: CGSize) {
        super.init(texture: texture, color: color, size: size)
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

class GameScene: SKScene, SKPhysicsContactDelegate {

    var gameStarted = false
    var player = Player(texture: nil, color: UIColor.brownColor(), size: CGSize(width: 50, height: 100))

    var levelTimerLabel = SKLabelNode()
    var levelTimerValue: Int = 0 {
        didSet {

            if levelTimerValue == 10 { self.increaseScore(withDelay: 0.1)}
            levelTimerLabel.text = "\(levelTimerValue)m"
        }
    }

    override func didMoveToView(view: SKView) {

        self.player.position = CGPoint(x: CGRectGetMidX(frame), y: CGRectGetMidY(frame))
        addChild(self.player)

        levelTimerLabel.zPosition = 200
        levelTimerLabel.position = CGPoint(x: CGRectGetMidX(frame), y: CGRectGetMidY(frame))
        levelTimerLabel.text = "\(levelTimerValue)m"
        addChild(levelTimerLabel)
    }

    //MARK: SCORELABEL METHOD
    func increaseScore(withDelay delay:NSTimeInterval = 0.5) {

        let block = SKAction.runBlock({[unowned self] in
            self.levelTimerValue += 1 // Swift 3 yo
        })

        let wait = SKAction.waitForDuration(delay)

        let sequence = SKAction.sequence([wait,block])

        self.runAction(SKAction.repeatActionForever(sequence), withKey: "countUp")

    }
    override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
        if gameStarted == false {

            gameStarted = true
            startWorld()
            increaseScore()
        }
       player.physicsBody?.velocity = CGVectorMake(0, 0)
       player.physicsBody?.applyImpulse(CGVectorMake(0, 150))  // Jump Impulse
    }

    func startWorld(){

        print("startWold method invoked")
    }
}

levelTimerValue 达到 10 时,countUp 动作将被替换为新的动作,速度将提高 5 倍。我想这就是你想要达到的目标。我稍微修改了您的代码以避免强引用循环,删除了不需要的 update: 方法调用和一些小的东西。另请注意,现在您没有名为 "wait" 的 SKAction 属性。该操作现在在本地创建。

编辑:

根据您的评论,您可以像这样暂停计时器:

 func pauseTimer(){

        if let countUpAction = self.actionForKey("countUp") {

            countUpAction.speed = 0.0
        }

    }

取消暂停也是一样...只需将 countUpAction.speed 设置为 1.0 如果您想暂停整个游戏,请查看 SO 问题。看看@Knight0fDragon 的回答。这是一个很好的方式,而且 IMO,它比完全暂停场景或视图更灵活。

此外,我建议您不要使用字符串 "countUp",而是创建一个这样的常量:

let kCountUpActionKey = "countUp"

因此您在重复使用此操作键时不会出现拼写错误。