Lander
Up Lander 2

This project is in two parts - follow the above the link to access the second part. In this project you will learn about:

bulletthe PictureBox control
bulletanimation using the Timer control
bulletthe Visual Basic coordinate system
bulletnesting
bulletvariables
bulletdeclaring 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:

bulletForm:
bulletcaption = Lunar Lander by (YOUR NAME HERE)
bulletbackcolor = black (use the palette of colors rather than the system colors)
bulletwidth = 8000
bulletheight = 7000

bulletPictureBox (put it somewhere towards the top left corner of the form):
bulletname =  picLander
bulletpicture: 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.
                                            
bulletappearance = flat
bulletautosize = true

bulletTimer control:
bulletname = tmr1
bulletinterval = 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

Dim vx

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.

 

Lander 2

Previous Up Next