如何在swift中进行反转倒计时或倒数计时器?

时间:2016-08-22 12:25:46

标签: ios swift sprite-kit progress-bar countdown

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

修改

我成功实现了我想要的东西。我刚刚创建了一个带有int变量作为文本的SKLabelNode,并且在update方法中增加了int变量--score ++ - 。但是得分标签的价值增长得非常快,是否有人知道它有多慢,然后经过一段时间后随着游戏的进一步加快?

提前谢谢你。

enter image description here enter image description here

enter image description here enter image description here

enter image description here

3 个答案:

答案 0 :(得分:2)

也许是这样的:

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即可 如果您想暂停整个游戏,请查看this SO问题。看看@ Knight0fDragon的回答。这是一个很好的方式,IMO,它比完全暂停场景或视图更灵活。

而不是使用字符串“countUp”,我建议你像这样制作一个常量:

let kCountUpActionKey = "countUp"

因此,在重复使用此操作键时,您将免于拼写错误。

答案 1 :(得分:0)

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

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

然后在同一个类中创建一个函数,该函数通过例如1

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

答案 2 :(得分:0)

@Whirlwind所以,这里是我如何使用你的代码:

我的GameScene:

class GameScene: SKScene, SKPhysicsContactDelegate {

    var wait = SKAction.waitForDuration(0.5) //change countdown speed here
    var levelTimerLabel = SKLabelNode()
    var levelTimerValue: Int = 0 {
    didSet {
        levelTimerLabel.text = "\(levelTimerValue)m"
    }
}

override func didMoveToView(view: SKView) {

    levelTimerLabel.zPosition = 200
    levelTimerLabel.position = CGPoint(x: self.frame.width / 2, y: self.frame.height / 2 )
    levelTimerLabel.text = "\(levelTimerValue)m"
    addChild(levelTimerLabel)
}
func increaseScore() {

    var block = SKAction.runBlock({
        () in
        self.levelTimerValue++
    })
    var 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() //MARK: SCORELABEL METHOD
        Player.runAction(SKAction.repeatActionForever(SKAction.animateWithTextures(TextureArray, timePerFrame: 0.058)))

 }else{

    }
    Player.physicsBody?.velocity = CGVectorMake(0, 0)
    Player.physicsBody?.applyImpulse(CGVectorMake(0, 150))  // Jump Impulse
}
override func update(currentTime: CFTimeInterval) {
    if gameStarted == true {
    if levelTimerValue == 10 {
        wait = SKAction.waitForDuration(0.1) //change countdown speed here
        }
    }
}
}

正如您所看到的,我已经使用了您提供的代码,到目前为止一切正常。但是,我需要做的和悲惨的未能成功的是如果levelTimerValue达到某个点或更好的话就改变等待变量说加速倒计时。你知道我怎么做吗?