How to handle multiple timers

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.
Post Reply
User avatar
mtdev
Prole
Posts: 20
Joined: Mon Feb 20, 2017 5:10 am
Location: Midwest US

How to handle multiple timers

Post by mtdev »

Playing around with an idea that has multiple bases. Player starts with 1 base and has a timer that increases units for it. My question is how should I handle the timer(s) for the npc bases? Have considered tracking the timer within the table for each base as they may need to differ from each other in the future.

Code: Select all

bases[id].timer = some float
Guess the question would be if that is the "normal" way to handle it?

Also, if anyone has any suggestions for how to draw the map, it would be helpful. Left click an NPC base to claim it and you will see what I am trying to solution. Current thought is to lock onto the player's starting base to start (as it does now) and then maybe have any right mouse clicks re-center the map. Thoughts?

Thanks for looking
Attachments
testing.love
(2.2 KiB) Downloaded 101 times
Lucyy
Citizen
Posts: 51
Joined: Thu Oct 15, 2015 6:57 am
Contact:

Re: How to handle multiple timers

Post by Lucyy »

The best way to do this is, like you said, by keeping track of the timers within the instances of your base object aka the table.

Your table would look something like:

Code: Select all

Base = {}
Base.Timer = 0
Base.createUnit = function()
    -- create your unit here
end
function Base:update(dt)
    this.Timer = this.Timer + dt

    if this.Timer >= 5 then
        this.createUnit()
        this.Timer = 0
    end
end
return Base
In this example the createUnit function would get called every 5 seconds for every instance of Base.
Last edited by Lucyy on Tue Mar 28, 2017 6:01 pm, edited 1 time in total.
User avatar
zorg
Party member
Posts: 3444
Joined: Thu Dec 13, 2012 2:55 pm
Location: Absurdistan, Hungary
Contact:

Re: How to handle multiple timers

Post by zorg »

Lucyy wrote: Tue Mar 28, 2017 3:44 pm <Code snippet Snip>
if you define the parameter to :update as dt then you should use it as dt, not DT; lua is case-sensitive.
Me and my stuff :3True Neutral Aspirant. Why, yes, i do indeed enjoy sarcastically correcting others when they make the most blatant of spelling mistakes. No bullying or trolling the innocent tho.
Lucyy
Citizen
Posts: 51
Joined: Thu Oct 15, 2015 6:57 am
Contact:

Re: How to handle multiple timers

Post by Lucyy »

zorg wrote: Tue Mar 28, 2017 5:00 pm if you define the parameter to :update as dt then you should use it as dt, not DT; lua is case-sensitive.
My bad, typed it on my phone xD I didn't notice it auto-corrected it
User avatar
mtdev
Prole
Posts: 20
Joined: Mon Feb 20, 2017 5:10 am
Location: Midwest US

Re: How to handle multiple timers

Post by mtdev »

Thank you Lucyy

I was thinking I might need every base to be on a different timer or probably in 1 of say 4 groups.

something like

Code: Select all

function love:update(dt)
	for _,base in pairs(bases)
		base.timer = base.timer - dt
		if base.timer <= 0 then
			createUnit(blah, blah)
			base.timer = base.defaultTimer (could be 1, 2, etc... - different for various bases)
		end
	end		
end
There would be at least 40 of these and perhaps more. Any gotchas come to mind? Thanks again!
Lucyy
Citizen
Posts: 51
Joined: Thu Oct 15, 2015 6:57 am
Contact:

Re: How to handle multiple timers

Post by Lucyy »

That seems about right ;o though you'd probably reset your timer to 0, no reason to start counting at 1.

And I recommend moving the code within your loop into an update function in your base object. And then change the loop to be like:

Code: Select all

for _, base in ipairs(bases) do
    base:update(dt)
end
This way your love.update will look a bit cleaner
User avatar
s-ol
Party member
Posts: 1077
Joined: Mon Sep 15, 2014 7:41 pm
Location: Cologne, Germany
Contact:

