Countdown timer

BlitzMax Forums/BlitzMax Programming/Countdown timer

Hi all

i am trying to create a countdown timer, it is only to work in seconds, i've tried various methods such as timers, to grabbing the millisecs and using mod 1000, none of which seem to work, anyone able to help me out on this one, give me a brief over view of how to get a countdown working???

many thanks

Quick and dirty example.
Strict

Graphics 640,480

Global timer:ttimer = CreateTimer(1)
Global secsRemaining:Int = 10


While (Not KeyDown(key_escape)) And secsRemaining > 0
	Cls
	DrawText "Time Left: " + secsRemaining,10,10
	Flip
	secsRemaining:-WaitTimer(timer)

Wend

End

Note: WaitTimer() halts execution until it can return a non-zero value. If you don't want that to happen then you can have the timer tick more often than once a second (see CreateTimer(1)), or:
Strict

Graphics 640,480

Global timer:ttimer = CreateTimer(1)
Global secsRemaining:Int = 10


While (Not KeyDown(key_escape)) And secsRemaining > 0
	Cls
	DrawText "Time Left: " + secsRemaining,10,10
	DrawText MilliSecs(),10,30 'to prove its redrawing the screen
	Flip
	If timer.ticks() > 0
		secsRemaining:-timer.ticks()
		timer._ticks = 0
	EndIf
Wend

End


Legend

Close to what i had, but far enough off that yours actually works :-)

thanks Gfk

*edit, will this slow down a game, waiting for a timer to tick?
*thanks, you beat me to it, lol

Hi, I'm using something like this in my apps:

SuperStrict

Type TCountDown
	Global Timer:TTimer = CreateTimer(100) 
	
	Field Time:Int 'Time in millisecs
	Field BackTime:Int
	
	Method New()
		AddHook EmitEventHook,DownHook,Self
	End Method
	
	Function Create:TCountDown(Time:Int = 10000) 
		Local C:TCountDown = New TCountDown
		C.Time = Time
		C.BackTime = Time
		Return C
	End Function
	
	Function DownHook:Object( id:Int , data:Object , context:Object )
		Local CD:TCountDown = TCountDown(context) 
		If CD <> Null Then
			CD.Update() 
		End If
		Return data
	End Function 

	
	Method Update() 
		BackTime:- 10
		If BackTime < 0 Then BackTime = 0
	End Method
	
	Method GetTime:Int() 
		Return BackTime
	End Method
	
	Method GetSeconds:Float() 
		Return Float(BackTime) / 1000
	End Method
	
	Method Reset() 
		BackTime = Time
	End Method
	
End Type


Graphics 800,600,0,-1
	
Local CD:TCountDown[10]
For Local I:Int = 0 To 9
	CD[I] = TCountDown.Create(Rand(5000 , 20000) ) 
Next


While Not KeyHit(KEY_ESCAPE) 
	Cls
		For Local I:Int = 0 To 9
			DrawText CD[I].GetSeconds() + " : " + CD[I].GetTime() , 20 , 20 + I * 20
			If CD[I].GetTime() = 0 Then CD[I].Reset()
		Next
	Flip
Wend


The main advantage of this is you don't have to worry about the update.

Thats brilliant,

I had wrapped the first example into a working type, but had to call an update manually each frame, this works great.

thanks

	Function DownHook:Object( id:Int , data:Object , context:Object )
		Local CD:TCountDown = TCountDown(context) 
		If CD <> Null Then
			CD.Update() 
		End If
		Return data
	End Function 


should be

	Function DownHook:Object( id:Int , data:Object , context:Object )
		Local CD:TCountDown = TCountDown(context) 
		If CD <> Null And TEvent(data).Source = TCountdown.Timer Then
			CD.Update() 
		End If
		Return data
	End Function 


Otherwise each emitted event will potentially count down the timers. But with this you make sure that only the TCountdown.Timer event will be handled.

Surely all you need to do is very simply:

1) Store the current Millisecs/1000 into a StartTime variable when you start the countdown

2) Calculate TimeElapsed=(Millisecs/1000)-StartTime

3) Calculate countdown with SecondsToWait-TimeElapsed