Your form should look like this:

We must make sure that the user cannot anticipate the timing of the event that will trigger his
or her reaction, so we will make the user wait for a random time between 3 and 7
seconds for the event to occur. Since you have already completed the Random
Number project, you should understand that a random decimal number between
3 and 7 can be generated with 3 + 4 * rnd().
We could use a Timer control to make the computer wait for this time, but
instead we will use the Timer() function. This is very different to the
Timer control - it is a function that simply returns the number of seconds
that have elapsed since midnight. For example, if you use the Timer()
function at one minute past midnight then it will return the number 60. This
function doesn't sound very useful, but it is useful in many programs, as we
shall see...
First, double-click the command button and type this code:
Run the program, click the button a few times, and notice how the numbers are
large, as you would expect, and how they increase a little between clicks.
Now let's get the reaction timer going. Set the command
button's BackColor property to
bright red and change its Style property to graphical (so that we can see the
BackColor)

Then change its code to
Private Sub cmdReact_Click()
waittime = 3 + 4 * Rnd()
endtime = Timer() + waittime
Do Until Timer() >= endtime
' Do nothing
Loop
Print waittime
End Sub
When you run this program and click the command button it should
make you wait a few seconds and then tell you how long you had to wait. Try
to understand the code!
This is the first time we have used a loop in any
of our programs. Loops are a very important part of any programming language -
they allow a block of code to be repeated many times. In some cases the
programmer knows in advance how many times the loop should be repeated, and
would probably use a "For...Next" loop. In this case, we don
not know how many times the loop will repeat, so we use a "Do...Loop".
The program repeats all the lines of code between the Do line and the Loop
line until the condition in the Do line is met (the condition can also be put in
the Loop line). In this case, the condition is that the Timer() function returns
a number greater than or equal to endtime. (The endtime was calculated by adding the
starting time and the waittime, a random number between
3 and 7). The only code inside our loop is a line that actually does nothing,
for it is a comment. A comment is any code on any line that comes
after an apostrophe (unless the apostrophe is itself part of a text string,
i.e. between double quotes). In the following line, the computer will ignore the
code that comes after the second apostrophe:
MsgBox ("This ISN'T a comment") ' This IS a comment
Note how VB makes comments easy to spot by coloring them green.
What is the point of including code that we know the computer will ignore? To
make the program easier to understand for anyone trying to read the code (this
includes us, in a few months time, when we have forgotten how the program
works!). It is a very good habit to include plenty of comments in all your
programs.
To help make our programs easier to read, we indent all the
lines inside a loop by putting a tab character at the beginning of each line,
just as we do for IF structures.
Now I'll give you all the code for a working reaction
timer. Type this very carefully, or you will have some difficult
debugging to do. Underneath is an explanation - note that this code uses a Select
Case structure, which is an alternative to an IF structure.
Private Sub Form_Load()
Randomize
End Sub
Private Sub cmdReact_Click()
Static endtime
Select Case cmdReact.Caption
Case "Click me to start"
cmdReact.Caption = "Wait"
cmdReact.BackColor = vbYellow
endtime = Timer() + 3 + 4 * Rnd()
Do Until Timer() >= endtime
DoEvents
Loop
cmdReact.Caption = "Click me NOW!"
cmdReact.BackColor = vbGreen
Case "Click me NOW!"
Print Timer() - endtime
cmdReact.Caption = "Click me to start"
cmdReact.BackColor = vbRed
End Select
End Sub
The most important feature of the above code is the Select
Case structure. This works by examining a certain expression and then
matching it to different possible 'cases' - it's a good alternative to an IF
structure when there are more than two cases to test for (it would be very
possible to write this code using an IF structure if we wanted to). In our
program the Select Case line takes a look at the caption of the command button,
which can have one of two values (there will be three later on). If the caption
is "Click me to start" then this will match the first Case line, so
the following lines of code will be activated, and so on. The Select Case
structure ends with End Select, just like an IF structure ends with End If.
Also, the code for the various cases should be indented, again like in an IF
structure.
To understand the function of DoEvents in the above code,
try temporarily removing it or making it into a comment by putting an
apostrophe in front of it. Now the command button does not turn yellow when it
should because the computer is so busy doing the loop that it has no time for
anything else. DoEvents is an instruction to do anything that is
waiting to be done (the re-drawing of the button with its new color, in this
case).
In the code above, you noticed that VB understands certain
constants such as vbRed and vbYellow - it doesn't have built-in constants for all
colors, but it does understand the primary colors (vbRed, vbGreen, vbBlue), the
secondary colors (vbYellow, vbMagenta, vbCyan), and also vbWhite and vbBlack.
The Static Endtime line declares the variable endtime in
a way that you haven't seen before. Since this variable occurs only in one
procedure there is no need to declare it in the General Declarations area at the
top of the code window, but if we don't declare it at all then it will forget
its value between successive clicks of the command button. By making the
variable into a static variable we make sure that the variable does not forget
its own contents.
Your program should work quite well, but it has a weakness...
it's quite easy to cheat by repeatedly clicking the button very fast while it
displays the "Wait" caption. We must do something to catch the cheats!
Add another Case, as shown below:
Private Sub cmdReact_Click()
Static endtime
Select Case cmdReact.Caption
Case "Click me to start"
cmdReact.Caption = "Wait"
cmdReact.BackColor = vbYellow
endtime = Timer() + 3 + 4 * Rnd()
Do Until (Timer() >= endtime)
DoEvents
Loop
cmdReact.Caption = "Click me NOW!"
cmdReact.BackColor = vbGreen
Case "Click me NOW!"
Print Timer() - endtime
cmdReact.Caption = "Click me to start"
cmdReact.BackColor = vbRed
Case "Wait"
Print "You cheated!"
End Select
End Sub
This new case is activated if the user clicks the button while
it has the caption "Wait". This happens while the loop is still
running so the 'Click me now message' still appears as normal.
Your program is working really well now (if you followed my
instructions carefully!). Can you think of ways of making it even better... for
EXTRA CREDIT... Here are some suggestions: