This is just one of many beginners tutorials available for Dark Basic by TDK_Man. They were primarily written for DB Classic users, but because they start at such a very low level and cater for complete newcomers to programming, the vast majority of them apply equally to DBPro users as well. You can find all of them here:
Dark Basic Tutorials For Complete Beginners
** TDK_Man's Timer Tutorial **
One subject you often see questions about on forums is that of timers. These may be for showing an on-screen display of either time left or time elapsed, though timers have many other uses.
This tutorial will show the seasoned DB user nothing new, but is instead aimed at the new programmer and looks at the way timers work and how they can be used in your programs. Feel free to copy any of the code in this tutorial into DB and run it.
TDK_Man
Timer Tutorial
All PC's have built-in timers which place values into registers for programmers to access. DB has a function called Timer() which accesses the computers timer register and returns values in one thousandths of a second increments.
To convert these values to seconds, we simply have to divide them by 1000. If you need finer timings than one second intervals, then you can divide by 100, 10 or not divide by anything at all to return 10th, 100th and 1000th of a second increments respectively.
The value can obviously be stored in a variable, so if for example, you use:
RetVal=Timer()
...then the current value of the PC's timer is stored in the variable RetVal.
This value can then be used for a multitude of tasks including calling procedures after a set amount of time (as a way to make your programs run the same speed on all spec machines), on-screen clocks & timers or any other timed events in your programs, (maybe it goes dark after playing for an hour, or a plane flies overhead every 15 minutes).
You are also not restricted to a single timer either. You can have as many independent timers as you like in your programs by using different variables. For example:
T1=Timer()
T2=Timer()
T3=Timer()
Will give you three timers which can be used for timing three separate events.
Copy and paste the following code into DB and run it:
Set Text Opaque
Do
Text 0,0,Str$(Timer())
Loop
The value you see is the contents of the timer register and it is continually changing, and fast! - even when your program is not running! This value is not a lot of use, so modify the code as shown below.
Set Text Opaque
Do
Text 0,0,Str$(Timer()/1000)
Loop
Now the value changes, but ticks over at a more useful once per second. It's still not totally useful as it will display a random value on every machine. To fix this, we need to grab this value into a variable and deduct it from the value of every subsequent use of Timer(). The result is a second counter that starts at 0 (zero):
Set Text Opaque
T=Timer()
Do
Text 0,0,Str$((Timer()-T)/1000)
Loop
ELAPSED TIME
To create an 'elapsed time' display, the basic programming procedure is as follows:
1. Grab the current value of Timer() into a 'start time' variable
2. In a loop, read updated values of Timer() into a 'current time' variable
3. Subtract the 'start time' value from the 'current time' value
4. Divide the result by 1000 to give the number of seconds elapsed.
In DB, the code for a 30 second timer would look something like this:
Rem Simple 30 Second Clock
Set Text Opaque
Ink RGB(255,255,255),0
T=Timer()
Repeat
Elapsed=(Timer()-T)/1000
Text 0,0,Str$(Elapsed)+" "
Until Elapsed=30: Rem change this value to alter the length of the timer
In your own programs, 'T=Timer()' is placed just before entering your main program loop and the line 'Elapsed=(Timer()-T)/1000' is placed somewhere inside your main loop with an If Elapsed= clause immediately following it:
Rem Continuous Seconds Counter
T=Timer()
Do: Rem Main Program Loop
Elapsed=(Timer()-T)/1000
If Elapsed=60
Inc MinutesPassed: Rem Or do whatever you need to do in your program
Elapsed=0
T=Timer()
Endif
Rem The rest of your main loop program here
Loop
Basically, this program counts the number of elapsed seconds in the variable 'Elapsed' and then checks to see if that value equals 60 (1 minute). If it does, the timer goes back to zero and continues indefinitely.
When the timer hits 60 seconds, (or whatever value you set), then what your program does is up to you. In the above example, the variable MinutesPassed is incremented - effectively counting the number of minutes elapsed. The program could then be set do do something specific when MinutesPassed equals a specific number of minutes.
Your program could just as easily call a function or subroutine when Elapsed reaches a given value.
Once the target value has been reached and the required task completed, you need to reset the timer. So, in our example above, we set the variable Elapsed to equal zero.
The next part of the program is the bit that most new programmers trip up with:
Having reset the variable Elapsed to zero, the formula 'Elapsed=(Timer()-T)/1000' is still using the original start value stored in 'T' and will therefore continue calculating the elapsed time from when the program was first run.
So, the start value variable needs updating with a new start time. We do this by putting another T=Timer() line inside the If 'Elapsed=' block of code. The value of Elapsed will then calculate the number of seconds elapsed from this point instead of the old one - ie from zero again.
COUNTING TIME DOWN
Counting down is essentially the same as counting up, so if say you want to give the user of your program a set amount of time to complete a task, then a slightly modified version of the first example is all that is required:
Rem Simple 30 Second Countdown Timer
Set Text Opaque
Ink RGB(255,255,255),0
Seconds=30: Rem change this value to alter the length of the timer
T=Timer()
Repeat
Elapsed=(Timer()-T)/1000
TimeLeft=Seconds-Elapsed
Text 0,0,Str$(TimeLeft)+" "
Until TimeLeft=0
The only differences in this example are the use of a variable called Seconds which contains the number of seconds to count down and the line 'TimeLeft=Seconds-Elapsed' which subtracts the elapsed time from the number of seconds in the level, placing the result in the variable 'TimeLeft'.
For example, when 10 seconds have elapsed, TimeLeft equals 30-10, or 20 seconds. When Timeleft gets to zero then the example program ends.
A PROPER CLOCK DISPLAY
If you want a digital clock display, then it really is quite simple and only needs a single timer.
Rem Digital Clock Example
Set Text Opaque
T=Timer()
Do: Rem Main Program Loop
Seconds=(Timer()-T)/1000
If Seconds>=60
Inc Minutes
If Minutes>=60
Inc Hours
If Hours>=24
Hours=0
Endif
Minutes=0
Endif
Seconds=0
T=Timer()
Endif
Hrs$=Str$(Hours)
If Hours<10 Then Hrs$="0"+Hrs$
Min$=Str$(Minutes)
If Minutes<10 Then Min$="0"+Min$
Sec$=Str$(Seconds)
If Seconds<10 Then Sec$="0"+Sec$
Text 0,0,Hrs$+":"+Min$+":"+Sec$+" "
Loop
In this example, the timer is used simply to get the seconds elapsed. When the value of the variable 'seconds' hits 60, it is reset to zero and the variable 'minutes' is incremented. In the same way, when 'minutes' hits 60, it too is reset to zero and 'hours' is incremented. 'Hours' is reset to zero when it hits 24 (not 60) as there are 24 hours in the day.
The rest of the program converts the numeric variables to strings with STR$() and formats the strings with a leading "0" if less than 10. The time is then printed to the screen.
If you have been able to follow the examples in this tutorial, you should have a good working knowledge of how timers work and can go away and implement your own ideas using Timer().
There are many more tutorials and example code snippets on TGPF - my game programming forums. Click on the link below - it's free to join and everyone's welcome!
Visit TDK_Man's Forums: TGPF
TDK_Man