Lua timers

Started by
8 comments, last by Roots 12 years, 11 months ago
I thought I posted this yesterday, but I guess something happened.

I'm trying to start a timer when a touch event happens, then stop after a pre set amount of time. The app I'm making goes like this:




local randomButton = display.newCircle(250, 350, 80)
randomButton:setFillColor(200, 0, 0)

timesTouched = 0
timeLimit = 1
touchTimer = 0

local function touchCount()
timesTouched = timesTouched + 1
print("Touched " .. tostring(timesTouched) .. " times")
end


local function randomColor(event)
if (timesTouched < 1) then
touchTimer = timer.performWithDelay (0, touchCount, 1)
end

if (touchTimer.count == (timeLimit * 1000)) then
print("The button has been touched " .. timesTouched .. " in " .. tostring(timeLimit) ..
" seconds")
end


end

randomButton:addEventListener ( "touch", randomColor)




I didn't want to give out almost all my code, but I figure if I didn't you wouldn't know what I was talking about or trying to do. So how do I get the timer to stop after ten seconds, then print a line telling me how many times I touched the button in 10 seconds? I'd really appreciate the help. I've been looking up the API and some Tutorials but nothing touches on my exact situation.
Advertisement
Some new info, even though I have recieved no answers thus far, I found on another site that you can make new timers using timerName = timer.new(), but that didn't work. It seems like the right syntax but the terminal gives me an error.

Not to be rude, but can someone please give me a quick answer? I've been wracking my brain trying to figure out how to do it and what's the right syntax for 3 hours.
Hmm Lua doesn't have any native timer object like what your expecting. You want some sort of tasked based global timer which updates things on a timeline. The line ..

touchTimer = timer.performWithDelay (0, touchCount, 1)

Would indicate that there is a global object called timer and one of its functions is to register a functor to execute with a given delay.. Why isn't that object functioning don't know.. It's global and probably somewhere in the main loop of the script or externally called from C it's updated each frame and that is how timed functions execute within your framework. Track down that object and see why it's not executing its registered functors..

Good Luck!

-ddn
I've figured out this much.

The first time the my object is touched, I need to start the timer, which I do with


timesTouched = 0
markTime = 0
timepassed = os.time() - markTime

local function buttonTouched(event)

if (timesTouched <= 0) then
markTime = os.time()

end

end

I need the timer to stop after 10 seconds, so I put



if timepassed == 10 then


Then that's where I kinda get lost. I've got a start time and an stop time, but I don't know when or how to get the timer to stop. I know that the stop must be called outside the touch event. But I don't know how to get it to check the time without a loop that stops after 1 run through or causing an infinite loop. Does this help clarify anything?
From the looks of it, your using an event driven system. Such systems don't do polling on states, they just respond to events externally. Such as a touch event in your case. The user triggers the event and the function randomColor() is called. (original code). It then creates a timed function callback ( timer.performWithDelay (0, touchCount, 1) ). This callback scheme is very common in Lua, since functions are first class objects they can be passed much like how variables are in other languages. The function touchCount is passed onto a global timer object which somewhere you have to find does periodic processing, probably once a frame.

Within this timers update loop it will then go through each registered callback and execute ones which have meet their timeout conditions. Which is when touchCount is called. Normally timer objects discard the functor once they've been executed unless they support multiple execution etc..

The logic in randomColor btw doesn't make much sense.. but that's something for you to work out. So randomColor will only be called when the user touches the object and that won't be predictable at all. So you cant check for time within randomColor and expect it to work correctly since it could be 1 sec between touches or 10 minutes.. Using event driven programming, you would emit a timed callback like what the codes does and handle the processing then.

If say you wanted to count the number of touches within a 10 sec span where the the first touch initiates the clock something like this would work..


local function printNumberTouches()
print("Touched " .. tostring(timesTouched) .. " times")
end


local function onTouch(event)

--only add this callback once
if (timesTouched ==0) then
--just assuming that 3rd param is the delay time ( so 10 secs in this case )
touchTimer = timer.performWithDelay (0, printNumberTouches, 10)
end

--add up all touches to this object
timesTouched=timesTouched+1;
end

randomButton:addEventListener ( "touch", onTouch)


and that should do it..

Good Luck!

-ddn
I tried your method, but it didn't work. It just printed out "Touched 1 times" ten times. I know that in timer.performWithDelay the 1st param is how long before the 2nd parm executes, and the 3rd param is how many times to execute the 2nd param.