Re: How to handle multiple timers

Post by s-ol »

Lucyy wrote: Wed Mar 29, 2017 4:37 am That seems about right ;o though you'd probably reset your timer to 0, no reason to start counting at 1.

And I recommend moving the code within your loop into an update function in your base object. And then change the loop to be like:

Code: Select all

for _, base in ipairs(bases) do
    base:update(dt)
end
This way your love.update will look a bit cleaner
In the last example he doesn't start counting at 1, he starts counting at the duration and decrements to 0, which is the proper way to do it IMO.
mtdev wrote: Wed Mar 29, 2017 3:48 am There would be at least 40 of these and perhaps more. Any gotchas come to mind? Thanks again!
That's far from a problematic amount of 'things of this complexity' to handle, and it's perfectly usual to keep this many seperate timers running :)

Lucyy is right that it may get easier to manage lots of different types of objects if you start encapsulating them OOP-style like in his example, but don't feel urged to do it if you don't see the need (yet) or it makes the project less simple to read in your opinion.

s-ol.nu /blog  -  p.s-ol.be /st8.lua  -  g.s-ol.be /gtglg /curcur

Code: Select all

print( type(love) )
if false then
  baby:hurt(me)
end
User avatar
zorg
Party member
Posts: 3444
Joined: Thu Dec 13, 2012 2:55 pm
Location: Absurdistan, Hungary
Contact:

Re: How to handle multiple timers

Post by zorg »

s-ol wrote: Wed Mar 29, 2017 3:32 pm In the last example he doesn't start counting at 1, he starts counting at the duration and decrements to 0, which is the proper way to do it IMO.
If not the proper way, i do agree that it's easier to code if a variable used as a counter going from someVal down to zero, since wherever you want to implement the check, you only need to compare the counter with 0, not any stored value.
Me and my stuff :3True Neutral Aspirant. Why, yes, i do indeed enjoy sarcastically correcting others when they make the most blatant of spelling mistakes. No bullying or trolling the innocent tho.
User avatar
s-ol
Party member
Posts: 1077
Joined: Mon Sep 15, 2014 7:41 pm
Location: Cologne, Germany
Contact:

Re: How to handle multiple timers

Post by s-ol »

zorg wrote: Wed Mar 29, 2017 4:19 pm
s-ol wrote: Wed Mar 29, 2017 3:32 pm In the last example he doesn't start counting at 1, he starts counting at the duration and decrements to 0, which is the proper way to do it IMO.
If not the proper way, i do agree that it's easier to code if a variable used as a counter going from someVal down to zero, since wherever you want to implement the check, you only need to compare the counter with 0, not any stored value.
Lucyy just asked about my reasoning in a PM and I already wanted to come back and change the wording too. When I have the choice to use either (because the limit is constant, see below) I go with this way and I consider it slightly superior because of what you said - it's cleaner when the limit is only read on reset, because it groups the action taken and the time to get there in your code visually. Someone might disagree here, and I guess it is personal choice.

However both ways definitely have their own reasons to be used, consider:

Code: Select all

local timer = 0

function love.update(dt)
  maxTimer = love.mouse.isDown(1) and 4 or 2
  if timer > maxTimer then
    timer = 0
    -- do something
  end
end
and

Code: Select all

local timer = 2

function love.update(dt)
  maxTimer = love.mouse.isDown(1) and 4 or 2
  if timer < 0 then
    timer = timer + maxTimer
    -- do something
  end
end
these two timers will have different behavior when the mouse is pressed and depressed anytime else than right on a timer reset.
This actual logic difference of course matters and the right one should be chosen (there are other ways to produce both behaviors, but these are the simplest I think).

s-ol.nu /blog  -  p.s-ol.be /st8.lua  -  g.s-ol.be /gtglg /curcur

Code: Select all

print( type(love) )
if false then
  baby:hurt(me)
end
Post Reply

Who is online

Users browsing this forum: Ahrefs [Bot] and 220 guests