我尝试过搜索其他答案,但找不到适用于我的方案的答案。我正在快速编写游戏,并希望创建一个秒表来确定玩家玩的时间长短。当用户触摸时,秒表将启动,当某个动作发生时,计时器停止并重置。我想使用分钟,秒,毫秒(即00:00.00)。
目前,时间功能有点有效。它不会从0开始,它从当前的时间点开始(我知道当我启动时,但我不知道如何在0开始)。它也只在我触摸屏幕时更新,我需要它从00:00开始计数并自行更新,直到取消操作被触发。
感谢您的时间。
这是我到目前为止所做的:
class GameScene: SKScene {
var activeTimer = SKLabelNode()
//var bestTime = SKLabelNode()
var startTime = TimeInterval()
//var currentTime = TimeInterval()
//var countingTime = TimeInterval()
var updateTimerAction = SKAction()
override func didMove(to view: SKView) {
activeTimer = self.childNode(withName: "active_timer") as! SKLabelNode
//bestTime = self.childNode(withName: "best_time") as! SKLabelNode
startTime = TimeInterval(Calendar.current.component(.second, from:Date()))
updateTimerAction = SKAction.sequence([SKAction.run(updateTimer), SKAction.wait(forDuration: 1.0)])
}
func startGame() {
// Other code
startGameTimer()
}
func resetGame() {
// Other code
stopGameTimer()
}
func startGameTimer() {
run(SKAction.repeatForever(updateTimerAction), withKey: "timer")
}
func updateTimer() {
activeTimer.text = stringFromTimeInterval(interval: startTime) as String
}
func stringFromTimeInterval(interval: TimeInterval) -> NSString {
let ti = NSInteger(interval)
let ms = Int((interval.truncatingRemainder(dividingBy: 1)) * 1000)
let seconds = ti % 60
let minutes = (ti / 60) % 60
return NSString(format: "%0.2d:%0.2d.%0.2d",minutes,seconds,ms)
}
func stopGameTimer() {
removeAction(forKey: "timer")
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
startGame()
for touch in touches {
// other code
}
}
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
for touch in touches {
// other code
}
}
override func update(_ currentTime: TimeInterval) {
updateTimer()
if <action> {
// stop timer and reset game
resetGame()
}
}
答案 0 :(得分:2)
最好不要使用TimeInterval对象,最好使用一个Timer对象来调用一个函数,该函数在每1秒后从0开始递增标签(或内部变量)的值(或者可以做得更小) )。要停止时钟,只需调用Timer对象的无效功能即可。 有关详细信息,请查看文档:{{3}}
答案 1 :(得分:2)
以下几行代码来自我3周前提交给Mac App Store的实际macOS游戏。它将数字倒数到0.在您的情况下,更改
self.currentSeconds -= 1
到
self.currentSeconds += 1
timeBackNode
是一个空节点,它包含SKLabelNode对象timeNode0和timeNode1。因此,当游戏以didMove
开始时创建它。
var currentSeconds = Int() // currentSeconds
var timeNode0 = SKLabelNode() // timeNode0
var timeNode1 = SKLabelNode() // timeNode1
func setupTimeGoal() {
enumerateChildNodes(withName: "//TimerBack", using: { timeBackNode, _ in
let goal = self.timeDict["num"] as! Int
self.currentSeconds = goal // In your case, goal is 0 since you are going to count up.
self.timeNode0 = SKLabelNode(fontNamed: "Your font's font name")
self.timeNode0.text = self.makeTimeWithSeconds(secs: goal)
self.timeNode0.fontSize = 26
self.timeNode0.fontColor = SKColor.black
self.timeNode0.horizontalAlignmentMode = .center
self.timeNode0.position = CGPoint(x: 1, y: -22)
timeBackNode.addChild(self.timeNode0)
self.timeNode1 = SKLabelNode(fontNamed: "Your font's font name")
self.timeNode1.text = self.makeTimeWithSeconds(secs: goal) // this function translate a counting number into a time code like 00:00:00
self.timeNode1.fontSize = 26
self.timeNode1.fontColor = SKColor.cyan
self.timeNode1.horizontalAlignmentMode = .center
self.timeNode1.position = CGPoint(x: 0, y: -23)
timeBackNode.addChild(self.timeNode1)
})
}
func repeatTime() {
let waitAction = SKAction.wait(forDuration: 1.0)
let completionAction = SKAction.run {
if self.currentSeconds == 0 && self.gameState == .playing {
self.removeAction(forKey: "RepeatTime")
self.proceedLoss()
return
}
self.currentSeconds -= 1
self.timeNode0.text = self.makeTimeWithSeconds(secs: self.currentSeconds)
self.timeNode1.text = self.makeTimeWithSeconds(secs: self.currentSeconds)
}
let seqAction = SKAction.sequence([waitAction, completionAction])
let repeatAction = SKAction.repeatForever(seqAction)
self.run(repeatAction, withKey: "RepeatTime")
}
答案 2 :(得分:0)
这是我最终做的事情。虽然El Tomato的答案似乎有效,但鉴于我的代码设置,我走了一条不同的路线。在与其他朋友交谈后,由于我的应用程序的设计,我选择使用计时器。如果我碰巧使用Timer对象遇到任何问题,我会更新这个问题。
以下代码将以触摸开始,以以下格式更新:&#34; 00:00.00&#34;当动作被触发时停止。此时间将暂停直到另一次触摸,然后定时器将从零开始。
class GameScene: SKScene {
var seconds = 0
var timer = Timer()
var timeStarted = Bool()
var activeTimer = SKLabelNode()
//var bestTime = SKLabelNode()
override func didMove(to view: SKView) {
activeTimer = self.childNode(withName: "active_timer") as! SKLabelNode
//bestTime = self.childNode(withName: "best_time") as! SKLabelNode
timeStarted = false
}
func startGame() {
startGameTimer()
timeStarted = true
}
func resetGame() {
timeStarted = false
stopGameTimer()
seconds = 0
}
func startGameTimer() {
timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: (#selector(updateTimer)), userInfo: nil, repeats: true)
}
func updateTimer() {
seconds += 1
activeTimer.text = timeString(time: TimeInterval(seconds))
}
func timeString(time:TimeInterval) -> String {
let hours = Int(time) / 3600
let minutes = Int(time) / 60 % 60
let seconds = Int(time) % 60
return String(format:"%02i:%02i.%02i", hours, minutes, seconds)
}
func stopGameTimer() {
timer.invalidate()
removeAction(forKey: "timer")
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
if !timeStarted {
startGame()
}
for touch in touches {
// other code
}
}
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
for touch in touches {
// other code
}
}
override func update(_ currentTime: TimeInterval) {
if timeStarted {
updateTimer()
}
if <action> {
// stop timer and reset game
resetGame()
}
}
}