Hey all,
I'm new to Corona and coding in general, but after looking to implement a timer/stopwatch in my game, I've created something which I think looks and generally works well but...
Although the logic seems fine to me, the time keeping is not 100% accurate.
I've tested it running alongside a real stopwatch and over the course of a minute it seems to lag a few seconds behind.
Can you spot where my logic and/or code is wrong? Or, is there some particular reason why this would be?
On a separate note, I tried to find some example code for a timer like this everywhere and could not. I think it's suits a great variety of apps and games - puzzle, racing, etc. So, if people think that this would be useful to others, I'm going to post it the 'Share Your Code' section - when it's working correctly of course.
Anyway, here's what I have so far:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 | local _W, _H = display.contentWidth, display.contentHeight local seconds, minutes, tenthSeconds -- Create basic start button (text) local startButtonText = display.newText( "Tap To Start", 0, 0, native.systemFont, 24 ) startButtonText.x = _W / 2; startButtonText.y = (_H / 2) + 80 startButtonText:setTextColor( 255, 255, 255 ) -- Create basic start/stop button local timerCount = display.newText( "00:00:0", 0, 0, native.systemFont, 48 ) timerCount.x = _W / 2; timerCount.y = (_H / 2) - 40 timerCount:setTextColor( 255, 255, 255 ) local function startTimer(e) startButtonText:removeSelf() startButtonText = nil function timerCount:timer( event ) local count = event.count tenthSeconds = math.floor(count % 10) seconds = math.floor(count / 10 ); seconds = math.floor(seconds % 60) minutes = math.floor(count / 600); minutes = math.floor(minutes % 60) timeFormat = string.format("%02d:%02d:%01d", minutes, seconds, tenthSeconds) self.text = timeFormat if count >= 6000 then timer.cancel( event.source ) -- Cancel timer after 10 mins end end timer.performWithDelay( 100, timerCount, 6000 ) -- Call timerCount function every 1/10th second for 10 minutes end -- Tap event listener for start button (text) startButtonText:addEventListener("tap", startTimer) |
One of the staff has a website, where they explain why this happens. Think it was something to do with fps. Also I think it said to us system.os or os.timer instead, you'll have to try find the site or someone else may post it as I can't remember it.
Thanks for the reply. Can't seem to find the web site that you're referring too though so if anyone can provide a link it would be appreciated.
So, what can I do to improve the accuracy of this timer model? Anything?
If not, what way is generally used to provide a similar, but more precise timer function? Are there samples around anywhere?
Thanks
Yeah, you won't get uber accurate timing. However, like Lewis said, use getTimer. It's a # that always increases and uses like the sys clock.
You can do it like so. First, save this as "Timer.lua":
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | Timer = {} function Timer:new() local ticker = {} ticker.lastTick = system.getTimer() ticker.paused = true ticker.totalTime = 0 function ticker:enterFrame(event) local lastTick = self.lastTick local now = system.getTimer() local difference = now - lastTick self.lastTick = now self.totalTime = self.totalTime + difference end function ticker:pause() self.paused = true Runtime:removeEventListener("enterFrame", self) end function ticker:reset() self.lastTick = system.getTimer() end function ticker:unpause() if self.paused == true then self.paused = false Runtime:removeEventListener("enterFrame", self) self.lastTick = system.getTimer() end end function ticker:start() Runtime:removeEventListener("enterFrame", self) self.paused = false Runtime:addEventListener("enterFrame", self) end return ticker end return Timer |