Timers tutorial

How timers work

Timers are an easy and powerful way to measure time with millisecond precision. Timers call a Lua function after a given period of time has elapsed. Once we create a timer object, we then have to start it and specify its interval in milliseconds. Next, we set a handler function for the timer that will be called when the interval time is up. If the recurring flag is set to true, our handler function will be evoked repeatedly.

timer = Timer ( )
timer:start ( 1000, true )

timer.on_tick = function ( timer )
  -- will be called once every 1000 ms
  local ms = timer:get_delta_ms ( )
end

It is never guaranteed that your handler function will be called precisely at the desired time interval. For example, let's say that we have created a recurring timer with an interval of 16 milliseconds. However, the callback function takes 32 milliseconds to execute. In such a case, the callback function would be evoked half less frequently than we expect. To accommodate for the potential delay between callbacks, we have to look at the timer's delta value. The delta value shows the actual amount of time elapsed since the last callback. Your program must take delta into account at each callback in order to produce smooth, frame-independent effects.

Clock example

Now that you understand how timers work, we will write a simple analog clock program, measuring time in seconds. We draw a clock arrow on a sprite and rotate it a tiny amount at every callback. The way delta is taken into account is as follows. We know that the seconds arrow of a clock rotates 0.006 degrees ( 360 / 60 / 1000 ) each millisecond. By multiplying delta in milliseconds by 0.006 we get the required change in degrees between callbacks.

display:create ( "Clock example", 800, 600, 32, true )

arrow = Sprite ( )
arrow.canvas:line_to ( 0, 200 )
arrow.canvas:set_line_style ( 5, WHITE, 1 )
arrow.canvas:stroke ( )
display.viewport:add_child ( arrow )

timer = Timer ( )
timer:start ( 16, true )

timer.on_tick = function ( timer )
  local delta = timer:get_delta_ms ( )
  arrow.rotation = arrow.rotation + 0.006 * delta
end
Download:  timer.lua