Countdown Timer

I’m using the code snippet

os.difftime(90, ElapsedTime) 

to countdown in my game. The problem with this is that it’s starting as soon as I start my game. I need it to start as soon I choose the “time trial” game mode. Any help?

What I do is use a variable to mark the time the user starts the game, usually by using startTime = ElapsedTime.

Then, whenever I want to know how long it’s been since the start, I can take ElapsedTime - startTime.

Or you can use another state machine to determine whether the timer should be on or off.

@veeeralp

See the small timer class I created under the discussion Timer that was started August 1st. I don’t know if that’s exactly what you want, but it might be a start.

I need the timer to countdown from 90 when the time trial game is selected. Right now it’s starting as soon as I run the app. Is there any other function to determine how much time has past besides ElapsedTime. I really need some help here

When you start your time trial game mode, capture the current value of ElapsedTime. For example:

function timeTrialStarted()
    -- Capture the start time
    startTime = ElapsedTime

    -- Other code
end

function update()
    -- Compute how much time has passed since time trial started
    local currentTime = ElapsedTime - startTime

    if currentTime > 90 then
        endTimeTrial()
    end
end

function endTimeTrial()
    -- Ends the time trial
end

(Your functions might be completely different, I just made up some function names to illustrate the procedure.)

ok @Simeon I tried it out. This is working perfectly in my game but there is one problem. How will I be able to display the currentTime counting down. right now it’s counting up to 90 seconds and then the game ends. Also, i use physics.pause and physics.resume to pause the physics objects in my game when the pause button is pressed. Is there a similar function like time.resume and time.pause or would I have to create my own function. Thanks!

I updated my last post

Just a little math will solve the problem…

text(90 - currentTime, 100, 100)

Of course, you’ll need to position and size the text where you need it.

thanks @Mark. I used

os.difftime(90,currentTime) 

to save some fps.
also, do you know how I would enable the time to pause and resume when the pause button is pressed.

Here is a timer class with an example of 3 countdown timers. Add the code you want when the timer reaches 0. I currently just have print statements.


-- timer class and an example of 3 countdown timers

function setup()

    --displayMode(FULLSCREEN)
    supportedOrientations(PORTRAIT)
    a=Timer(200,600,100,50)    -- set x, y position of timer button
    b=Timer(200,500,100,50)
    c=Timer(200,400,100,50)
end

function draw()
    background(40, 40, 50)
    text("Example of 3 countdown timers",WIDTH/2,940)
    text("Press red button to start, it turns green when running",WIDTH/2,900)
    text("Press green button to pause, it turns yellow",WIDTH/2,860)
    text("Press yellow button to continue, it turns green",WIDTH/2,820)
    text("Double tap button to reset to 0, it turns red",WIDTH/2,780)
    
    if a:showTimer() then    -- show timer and check for 0
        print("timer a reached 0")    -- add code here for 0 
    end
    
    if b:showTimer() then
        print("timer b reached 0")
    end
    
    if c:showTimer() then
        print("timer c reached 0")
    end
end

function touched(t)
    if t.state==BEGAN then
        if a:touched(t) then    -- check if button pressed
            a:startTimer(20)    -- set countdown time
        end
        
        if b:touched(t) then
            b:startTimer(30)
        end
        
        if c:touched(t) then
            c:startTimer(40)
        end        
    end
end

Timer = class()

function Timer:init(x,y)    -- initialize timer values
    self.x=x
    self.y=y
    self.w=100
    self.h=50
    self.timer=0  
    self.xx=0
    self.pause=0
    self.color=color(255,0,0,100)
end

function Timer:showTimer()
    local str
    local tmr
    if self.pause>1 then    -- timer paused
        str="Start"
        tmr=self.pause
        self.color=color(229, 251, 9, 200)
    elseif self.timer > 0 then    -- timer is running
        str="Pause"
        self.color=color(0, 255, 0, 100)
        tmr=math.ceil(self.xx - (ElapsedTime-self.timer))
        if tmr==0 then
            self.timer=0
            return true    -- timer reached 0
        end
    else -- timer was reset
        str="Start"
        self.color=color(255,0,0,100)
        tmr=0
    end
    
    pushMatrix()
    fill(self.color)
    rectMode(CENTER)
    rect(self.x,self.y,self.w,self.h)
    fill(255)
    tmr=string.format("%3d %s",tmr,str)
    text(tmr,self.x,self.y)  
    popMatrix() 
    
    return false   -- timer is running or was reset  
end

function Timer:startTimer(val)
    if self.pause>0 then
        self.xx=(ElapsedTime-self.timer)+self.pause
        self.pause=0
    elseif self.timer>0 then
        self.pause=math.ceil(self.xx - (ElapsedTime-self.timer))        
    else
        self.xx=val
        self.timer=ElapsedTime  
    end  
end

