Jump to content

[TOPIC: topicViewTemplate]
[GLOBAL: userSmallPhoto]
Photo

Need to make a gradually speeding up loop. [SOLVED]
Started by darkelgameman Jun 18 2018 03:55 PM

- - - - -
5 replies to this topic
[TOPIC CONTROLS]
[/TOPIC CONTROLS]
[modOptionsDropdown]
[/modOptionsDropdown]
[reputationFilter]
[TOPIC: post.html]
#1

darkelgameman

[GLOBAL: userInfoPane.html]
darkelgameman
  • Observer

  • 2 posts
  • Corona SDK

Hi! I'm making my first project with corona right now. I have everything working so far, but I just need to find out one thing: how can I make a slowly speeding up loop? I just need any kind of loop that executes a function , and it keeps happening faster and faster.

For instance, it will execute the function every 3000 ms. Every time it executes, though, it goes down by 10 ms.

 

I've made a sleep function from code online but all that does is freezes the program, which I don't want. I've also tried timer.performWithDelay using "enterFrame" but that instantly reaches huge speeds.

 

Can anyone help me? 



[TOPIC: post.html]
#2

sidermaniac

[GLOBAL: userInfoPane.html]
sidermaniac
  • Observer

  • 25 posts
  • Corona SDK

This code prints out using timer.performWithDelay() starting at every 1000ms delay and dropping to 100 and exiting at 0:

local tm = {count=0}
local function handleit(event) 
	print(event.name..event.time)
	tm.count = tm.count + 1 
	if tm.count == 10 then 
		print"timer reset"
		tm.count = 0
		tm["timer"]= nil 
		tm:set_timer()
	end 
end 
function tm:set_timer()
	if self.speed == nil then 
		self.speed = 1000
		print("timer start speed 1000")
	elseif self.speed == 0 then 
		print "done"
		return 
	else
		self.speed = self.speed - 100 
		print("new timer speed: "..self.speed)
	end 
	self["timer"] = timer.performWithDelay(self.speed, handleit, 10)
end 
tm:set_timer()

Edit: 

I cleaned up the code a little.

I made sure to set the expired timer table entry to nil before creating a new one.  

I think without that there might have been a memory leak.  



[TOPIC: post.html]
#3

sidermaniac

[GLOBAL: userInfoPane.html]
sidermaniac
  • Observer

  • 25 posts
  • Corona SDK

Here is another method. This one uses two timers. 

The first timer called print_timer acts as the loop and prints the event.name and event.time to the console. 

The second timer called speed_timer is used to gradually decrease the delay in print_timer causing it to fire events faster. 

local print_timer = nil 
local speed_timer = {speed = 1010}
local function handle_print_timer(event)
	print(event.name.." "..event.time)
end 
local function handle_speed_timer(event)
	speed_timer.speed = speed_timer.speed - 10
	if speed_timer.speed <=0 then 
		timer.cancel(speed_timer["timer"])
		speed_timer["timer"] = nil 
		speed_timer.speed = 1
		print("Maximum speed set")
	end 
	if print_timer ~= nil then 
		timer.cancel(print_timer)
		print_timer = nil 
	end 
	print_timer = timer.performWithDelay(speed_timer.speed, handle_print_timer, 1000)
	print("Speed changed to: "..speed_timer.speed)
end 
speed_timer["timer"] = timer.performWithDelay(2000, handle_speed_timer, 1000 )

In the code I have set a maximum iterations for each timer. This is only so it didn't run constantly during testing.   

The speed timer is set to change the speed every 2 seconds. 

The print timer begins printing events at a rate of 1 per second. So you will see two printed timer events between speed changes until the delay drops to about 650. Then the print timer will start printing 3 events for every speed change. And then obviously this grows as the delay drops.  

When the delay drops below 0, I set the print timer speed to 1 and remove the speed timer.  This will give you maximum speed from the timer. 



[TOPIC: post.html]
#4

roaminggamer

[GLOBAL: userInfoPane.html]
roaminggamer
  • Corona Geek

  • 6,981 posts
  • Corona SDK

Not wanting to miss out, this is my 2-cents.
local resetOnMin = true

local maxPeriod  = 5000
local minPeriod  = 60
local periodDelta = 100

local lastT = system.getTimer()
local curPeriod = maxPeriod

local function work()
   print("Period: " .. tostring(curPeriod) .. " @ " .. tostring(system.getTimer()) )
end

local function enterFrame()
   local curT = system.getTimer()
   local dt = curT - lastT
   --
   if( dt < curPeriod ) then return end
   lastT = curT
   --
   work()
   --
   curPeriod = curPeriod - periodDelta
   if( curPeriod < minPeriod ) then     
      if( resetOnMin ) then
         curPeriod = maxPeriod 
      else
         curPeriod = minPeriod
      end
   end
end; Runtime:addEventListener( "enterFrame", enterFrame )


[TOPIC: post.html]
#5

roaminggamer

[GLOBAL: userInfoPane.html]
roaminggamer
  • Corona Geek

  • 6,981 posts
  • Corona SDK

And a timer variant:
 
local proxy = {}

proxy.resetOnMin = true
proxy.maxPeriod  = 5000
proxy.minPeriod  = 60
proxy.periodDelta = 100
proxy.curPeriod = maxPeriod

local function work()
   print("Period: " .. tostring(proxy.curPeriod) .. " @ " .. tostring(system.getTimer()) )
end

function proxy.timer( self )
   work()
   --
   self.curPeriod = self.curPeriod - self.periodDelta
   --
   if( self.curPeriod < self.minPeriod ) then     
      if( self.resetOnMin ) then
         self.curPeriod = self.maxPeriod 
      else
         self.curPeriod = self.minPeriod
      end
   end
   timer.performWithDelay( self.curPeriod, self )

end; timer.performWithDelay( proxy.curPeriod, proxy )

Edited by roaminggamer, 08 July 2018 - 09:55 PM.


[TOPIC: post.html]
#6

darkelgameman

[GLOBAL: userInfoPane.html]
darkelgameman
  • Observer

  • 2 posts
  • Corona SDK

Thank you both so much for the help! I've been waiting a month to get this project done, I had a great idea and I couldn't finish this without the loop. 




[topic_controls]
[/topic_controls]