Lab 6: More Visual Basic and User Interfaces

Sat Nov 10 09:04:11 EST 2001

By the end of this lab, you will:

You will also discover more ways to make errors and stumble over mystifying behaviors. Don't get too frustrated! Ask a lab assistant for advice, take a short break, and try again. Please make sure that you understand and have followed the instructions for submitting your work, and that you have safely saved your work in a permanent place as well in case something goes wrong. Check with the lab assistants!

The game you wrote in the previous lab was quite static and purely textual: nothing happened until the user typed a number into a TextBox, and the only satisfaction was the dubious intellectual one of using binary search. This lab will build a game that is much less cerebral (if that's the right word in this context), and much more graphical and interactive. It's a rudimentary version of "shoot 'em up" games like Doom or Quake, though the real inspiration is my favorite arcade game, Whack a Mole; in honor of that, let's call the game WhaM.

In WhaM, an image (in my case, of a small prairie dog like the one at the top of this page) jumps randomly around the screen. Your job is to hit the image with the mouse as fast as you can; after ten hits, your elapsed time is reported, and you get a chance to play again.

To make this work, you will use several components and library subroutines that you have not used before:

You are welcome to use the prairie dog above, or any other image that you like. (The picture on my web page is about the right size, for example.)

No prairie dogs were harmed in the making of this lab.

Part 1: Visual Basic components you will use
Part 2: Writing your own program
Part 3: Finishing up and Shutting down

Part 1: Visual Basic Components You Will Use

Images and the Image Control

The Image control is one of two controls in VB that display images -- pictures, diagrams, etc. -- on a form. The Image control is somewhat simpler and faster than the PictureBox, and also a bit more flexible, so we will use it here.

There are several ways to cause an image to appear. The easiest is to add it to the form at design time. Select Image from the toolbox at the left of the screen ; sweep out a rectangle on the form where you want the image to appear. Select Picture from the Image properties. This will display None, followed by "...". If you select the "...", you can browse for a file to use as the image.

The Image control will handle a variety of image encodings. For this lab, you will probably want to use either a GIF file or a JPG file, since these are the kind found on web pages. The prairie dog is a JPG file.

Sizes and Positions

Every object on a form has a size, measured in "screen units" of 1/1440 inch; these values are stored in the Width and Height properties. The position of the upper left corner of each object is stored in its Left and Top properties.

The form itself has a size, but the area where objects are drawn is stored in the form's ScaleWidth and ScaleHeight properties.

Moving an Image

The Image control has the first object we've seen that has a method that causes it to do something; heretofore, we've only affected objects by changing their properties. But for an Image (and most controls), you can change its position on the screen as your program runs by a Move statement that specifies new Left and Top values. The VB statement

	Image1.Move newleft, newtop
will cause the image to move so its upper left corner is at the position given by the values of newleft and newtop.

The Timer Function

One part of this lab is to time the user to see how long it takes to whack ten prairie dogs. That is done with a VB function called Timer. Each time you call Timer, in a statement like this:
	t = Timer
it produces the current time in seconds since midnight. So you can compute an elapsed time like this:
	starttime = Timer
	' do some computing
	elapsed = Timer - starttime
You can experiment with this in the Immediate window by typing
	starttime = Timer
	(now wait a bit)
	print Timer - starttime
	(now wait a bit)
	print Timer - starttime
and so on. The time returned by the Timer function is a value of type Single, measured in seconds.

The Timer Control

VB also provides a control, confusingly called Timer but unrelated to the Timer function, that is used to cause a computation to be done over and over at a specified time interval. You will use a Timer control in WhaM to cause the dog to move to a new position every second or so.

To use a Timer control, you must first draw it on the form, by selecting it from the toolbox , and drawing it on the form. It has a fixed size and shape; you can't change that. And it doesn't matter where you place it, since it will be invisible when your program starts to run.

A Timer control has only one interesting property, its Interval, and only one event, confusingly called Timer! The Interval is measured in milliseconds, so if you set the Interval property to 1000 for a timer Timer1, the event subroutine Timer1_Timer will be called once a second. So your program will cause the dog to move by putting the right code into Sub Timer1_Timer. You can change the Interval as the program is running. (If the Interval is set to zero, the timer never fires.)

The OptionButton Control

OptionButton controls are used in groups, to select at most one choice out of several. An OptionButton can be either True or False; at most one in a group can be True. We will use two OptionButtons here to let the user decide who or what to whack. An selected (that is, True) OptionButton looks like this on a Form:

All the OptionButtons that you draw this way are linked, so that at most one of them can be true. If you want independent groups of options, you have to put each group inside a Frame; that's not needed in this lab.

Part 2: Writing Your Own Program

Your assignment

Your assignment is to implement a version of WhaM. Our version looks like this before it starts; the two pictures and the Timer will disappear when the program starts to run.

You can make yours look more professional if you wish, once you have it working properly, by laying out the components anywhere and using any sizes, fonts, and colors that you like.

What your program should do

Your program should do the following:

Draw the Interface

Each component of the user interface has a name in the VB program; yours doesn't have to look like the one above but it has to use the same names.

At this point, your interface should look similar to the one shown above. You must use these names for components so the lab assistants can help you and so we can grade.

Using the icons in the toolbox area on the left side of the VB window, draw the components above on the Form called Form1. As you draw each one, immediately change its name to the corresponding name given above by editing the Name field in the Properties window on the right side of the VB window.

Change the Caption fields of the Labels, OptionButtones, and Button.

Finally, change the Caption property of Form1 to something that includes your name.

Saving your work

There's a fair amount of work in this lab, and you don't want to lose it. So you should save your work every few minutes, especially after you make significant changes or additions. Choose File / Save Project As.... You will offered the chance to save Form1.frm; save it as Wham.frm on your H: drive. Similarly, save Form1.frx as Wham.frx and Project1.vbp as Wham.vbp. (The .frx and .vbp files are just text and you can look at them with Notepad.) You can then restart this at some later time by opening the .vbp file with File / Open Project....

Add the Statements for the Program

Program statements are placed in the Code window, which is often hiding behind the Form window. You can switch back and forth between Code and Form using the entries under the View menu item. You can also freely edit anything in the Code window, especially to delete unwanted items and blank lines. Your entire program is there, though you may have to scroll up and down to see it.

You will need a variable to hold the number of hits that the user has managed to get. Since this value will be needed by at least two subroutines of your program, it must be declared at the beginning of your program, before any of the Sub definitions. Go to the code window and type this line:

	Dim hits As Integer

Start Button

Now you can start to add functionality. First, make the Start button work. Go to the Code window and select start from the drop-down list at the top left; this will create a template for subroutine start_Click:

    Sub start_Click()

    End Sub

You can make an object invisible by assigning False to its Visible property, as in

	Logo.Visible = False
Add statements to start_Click to make the logo, the two OptionButtones, and the Start button itself disappear when the Start button is pushed. Test the program so far.

Choosing the Desired Image

Now add statements to start_Click to display the image that the user selected; that's the one whose OptionButton is True. If OptionButton1 is true, you don't need to do anything. But if OptionButton2 is true instead, you need to assign Image2 to Image1 (in effect overriding the prairie dog picture). So you need an If statement to test whether OptionButton2 is true, and assign Image2 to Image1 if it is.

Now the desired image is in Image1, but you still have to make that Visible or it won't appear.

When you have written this much, test it: it should display the selected picture when the Start button is pushed.

New Random Positions

You have to move the image every time the user successfully hits it with the mouse, and also when the timer fires. So it's best to write a subroutine that does the move operation and call it from those two places. Create a subroutine called moveit; if you start typing
    Sub moveit
VB will create a tempate for you to fill in. Add the following line to that subroutine:
    Image1.Move Rnd * (ScaleWidth - Image1.Width), Rnd * (ScaleHeight - Image1.Height)
The built-in function Rnd produces a different (pseudo-)random number between 0 and 1 each time it is called. This line creates new random Left and Top coordinates and moves the image to that place. Instead of using the whole width and height of the screen, we've reduced them by the width and height of the image itself so the image stays entirely on the screen.

You need to add statements to the subroutine Image1_Click to make the image move when the mouse is clicked on it. First add the line

to Image1_Click and verify that the image moves to a random place each time you click it.

Then add a moveit to Timer1_Timer. Now the image should move around each time you click on it, and also once per second if you don't touch it. Test this part of the program. You might find it helpful to add the statement

to Image1_Click; this will make a noise when the image is clicked.

Counting Hits

Now you can go on to the real logic of the program, which is to count the number of hits, and display a MsgBox when it gets to ten. Your task now is to fill in the last few lines of Image1_Click to increment the number of hits and do the test. When hits gets to 10, display the right message in a MsgBox, and then either terminate the program or play again, depending on the user's response.

This will require an If statement to compare the number of hits to 10, and another If to check the response from MsgBox. MsgBox returns a value that indicates which button was pushed; we didn't use that feature before, but here we have to include Yes and No buttons ("Another game?"). If you say

	MsgBox("...", vbYesNo)
MsgBox will create a dialog box with Yes and No buttons, then return vbYes if the Yes button is pushed, and vbNo if the No button is pushed. This lets you write the If statements that will decide whether to play another game or quit, depending on the user's response; for example
	If MsgBox("...", vbYesNo) = vbNo Then

Update the Elapsed Time

Finally, add the statements to start_Click to initialize the hit count and elapsed time when the Start button is pushed, and to Image1_Click to to include the value in the MsgBox when the game is over. You will need to declare a variable starttime to store the initial time; it should be of type Single.

It is sufficient to restart the game with the image that was chosen originally; if you want, you can offer the user a choice of images each time a new game is played, but this is more complicated.

Good Programming Habits

Even though this is your second Visual Basic program you are still liable to make mistakes. Write small sections at a time, and test as you go, as we have been suggesting above.

Use MsgBox statements to display results as your computation proceeds, or just to verify that your program is going where you think it is. These are easy to add and help narrow down problems quickly.

Add comments to your code to remind yourself of what some statement is doing, and perhaps to help the grader figure out what you had in mind as well. You can also "comment out" MsgBox statements by sticking a comment marker at the beginning of the line; this leaves the code there for future use but it doesn't affect the program until you uncomment it.

You should indent your code the way it has been shown in class, and the way it appears in the Help system. Indenting the statements between Sub and End Sub and If and End If helps you see quickly what's included in a subroutine or a condition; you should always maintain consistent indentation. (VB could do it for you, but it does only a tiny bit.)

Part 3: Finishing up and shutting down

This is basically the same as what you did for the previous VB lab, but with different file names. Please be careful this time too.

Copy your files to your Unix Account

You will first be offered the chance to save Form1.frm, which contains your VB Form1 objects and code.

You may next be offered the chance to save the file that contains your Images, which has the extension Form1.frx, though it usually happens automatically when you save the .frm file. If this is offered,

You will next be offered the chance to save the VB project itself in Project1.vbp.

wham.frm and wham.vbp are ordinary text files that you can look at and even change with Notepad.

Submitting your work

It is a very good idea to check with one of the lab assistants to make sure that they have seen your project in its working state, that your files have been properly saved in your Unix account, and that you are sending the right files for grading. Mail the files to yourself as well and be sure that they have arrived safely. Do all of these before you quit VB and log out.
Every year, several people lose all of their work because they have not followed these instructions or heeded these warnings. Please don't be one of this year's victims!

You can make sure that you have saved the proper files on your Unix account: Log in to and look to make sure that the files are there and appear to be correct. On arizona, the command

	ls -l
will list the contents of your directory; the file names, sizes, and dates ought to look something like this:
	-rw-r--r--   1 yourname student      5432 Oct 20 19:19 wham.frm
	-rw-r--r--   1 yourname student     23145 Oct 20 19:19 wham.frx
	-rw-r--r--   1 yourname student      1234 Oct 20 19:19 wham.vbp
You can also print the contents of .frm and .vbp files to see whether they look right; the command
	cat wham.frm
will print the file wham.frm; it should contain your VB code along with some other material. If it doesn't look right, check with a lab assistant before leaving the lab. Finally, you can mail the lab to yourself before you mail it to cs109 or cs111; this will help verify that you are mailing the right material. The should have different sizes, and the .frm file is generally quite a bit bigger than the .vbp file.

If you've completed the lab, sent your email to or and transferred your work to your Unix account, then you are finished.