|
This project is in two parts - follow the above the link to access the
second part. In this project you will learn about:
 | the PictureBox control |
 | animation using the Timer control |
 | the Visual Basic coordinate system |
 | nesting |
 | variables |
 | declaring variables |
This project will show a picture of an Apollo lunar lander vehicle above the
surface of the moon. The objective will be to use rocket thrusters (controlled
by command buttons) to guide the lunar lander onto a small landing pad on the
lunar surface.
Create a new project (File/New Project), making sure you specify a Standard EXE project. Save the project immediately with File/Save
Project (not Ctrl-S, for that only saves the form file). Create a new folder
called Lander to hold the various parts of the project, then save the form file
and the project file, both with the same name as the folder. Don't forget to
save your work every 10 minutes or so (you CAN use Ctrl-S for this).
Looking at the toolbox at the left of the VB window, you will notice that there are two controls that are designed to
hold pictures, the PictureBox control
and the Image control . Which one
should we choose? It's almost always better to choose the PictureBox control,
for it has many advantages over the Image control. The only big advantages of the
Image control is that it can have a transparent background and that it can be
stretched (if the stretch property is set to true).
Add a PictureBox control and a Timer control
to the form and set the properties to:
 | Form:
 | caption = Lunar Lander by (YOUR NAME HERE) |
 | backcolor = black (use the palette of colors rather than the system
colors) |
 | width = 8000 |
 | height = 7000
|
|
 | PictureBox (put it somewhere towards the top left corner of the form):
 | name = picLander |
 | picture: either right-click, copy and then paste the image into the PictureBox
OR, if that does not work, right-click the picture, save it into your lander
folder, then choose the picture property of the picture box, click the
ellipsis (...) and select the picture that you just saved.
|
 | appearance = flat |
 | autosize = true
|
|
 | Timer control:
 | name = tmr1 |
 | interval = 100 |
|
It doesn't matter where you put the Timer control, for it will become
invisible when the program is run. Think of the Timer control as like an egg
timer - it can be set to go off after a certain period of time and when it does
go off its code is activated. Unlike an egg timer, the Timer control goes off
repeatedly, at regular intervals. The interval property of the Timer control is
measured in milliseconds or thousandths of a second. Here the interval
has been set to 100 milliseconds, or 0.1 seconds. This means that the timer
control will 'go off' ten times every second. Each time the Timer goes off, its
code will move the picture into a new position and since it goes off so often,
the motion should seem quite smooth (compare it to your television, which shows
you 25 pictures every second and seems VERY smooth).
You might be thinking that
a shorter interval might give even smoother motion - that's true but it might
not be a good idea because it might cause your program to behave differently on
a fast computer and a slow one (ask me why if you are interested).
How can we make the lander picture move to the right? You must understand the
Visual Basic Coordinate system before you can answer that question. Unlike in
your math class, where x and y coordinates are measured to the right and
then up, Visual Basic coordinates are measured to the right and then down,
using the properties left and top as shown in the diagram below (your form should be black but I have made mine gray so that you can see the
other details clearly).

This might be a good time to mention that Visual Basic does not
usually use units such as cm, mm, inches or even pixels. Instead, Mr. Gates has
invented a special unit for us called the 'twip'! A twip is defined as 1/1440 inch - not an easy number to remember! The
good thing about this unit is that it is a very small distance, so we never have
to work with fractions of a twip. Since this unit is small, a movement of 50
twips to the right would be quite modest, as we shall see...
In order to make the picturebox move to the right, we must
increase the value of the picLander.Left property. Double click the Timer
control and type this code:
Private Sub tmr1_Timer()
picLander.Left = picLander.Left + 50
End Sub
When you run the program, you should see the PictureBox control move smoothly
towards the right. The middle line of code is taking the existing value of
picLander.left, then adding 50 to it, then storing the result in PicLander.Left
so that this property gets a new value. The overall effect is that each
time this line is run the 'left' property is increased (or 'incremented') by 50.
If you need more reminders about how the assignment operator '=' works then look
back to the calculator project.
How would you make the picture go left instead of right? You might
think you could do this by changing the 'left' property in the code into
its opposite - a property called 'right', but unfortunately there is no
such property (VB doesn't need such a property because knowing the 'left'
property is enough to determine where the control is located horizonatally
on the form). So if you can't use a property called 'right' what else
could you change in the code to make the picture move in the opposite
direction? TRY IT! Also try changing the code so that picture moves faster or
slower. Then try changing the code so that the
picture moves down the form instead of horizontally. When you are satisfied that
you understand how the code works, change it back to the code above.
You have made a program that makes the lander move, but the program is not
yet interactive - all we can do while the program is running is watch. Now we
will add some command buttons to allow us control the thruster rockets that
will push the lander in different directions.
You probably noticed that when you changed the number 50 in the above code to
a bigger number, the speed of the lander increased, thus this number is
equivalent to the speed of the lander. We would like the speed of the lander to
be variable, so we will replace the value 50 with a variable called vx
(meaning
velocity in the x direction). You have met variables already in your math class,
so you know that a variable is like a container. In Visual Basic, variables can
contain numbers, text strings, dates etc. So change the code now so that it
looks like this:
Private Sub tmr1_Timer()
picLander.Left = picLander.Left + vx
End Sub
Now add two command buttons so that we can control the horizontal motion of
the lander (we will tackle the vertical motion later). Set the captions and
names as shown here. Your form should be much bigger than this, and black rather
than gray.

