Page 1 of 1

Move object every X seconds

Posted: Tue Aug 21, 2012 4:09 am
by geocine

Code: Select all

function love.update(dt)
	-- Move currentSquare every X seconds
	currentSquare = Rectangle:new(math.random(0, love.graphics.getWidth() - 25),math.random(0,love.graphics.getHeight()-25),25,25)
end
I don't know how often an update is called every second. On XNA it is called 60 times per second. I want to update my "Rectangle" object position every X seconds, how do I do that?

Re: Move object every X seconds

Posted: Tue Aug 21, 2012 4:26 am
by Roland_Yonaba
A handy solution is to implement an accumulator.

Code: Select all

function love.load()
   count = 0
   updateDelay = ... --set it to the desired delay
end

function love.update(dt)
   count = count + dt -- dt is in seconds
   if count > updateDelay then
      ---update logic code goes here
      count = 0
   end
end

Re: Move object every X seconds

Posted: Tue Aug 21, 2012 7:51 am
by geocine
Thanks. This is what I came up with.

Code: Select all

local currentSquare
timeRemaining = 0.0
TimePerSquare = 0.75

function love.update(dt)
	if timeRemaining == 0.0 then
		currentSquare = Rectangle:new(math.random(0, love.graphics.getWidth() - 25),math.random(0,love.graphics.getHeight()-25),25,25)
		timeRemaining = TimePerSquare
	end

	timeRemaining = findMax({0,timeRemaining-dt})	
end

Re: Move object every X seconds

Posted: Tue Aug 21, 2012 8:16 am
by Roland_Yonaba
Hmm..
Well, I don't know what the code behind Rectangle:new()
But, actually, if this is supposed to return a new rectangle each frame, then that's too bad, cause it'll end up eating memory quickly.
Create this rectangle once, then act on his parameters to update it.
Unless the point of your game is too generate a lot of objects.

And use precalculated values. If you don't ever change the game's window height and width, no need to compute love.graphics.getWidth()-25 every update cycle, set it once, then use it.

What's findMax is supposed to do ? Find the maximum value between 0 and timeRemaining-dt ?
Then why passing them as a table ? It'll be safe to use math.max

Re: Move object every X seconds

Posted: Tue Aug 21, 2012 9:57 am
by ivan
Just a small modification to Roland's example.
You may need to update the game logic multiple times per 'love.update' in order to avoid slowdown.

Code: Select all

function love.load()
   count = 0
   updateDelay = ... --set it to the desired delay
end

function love.update(dt)
   count = count + dt -- dt is in seconds
   while count > updateDelay do
      ---update logic code at fixed rate of "updateDelay"
      count = count - updateDelay
   end
end
Also, drawing objects becomes a bit more complicated.
To avoid stuttering, you have to compensate for the accumulated delta in "count":

Code: Select all

function love.draw()
  -- draw objects at interpolated positions/angles:
  -- position = velocity * count
end

Re: Move object every X seconds

Posted: Tue Aug 21, 2012 11:37 am
by kexisse
The hump library has a Timer class that is perfect for this.

Re: Move object every X seconds

Posted: Tue Aug 21, 2012 12:15 pm
by T-Bone
You can easily make a timing queue of sorts that can process any number of events at given times. Something like this

Code: Select all

queue = {}
queuetime = 0

function updatequeue(dt)
	queuetime = queuetime + dt
	for i =#queue,1,-1 do
		if queue[i] and (queue[i].time < queuetime) then
			queue[i].func()
			table.remove(queue,i)
		end
	end
end

function delay(func,time)
	--execute the function "func" after time "time"
	table.insert(queue,{time=queuetime+time,func=func})
end

function love.update(dt)
	updatequeue(dt)
	
	--add rest of love.update here
	
end

function love.keypressed()
	--example
	delay(function()
		print("Awesome sauce")
	end,5)
	--the string "Awesome sauce" will be printed after 5 seconds
end

Re: Move object every X seconds

Posted: Fri Aug 24, 2012 6:41 am
by geocine
Roland_Yonaba wrote:Hmm..
Well, I don't know what the code behind Rectangle:new()
But, actually, if this is supposed to return a new rectangle each frame, then that's too bad, cause it'll end up eating memory quickly.
Create this rectangle once, then act on his parameters to update it.
Unless the point of your game is too generate a lot of objects.

And use precalculated values. If you don't ever change the game's window height and width, no need to compute love.graphics.getWidth()-25 every update cycle, set it once, then use it.

What's findMax is supposed to do ? Find the maximum value between 0 and timeRemaining-dt ?
Then why passing them as a table ? It'll be safe to use math.max
Thanks for the wonderful advices . I didn't thought of this too much, because I was porting the code as is from a C# implementation.
ivan wrote:Just a small modification to Roland's example.
You may need to update the game logic multiple times per 'love.update' in order to avoid slowdown.

Code: Select all

function love.load()
   count = 0
   updateDelay = ... --set it to the desired delay
end

function love.update(dt)
   count = count + dt -- dt is in seconds
   while count > updateDelay do
      ---update logic code at fixed rate of "updateDelay"
      count = count - updateDelay
   end
end
Also, drawing objects becomes a bit more complicated.
To avoid stuttering, you have to compensate for the accumulated delta in "count":

Code: Select all

function love.draw()
  -- draw objects at interpolated positions/angles:
  -- position = velocity * count
end
I didn't account for velocity. This is worth a try, I would try this.
kexisse wrote:The hump library has a Timer class that is perfect for this.
I will definitely check that out.
T-Bone wrote:You can easily make a timing queue of sorts that can process any number of events at given times. Something like this

Code: Select all

queue = {}
queuetime = 0

function updatequeue(dt)
	queuetime = queuetime + dt
	for i =#queue,1,-1 do
		if queue[i] and (queue[i].time < queuetime) then
			queue[i].func()
			table.remove(queue,i)
		end
	end
end

function delay(func,time)
	--execute the function "func" after time "time"
	table.insert(queue,{time=queuetime+time,func=func})
end

function love.update(dt)
	updatequeue(dt)
	
	--add rest of love.update here
	
end

function love.keypressed()
	--example
	delay(function()
		print("Awesome sauce")
	end,5)
	--the string "Awesome sauce" will be printed after 5 seconds
end
This would be great for a wider scale implementation.