I understood what you said about it being event driven though, so I had a kind of revelation. I could create the whole program within a loop that keeps comparing one time to another until the difference between them is 10. I actually started typing this post up when I thought of it, looked around and experimented and then came back to right this post. I couldn't quite figure out. So is there anyone who could help me do that? Of course, any other solution to my problem would be welcomed as well.
I need the timer to stop after 10 seconds, so I put


[color="#000088"]if timepassed [color="#666600"]== [color="#006666"]10 [color="#000088"]then
So if the time goes from 9.9 to 10.001 the conditional is never met.
"It's like naming him Asskicker Monstertrucktits O'Ninja" -Khaiy

I made some changes and tried to get it to work again, but there is still a problem, here's the code:


markTime = 0
timePassed = os.time() - markTime
timesTouched = 0
cycles = 0

local randomButton = display.newCircle(250, 350, 80)
randomButton:setFillColor(200, 0, 0)



function gameCycle()

if markTime - timePassed >= 10 then
printResult()
cycles = cycles + 1
end

function printTimes()
print(tostring(markTime) .. " " .. tostring(timePassed))
end

local function printResult()
print("Touched " .. tostring(timesTouched) .. " times")
end

local function onTouch(event)

printTimes()

if (timesTouched == 0) then
markTime = os.time()
end

timesTouched = timesTouched + 1

randomColor()

--if (timesTouched >= 1) then
--while cycles ~= 1 do gameCycle() end
--end

printTimes()
end

function randomColor()

randomButton:setFillColor (math.random(255) , math.random(255), math.random(255))
randomButton.x = math.random(300)
randomButton.y = math.random(800)
end

randomButton:addEventListener ( "touch", randomColor)

printTimes()

end

gameCycle()
--printTimes()



If I try to loop the gameCycle() with a repeat or while, it repeats infinitely and the game never actually starts. I want it to keep checking if the timer has stopped, but if I don't have a loop I can't keep checking it.

BTW, the printTimes() was my way of trying to get it to tell me the markTime and passedTime every time the circle is touched, but it doesn't want to work right.
You have to fill out the function [color=#000000][font=CourierNew, monospace][size=2]timer[/font][color=#666600][font=CourierNew, monospace][size=2].[/font][font="CourierNew, monospace"]performWithDelay with the proper parameters. The method I laid out will work but you need to determine what that function wants. I was taking a stab at what they meant, apparently the 3rd param is number of times to execute the callback, and i suspect the first param is the delay time. This is something you have to figure out. The idea is this..[/font]
[font="CourierNew, monospace"]
[/font]
[font="CourierNew, monospace"]-Register Touch event callback[/font]
[font="CourierNew, monospace"][/font][font=CourierNew, monospace][size=2]-When touch callback is executed, start up a timed callback using [/font][color=#1C2837][font=CourierNew, monospace][size=2][color=#000000]timer[color=#666600].[color=#000000]performWithDelay with 10 sec delay, only do this once, in the mean time keep counting touches[/font]
[color=#1C2837][font=CourierNew, monospace][size=2][color=#000000][/font][font=CourierNew, monospace][size=2]-When the timed callback executes print the number of touches. [/font]
[font=CourierNew, monospace][size=2]
[/font]
[font=CourierNew, monospace][size=2]The logic is sound and simple, but i can't guess at your APIs, you need to dig deeper and get a handle on your own interfaces. [/font]
[font=CourierNew, monospace][size=2]
[/font]
[font=CourierNew, monospace][size=2]Good Luck![/font]
[font=CourierNew, monospace][size=2]
[/font]
[font=CourierNew, monospace][size=2]-ddn [/font]

I need the timer to stop after 10 seconds, so I put


[color="#000088"]if timepassed [color="#666600"]== [color="#006666"]10 [color="#000088"]then
So if the time goes from 9.9 to 10.001 the conditional is never met.


So check: if (timepassed >= 10).


System timing is not as precise as you or I would like them to be due to practical limitations. Furthermore, even if they were ultra-precise the time it takes to get through one update/draw loop of your application is variable, so you still couldn't depend on stopping at an exact value. If you are trying to check for or stop on a precise time value, you're most likely not understanding what goes on underneath the code.

Hero of Allacrost - A free, open-source 2D RPG in development.
Latest release June, 2015 - GameDev annoucement

This topic is closed to new replies.

Advertisement