The cmdRight button should increase the speed of the lander to
the right, so double-click it and type:
Private Sub cmdRight_Click()
vx = vx + 20
End Sub
The middle line will add 20 to the existing value of vx, then
store the result back in vx.
The cmdLeft button should decrease the speed to the right
so double-click it and type:
Private Sub cmdLeft_Click()
vx = vx - 20
End Sub
If clicking this button causes vx to become negative, that
simply means the lander will move to the left rather than to the right.
Now try running the program and using the command buttons to
move the lander - nothing happens!! What went wrong? The answer is important,
but not obvious. The reason that the program does not work as expected is that
Visual Basic has created three different variables called vx, one for
each control. Therefore when we click a command button we may be changing the vx
variable that belongs to the command button, but we are not changing the vx
variable that belongs to the Timer control and therefore the timer code does not
make the picturebox move. The solution? Tell the computer to create a single
variable vx which is to be shared throughout the program. To do this create a
new blank line above all the existing code in the code window and type
into the blank line. This line 'declares' the variable vx (Dim
is short for dimension.) Note that we are typing code outside any subroutine
(not between wrappers) - this is only allowed in special situations such as this
one.
Try running the program now and you should find that it works
very nicely - we have realistic control over the lander's horizontal motion.
Now for the vertical motion - should we add a command button for
an upward thruster and another for a downward thruster? Because you are so
smart, you will have realized that a real lander would not have a downward
thruster, since the moon's gravity already provides a downward force. So add a
single command button for the upward thruster, as shown:

This thruster should change the vertical speed, which is
described by the variable vy, but should the button add to vy or subtract
from it?? Since VB measures down rather than up, vy is the downward
speed, and an upward pushing thruster will subtract from the downward speed. Make
the following changes to the code:
Dim vx, vy
Private Sub cmdLeft_Click()
vx = vx - 20
End Sub
Private Sub cmdRight_Click()
vx = vx + 20
End Sub
Private Sub cmdUp_Click()
vy = vy - 20
End Sub
Private Sub tmr1_Timer()
picLander.Left = picLander.Left + vx
picLander.Top = picLander.Top + vy
End Sub
The program should work just fine, except that we have not yet
added the moon's gravity so we can make the lander move up but cannot bring it
back down again.
How exactly should we add gravity to the program? Should we make
another command button, so that gravity pulls on the lander each time we click
the button? That would be wrong, for gravity acts on the lander continuously.
This means that every time the timer control goes off the moon's gravity will
have caused the lander's vertical speed to change, so we must add the 'gravity
code' to the code for the timer. Change the timer code like this:
Private Sub tmr1_Timer()
picLander.Left = picLander.Left + vx
picLander.Top = picLander.Top + vy
vy = vy + 3
End Sub
so that each time the timer goes off the downward speed, vy,
increases by 3 (we don't want to increase it by a big number since this number
is going to be added to vy ten times every second). Now run the program, and
enjoy flying the lander in all directions in a very realistic fashion. If you
have successfully got this far... WELL DONE!
The lander project is nearly finished now - we can fly the
lander, but we can't land it... we have no moon to land on! Click HERE
to move to the next lesson and see how this can be done.
|