我在Xcode中为游戏创建了一个简单的计时器(SpriteKit):
变量timer,seconds和score在类中初始化。
func scoreTimer() {
timer = Timer.scheduledTimer(timeInterval: 0.05, target: self, selector: #selector(countUp), userInfo: nil, repeats: true)
}
@objc func countUp() {
seconds += 0.05
seconds = (seconds * 100).rounded() / 100
score = score + 0.015
updateScore()
}
updateScore() {
scoreLabel.text = "\(score)"
}
加载GameScene时,计时器在didMove()中启动。
我尝试每0.5秒调用一次countUp()。在此函数中,变量秒数增加并且舍入加上得分变量增加。从那里我想调用updateScore函数来更新scoreLabel.text - 但这不起作用。该函数被调用,但scoreLabel没有更新,虽然当我尝试打印得分变量时,它表明它不断增加。
我怎样才能实现这一点以及这里有什么问题?
答案 0 :(得分:3)
除非您使用SpriteKit之外的技术,否则应该使用SpriteKit避免使用计时器。原因是因为SpriteKit有自己的时间管理,并且计时器可能与它不一致。例如,在您的情况下,计时器更新分数。如果你暂停比赛怎么办?除非你记得停止,否则你的计时器仍然会增加分数。
相反,依靠行动来做你需要的事情下面是你如何做你想要的。
let wait = SKAction.wait(forDuration: 0.5)
let update = SKAction.run(
{
seconds += 0.05
seconds = (seconds * 100).rounded() / 100
score = score + 0.015
updateScore()
}
)
let seq = SKAction.sequence([wait,update])
let repeat = SKAction.repeatForever(seq)
run(repeat)
@RonMyschuk提到了一个我错过的想法,所以我也会在答案中添加它。
如果您需要创建可以在组中单独暂停或暂停的计时器,则添加额外的SKNode并将计时器操作附加到节点而不是场景。然后,当您需要暂停计时器时,您可以暂停该节点。这样可以在您的计时器暂停时继续更新场景。
答案 1 :(得分:2)
我认为应该在Spritekit中避免使用Timers。
您还可以使用更新循环更新标签。
通过更新循环控制时间允许您在游戏停止时暂停“计时器”,而无需从场景中删除操作。
您还可以使用此方法运行多个计时器
private var updateTime: Double = 0
private var updateTime2: Double = 0
override func update(_ currentTime: CFTimeInterval) {
//this will be some sort of variable dictating the state of your game
guard gameState == .playing else {
updateTime = 0
updateTime2 = 0
return
}
if updateTime == 0 {
updateTime = currentTime
}
if updateTime2 == 0 {
updateTime2 = currentTime
}
if currentTime - updateTime > 0.5 {
//do something every half second
updateTime = currentTime
score = score + 0.015
updateScore()
}
if currentTime - updateTime2 > 30 {
//do something every 30 seconds
updateTime2 = currentTime
someFunc()
}
}