如何快速进行倒计时或倒计时?

Posted

技术标签:

【中文标题】如何快速进行倒计时或倒计时?【英文标题】:How to make a reversed countdown or a count up timer in swift? 【发布时间】:2016-08-22 12:25:45 【问题描述】:

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

编辑

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

提前谢谢你。

【问题讨论】:

我将从标签值增加的条件开始。是基于时间(即每 30 秒增加一次)还是基于进度?还是完全基于其他东西? @Ollie 抱歉回答迟了,我认为计时器是基于进度的。它只是一个上升的 SKLabelNode,在某个点之后它应该上升得更快,因为游戏向左滚动得更快(sidescroller) 【参考方案1】:

也许是这样的:

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 属性。该操作现在在本地创建。

编辑:

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

 func pauseTimer()

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

            countUpAction.speed = 0.0
        

    

取消暂停将是相同的...只需将 countUpAction.speed 设置为 1.0 如果您想暂停整个游戏,请查看this SO question。看看@Knight0fDragon 的回答。这是一个不错的方法,而且 IMO,它比完全暂停场景或视图更灵活。

我建议您不要使用字符串“countUp”,而是像这样创建一个常量:

let kCountUpActionKey = "countUp"

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

【讨论】:

效果很好!非常感谢 :-) 如果您不介意,我有一个问题,我将在我的游戏中实现暂停状态,如何暂停倒数计时器并再次恢复?你为什么要创建一个玩家类?再次感谢您,我会将您的答案标记为正确。 @iCod3r 我进行了编辑以向您展示如何获取特定操作并暂停它。至于 Player 类......好吧,我为我做了这个,以便在内部测试它并忘记删除它:) 也可以,谢谢!只剩下一个简单的问题(我知道我有很多问题,抱歉)我的 countUp 计时器从值“0.15”开始,然后当它达到 50m 时变为“0.14”,到 100m 时变为“0.13”等等。我的问题是,我怎样才能在比赛中找出计时器的价值?因此,如果玩家暂停游戏,假设在 200m 并且 countUp 计时器的值为“0.11”,重要的是当玩家恢复游戏时,countUp 计时器具有与暂停状态之前相同的值,因此游戏速度保持不变 好吧,你有点跑题了。你原来的问题得到了回答。如果您有不同的问题,请随时提出新问题,希望有人会回答。总之,当玩家暂停游戏时,等待动作的持续时间参数的值与之前相同。为什么你认为有些事情会改变?无论如何,您真的应该问新问题,因为我们将进入单独的主题。祝你的游戏好运! 哦,是的,对不起,你是对的!我把速度值误认为是等待动作/持续时间值。无论如何,我不再对这个话题有任何疑问。你太棒了,我希望我能多次支持你回答:-)谢谢!【参考方案2】:

您可以使用 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)"

【讨论】:

在 SpriteKit 中更合适的方式是使用 SKAction 或 update: 方法。 NSTimer 不受视图或场景暂停状态的影响,因此当用户接到电话或发生其他中断时,自动暂停/取消暂停将不起作用。 但是,您可以在发生中断时使计时器无效。虽然我同意 感谢您回答 Yannick,但就像 @Whirlwind 所说的 NSTimer 不受视图状态的影响,因此它不适合我。 @Yannick,它比这更复杂,你需要保留已经过去的时间,然后在返回时触发一个计时器以获取差异,然后重新启动正常计时器,主要的痛苦是正确。 @Whirlwind 我看了你的帖子并尝试实现它,我必须修改一些东西才能让它正常工作,以便它适合我的游戏。如果你不介意的话,我会在几个小时内向你报告,不幸的是我现在得走了。

以上是关于如何快速进行倒计时或倒计时?的主要内容,如果未能解决你的问题,请参考以下文章

Android Study Jam 倒计时:最后一周 提交小测赢好礼

日期选择器中的小时:分钟:秒如何快速

JS实现为控件添加倒计时功能

如何使用 NSTimer 进行倒计时?

快速倒计时计时器逻辑

微信小程序----团购或秒杀的批量倒计时实现