Page 1 of 2

Best way to do a timer?

Posted: Sat Oct 18, 2014 7:09 pm
by jjmafiae
How can I make a timer that doesn't break at different framerates?

Re: Best way to do a timer?

Posted: Sat Oct 18, 2014 8:20 pm
by mode7
Thats easy! Something like:

Code: Select all

function newTimer(time,callback)
    local expired = false
    local timer = {}
    
    function timer.update(dt)
         if time < 0 then
               expired = true
               callback()
         end
         time = time - dt         
    end

    function timer.isExpired()
        return expired
    end

    return timer
end

function love.load()
    myTimer = newTimer(2 , function() print("Your timer is due!") end)
end

function love.update(dt)
    if not myTimer.isExpired() then myTimer.update(dt) end
end
This will display "Yout timer is due" after 2 seconds.

Re: Best way to do a timer?

Posted: Sat Oct 18, 2014 8:26 pm
by Zilarrezko
Here's one that I used just last night.

Code: Select all

timer = 0
speed = 2

function love.update(dt)
     if timer > 1 then

          timer = timer - 1
     end

     timer = timer + dt * speed
end
speed is the frequency of the timer going over the limit every second. So if speed is 10, than the "if time > 1 then" block of code is run 10 times a second.

Unless you meant just a timer counting up...

In which case that's easier.

Code: Select all

timer = 0
function update(dt)
     timer = timer + dt
end
or counting down...

Code: Select all

timer = 60 --in seconds
function update(dt)
     if timer <= 0 then
      
     end
     timer = timer - dt
end
Not sure how many definitions of timer's there are... But you are a seasoned programmer, I think you'll do fine.

Re: Best way to do a timer?

Posted: Tue Oct 21, 2014 3:20 am
by Positive07
And when you are using this in a thread you can do

Code: Select all

require "love.timer"
local initialtime = love.timer.getTime()
local stoptimer = 10 --10 seconds

while true do
    timer = love.timer.getTime() - initialtime
    if timer > stoptimer then
        --Do your scheduled actions here
    end
end
This code doesn't depend on love.update or dt so it is easier to use it across your code.

EDIT: If you want dt in your thread then I recommend you use this:

Code: Select all

require "love.timer"
local oldtime = love.timer.getTime()

while true do
    local newtime = love.timer.getTime()
    local dt = newtime - oldtime
    oldtime = newtime

    --Do something using "dt" here
end

Re: Best way to do a timer?

Posted: Tue Oct 21, 2014 10:07 am
by davisdude
Couldn't you also use

Code: Select all

local dt = love.timer.getDelta()

Re: Best way to do a timer?

Posted: Tue Oct 21, 2014 11:51 am
by kikito
Well I created cron.lua exactly for this reason.

A timer can be two things: it can be "something that you want to happen after a certain amount of time has passed" or "something that you want to execute periodically". cron.lua does both.

Here's how you "change a message after 10 seconds have passed", using cron.after:

Code: Select all

local cron = require 'cron'

local msg = "not yet"
local timer = cron.after(10,  function() msg = "10 seconds have passed" end)

function love.update(dt)
  timer:update(dt)
end

function love.draw()
  love.graphics.print(msg, 100, 100)
end
Here's how you "increment an on-screen timer every second", using cron.every:

Code: Select all

local cron = require 'cron'

local seconds = 0
local timer = cron.every(1, function() seconds = seconds + 1 end)

function love.update(dt)
  timer:update(dt)
end

function love.draw()
  love.graphics.print(seconds, 100, 100)
end
There are more examples in the project's page. There is also a small demo in the demo branch.

Re: Best way to do a timer?

Posted: Tue Oct 21, 2014 7:10 pm
by Jasoco
I recommend Cron too. It just makes it dead simple and brainless.

Re: Best way to do a timer?

Posted: Wed Oct 22, 2014 12:58 am
by Positive07
davisdude wrote:Couldn't you also use

Code: Select all

local dt = love.timer.getDelta()
As the wiki says love.timer.getDelta "returns the time between the last two frames" in a thread there are no frames... also the time between frames is probably not the same as the time that the loop took, since the loop and the frames are separated.

So probably if you use getDelta it wont be right... I'm not sure about this though but I recommend using love.timer.getTime over love.timer.getDelta

NOTE: IN THREADS! in the main program you can use getDelta and whatever you like... but in threads you probably need something else

PS: cron.lua is amazing... if you are doing timers you really want to use it.

Re: Best way to do a timer?

Posted: Wed Oct 22, 2014 10:15 am
by davisdude
Positive07 wrote:in a thread there are no frames
Huh. I didn't know that.

Re: Best way to do a timer?

Posted: Thu Oct 23, 2014 2:05 pm
by Zilarrezko
Everyone is making a plug hahaha.

But if you're still trying to decide on one. Don't use my first example... I've discovered a problem with having the speed variable higher than your frame rate, causing a spill of speed.

So what is happening is the difference in the fps and the speed in a second was spilling into the timer. So then if you wanted to change the speed to under the fps. Than the difference in the fps and speed would decrement every frame the spilled timer therefore making whatever you want to execute when the timer is up execute every frame until the timer's overflow is balanced out.

I'm sure kikito's library compensates for these things. He and/or she thinks of everything. ;)