如何快速进行倒计时或倒计时?
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 我看了你的帖子并尝试实现它,我必须修改一些东西才能让它正常工作,以便它适合我的游戏。如果你不介意的话,我会在几个小时内向你报告,不幸的是我现在得走了。以上是关于如何快速进行倒计时或倒计时?的主要内容,如果未能解决你的问题,请参考以下文章