Timer/Stopwatch Not Accurate/Precise - Slow

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
views:2748 update:2011/9/26 8:07:09
corona forums © 2003-2011