function Timer:pauseTimer()
    self.pause=math.ceil(self.xx - (ElapsedTime-self.timer))
end

function Timer:touched(t)
    if t.state==BEGAN then    -- screen was touched
        if t.x>self.x - self.w/2 and t.x<self.x+ self.w/2 and
            t.y>self.y-self.h/2 and t.y<self.y+self.h/2 then
                if t.tapCount==2 then    -- 2 taps, reset timer
                    self.timer=0
                    self.pause=0
                    return false
                end
        return true    -- button pressed
        end
    end
    return false    -- no button pressed
end

nevermin @Simeon I figured it out. I used what you taught me about capturing the ElapsedTime and subtracting it from the currentTime. You’re a great developer.

.@dave1707 and @Simeon I’m using your way of capturing the time elapsed when the pause button and resume button are tapped. The problem with this is that the difference between the two stays the same when you press the button twice. For example, when I press the pause button at 5 seconds and the resume button at 8 seconds. The difference between them is 3. So as usual, I would subtract these from the currentTime. What happens when I press the pause and resume button another time. Is there any way I could detect wether I went back to my pause state and then to my run state and then to my pause state again and tell the program to figure out the ElapsedTime again. Sorry if I’m acting crazy, it’s 2 AM here and this problem has kept me up. I really am confused

@veeeralp

I’ve read your comment several times, but I’m not sure what you’re after. In my example program above, if you start one of the countdown timers, say the 40 second timer, it doesn’t matter how many times you pause and start it, the calculated run time of the timer is still 40 seconds when it reaches 0. The amount of any of the pauses is taken care of in the ElapsedTime calculations so the calculated running time of the timer is what you start it out at. Could you re-phrase your question. For example, it you start the 40 second timer and pause it when it reaches 32 for 10 sec, start it again, pause it when it reaches 20 for 5 sec, start it again and let it run to 0. The run time of the timer is 40 seconds, but the total elapsed time is 55 seconds ( 40 sec for the timer and 15 sec for pauses).

.@dave1707 here’s how I’m using a timer in my game.

function timetrialButtonPressed()
   startTime = ElapsedTime
   
   supportedOrientations(ANY)

   -- Initialise the parameters which determine difficulty
   -- Namely: number of mines and the grid size
   obj=physics.body(CIRCLE,25)
   obj.x=497.253
   obj.y=500
   
   obj.restitution=0.60
   obj.sleepingAllowed=false
   gameDifficulty = statetimetrial

   resetGameParameters()

end

function HowToPlayButtonPressed()  
    gameState = stateHowToPlay
end
function pauseButtonPressed()
    pauseTime = ElapsedTime
    gameState = statePause
    physics.pause()
end
function resumeButtonPressed()
    pauseTime2 = ElapsedTime
    physics.resume()
    gameState = stateRun
end

and then I’m drawing the time

                timeinPause = pauseTime2 - pauseTime
                local currentTime = ElapsedTime - startTime - timeinPause
                if currentTime > 10 then
                    gameState=stateGameOverTT
                    sound(SOUND_EXPLODE, 40989)
                end       
                timeLeft=os.difftime(10,currentTime)
                text("Stars Collected: "..targetsCollected,0,HEIGHT -30)
                text("Time Left: "..timeLeft,0,HEIGHT -60)

in the second section of code I subtract pauseTime2 and pauseTime to get timeinPause. I then subtract this to the current time. The pause feature works flawlessly if u press the pause button once and go back to the resume state, but it messes up when the press the pause and resume button a second time because the timeinPause is the same as the previous. Hope you see now where I’m getting at, I explained it horrendously yesterday. Hope you can help. My timer is like the once the @Simeon coded

@veeeralp

I don’t have time to look a what you have coded, I have someplace I have to be, but you probably need to accumulate your paused times. It works with the first pause because that’s the amount you have saved. When you do your second pause, your saving that amount but loosing the amount from the first pause. I’ll look at it more when I get back unless you figure it out first.

@veeeralp

Looking at the code you posted, it looks like you’re not accumulating the pauses. Try changing the line timeinPause = pauseTime2 - pauseTime to timeinPause = timeinPause + pauseTime2 - pauseTime. That should accumulate all the pauses. You’ll also have to 0 out timeinPause before you start the game or when the game is over if you go right into another round.

@dace1707 I tried doing what you said and once u press the resume button again. The whole timer messes up and starts counting up rapidly. I’m not sure what us doing this, I tried putting timeinPause = timeinPause - pauseTime2 - pauseTime and it starts counting down. I’m putting this in my draw function if it helps

@veeeralp

Sorry, I didn’t realize that code was in the draw function even though you said it was. That line of code was being executed constantly, so the timeinPause value was increasing constantly. Try moving the line of code timeinPause = timeinPause + pauseTime2 - pauseTime as the last line in the function resumeButtonPressed(). That way, timeinPause will be updated only when the program is resumed.