Move object every X seconds

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
geocine
Prole
Posts: 16
Joined: Sat Aug 04, 2012 5:17 pm

Move object every X seconds

Post by geocine » Tue Aug 21, 2012 4:09 am

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?

User avatar
Roland_Yonaba
Inner party member
Posts: 1563
Joined: Tue Jun 21, 2011 6:08 pm
Location: Ouagadougou (Burkina Faso)
Contact:

Re: Move object every X seconds

Post by Roland_Yonaba » Tue Aug 21, 2012 4:26 am

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

geocine
Prole
Posts: 16
Joined: Sat Aug 04, 2012 5:17 pm

Re: Move object every X seconds

Post by geocine » Tue Aug 21, 2012 7:51 am

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

User avatar
Roland_Yonaba
Inner party member
Posts: 1563
Joined: Tue Jun 21, 2011 6:08 pm
Location: Ouagadougou (Burkina Faso)
Contact:

Re: Move object every X seconds

Post by Roland_Yonaba » Tue Aug 21, 2012 8:16 am

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

User avatar
ivan
Party member
Posts: 1548
Joined: Fri Mar 07, 2008 1:39 pm
Contact:

Re: Move object every X seconds

Post by ivan » Tue Aug 21, 2012 9:57 am

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

User avatar
kexisse
Citizen
Posts: 56
Joined: Wed Jun 13, 2012 2:52 pm

Re: Move object every X seconds

Post by kexisse » Tue Aug 21, 2012 11:37 am

The hump library has a Timer class that is perfect for this.

User avatar
T-Bone
Inner party member
Posts: 1492
Joined: Thu Jun 09, 2011 9:03 am

Re: Move object every X seconds

Post by T-Bone » Tue Aug 21, 2012 12:15 pm

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

geocine
Prole
Posts: 16
Joined: Sat Aug 04, 2012 5:17 pm

Re: Move object every X seconds

Post by geocine » Fri Aug 24, 2012 6:41 am

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.

Post Reply

Who is online

Users browsing this forum: No registered users and 27 guests