Best way to do a timer?

Questions about the LÖVE API, installing LÖVE and other support related questions go here.
Forum rules
Before you make a thread asking for help, read this.
jjmafiae
Party member
Posts: 1331
Joined: Tue Jul 24, 2012 8:22 am

Best way to do a timer?

Post by jjmafiae »

How can I make a timer that doesn't break at different framerates?
mode7
Prole
Posts: 35
Joined: Tue Aug 21, 2012 5:45 pm
Contact:

Re: Best way to do a timer?

Post 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.
User avatar
Zilarrezko
Party member
Posts: 345
Joined: Mon Dec 10, 2012 5:50 am
Location: Oregon

Re: Best way to do a timer?

Post 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.
User avatar
Positive07
Party member
Posts: 1006
Joined: Sun Aug 12, 2012 4:34 pm
Location: Argentina

Re: Best way to do a timer?

Post 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
for i, person in ipairs(everybody) do
[tab]if not person.obey then person:setObey(true) end
end
love.system.openURL(Github.com/Positive07)
davisdude
Party member
Posts: 1154
Joined: Sun Apr 28, 2013 3:29 am
Location: North Carolina

Re: Best way to do a timer?

Post by davisdude »

Couldn't you also use

Code: Select all

local dt = love.timer.getDelta()
GitHub | MLib - Math and shape intersections library | Walt - Animation library | Brady - Camera library with parallax scrolling | Vim-love-docs - Help files and syntax coloring for Vim
User avatar
kikito
Inner party member
Posts: 3153
Joined: Sat Oct 03, 2009 5:22 pm
Location: Madrid, Spain
Contact:

Re: Best way to do a timer?

Post 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.
Last edited by kikito on Wed Oct 22, 2014 10:25 am, edited 1 time in total.
When I write def I mean function.
User avatar
Jasoco
Inner party member
Posts: 3655
Joined: Mon Jun 22, 2009 9:35 am
Location: Pennsylvania, USA
Contact:

Re: Best way to do a timer?

Post by Jasoco »

I recommend Cron too. It just makes it dead simple and brainless.
User avatar
Positive07
Party member
Posts: 1006
Joined: Sun Aug 12, 2012 4:34 pm
Location: Argentina

Re: Best way to do a timer?

Post 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.
for i, person in ipairs(everybody) do
[tab]if not person.obey then person:setObey(true) end
end
love.system.openURL(Github.com/Positive07)
davisdude
Party member
Posts: 1154
Joined: Sun Apr 28, 2013 3:29 am
Location: North Carolina

Re: Best way to do a timer?

Post by davisdude »

Positive07 wrote:in a thread there are no frames
Huh. I didn't know that.
GitHub | MLib - Math and shape intersections library | Walt - Animation library | Brady - Camera library with parallax scrolling | Vim-love-docs - Help files and syntax coloring for Vim
User avatar
Zilarrezko
Party member
Posts: 345
Joined: Mon Dec 10, 2012 5:50 am
Location: Oregon

Re: Best way to do a timer?

Post 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. ;)
Post Reply

Who is online

Users browsing this forum: No registered users and 32 guests