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
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.
The form itself has a size, but the area where objects are drawn is stored in the form's ScaleWidth and ScaleHeight properties.
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, newtopwill cause the image to move so its upper left corner is at the position given by the values of newleft and newtop.
t = Timerit produces the current time in seconds since midnight. So you can compute an elapsed time like this:
starttime = Timer ' do some computing elapsed = Timer - starttimeYou 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 - starttimeand so on. The time returned by the Timer function is a value of type Single, measured in seconds.
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.)
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.
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.
Your program should do the following:
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.
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
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 = FalseAdd 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.
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.
Sub moveitVB 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
moveitto 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
Beepto Image1_Click; this will make a noise when the image is clicked.
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 ...
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.
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.)
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.
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.
You can make sure that you have saved the proper files on your Unix account:
Log in to arizona.princeton.edu and look to make sure that the
files are there and appear to be correct. On arizona, the command
If you've completed the lab, sent your email to cs109@princeton.edu
or cs111@princeton.edu and transferred your work to your Unix account,
then you are finished.
Submitting your work
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.