Exercise 9: Lunar Lander
You can't learn programming with Mr. Ward without
making a lunar lander! We will make a project in which an image (a
real photo of the Apollo 11 lander that first carried humans to the
moon) 'flies' realistically, being pulled down by the moon's gravity
and pushed up and sideways by rocket thrusters (you can see the
finished simulation at the bottom of this page). Ultimately we will
extend the program until we can carefully land the lander on a
special 'landing pad'. Please do all the steps and don't just jump
to the end - you will learn much more if you don't skip anything!
Part 1
In this part we will import the images we need and
write very simple scripts to handle the horizontal motion of
the lander. We will deal with the horizontal motion and the vertical
motion separately since they are quite different - the vertical
motion is affected by gravity and the horizontal motion is not.
Copy this image into your personal folder then
import into the stage background (NOT a sprite costume). To import
into the stage background click the 'stage' icon in the bottom right
corner of Scratch then click 'backgrounds ' a the top of the scripts
area then click 'Import'. You can delete the white background since
we will not be using it.

This picture is a bit less wide than the stage so
you will probably need to open it in the image editor and click the
'Grow' button
(not the zoom
scale) to make it cover the stage.
Also import the following image (the Apollo 11
lander) as a sprite (copy it to your folder then
hit the 'Choose new sprite from file' button
and import it. Change the name of
the new sprite to 'lander'. Delete the cat sprite (right-click it
and choose 'delete').
Now we are ready to make the sprite move. We will
use a variable called 'vx' to represent the velocity (speed)
in the 'x' (horizontal) direction and later we will add a 'vy'
variable for the vertical velocity. For the moment, just create a
variable called 'vx'.
As in the previous projects, we will use a 'forever
loop' which continuously makes the lander do little 'jumps'.
Each jump goes a number of steps equal to the speed variable, so the
bigger the variable the bigger the jump. In this case only the x
value (the horizontal position of the sprite will be affected, so
the lander will only move right (if vx is positive), or left
(if vx is negative).
Check out these scripts:

When we press the right arrow key the value of vx
is increased by 0.4. When we press the left arrow key the value of
vx is decreased by 0.4 (or increased by -0.4,
of you prefer). Why 0.4? Because I've tried changing this number and
0.4 seems to work well on my home computer. I'm a bit worried though
that the loop might run at different speeds on different computers -
I wouldn't really want the lander to accelerate faster just because
it's being used on a faster computer. I don't know Scratch well
enough yet to know whether this is really a problem. Try changing
the numbers if you like.
When the green flag is clicked then a forever loop
is launched which simply changes (over and over again) the x value
(horizontal position) of the lander sprite by adding vx to
it.
If you add the above scripts to the lander sprite
(not to the stage, of course) then you should be able to make the
lander accelerate left and right as if being pushed by blasts from
the side thrusters.
Part 2
In the next step we will add the vertical motion.
That's a bit more complicated because the moon's gravity is present,
continually changing the vertical velocity vy. Let's choose
to make the upwards direction the positive y
direction. Therefore the upward-pushing rocket thruster should make vy
bigger (more positive) but the gravity should subtract from vy. The good news about the vertical motion is that we don't
need to think about the lander being pushed down by a
thruster - no downward-pushing thruster is needed because the
downward force of gravity is always present.
So make a new variable 'vy' and then change
the scripts of the lander sprite as shown:

The only differences are that
With the new scripts in place, you should be able to
fly your lander around in a realistic way, complete with gravity!
Part 3
Now we will add blocks to detect a landing with the
lunar surface.

Three of these five scripts are completely unchanged
but we have a new script to handle the 'reset' message and the green
flag script on the left has a few extra lines.
Look at the green flag script. The important lines
that change x, y and vy are still there but now
they are inside an 'if ... else ... ' structure so that x,
y and vy are only changed IF the condition in
the 'if' block is met. That condition is that the vertical (y)
position of the lander must be greater (more positive) than -170. Remember that on
the bottom edge of the stage y is equal to -180, so a value
of -170 is a little higher than the bottom edge of the stage.
If the 'if' condition is not met (because the
lander has gone too close to the bottom of the stage) then the
'change x' and 'change y' blocks no longer run. Instead the
'else' part activates and a message is displayed for 3 seconds,
after which a 'reset' message is broadcast to the other scripts.
The 'reset' message is handled by a separate
script that simply puts the lander back in the top left corner of
the stage and sets the horizontal and vertical velocities back to
zero. I put these blocks in a separate script to keep the main
(green flag) script as simple and clear as possible. It would also
have been possible to put those three lines directly in the green
flag script rather than using a broadcast message.
If you carefully set up the scripts as shown then
everything should work fine... except for one little detail. You
will probably notice that the lander hits the bottom of the stage
before the message appears. We want the message to appear when the
feet of the lander reach y=-170 but the program assumes so
far that the position of lander is the position of the centre of the
lander. So we need to tell the program to use the position of the
lander's foot, not its centre. To do that, make sure the lander
sprite is selected in the bottom right corner of Scratch, then click
the 'costumes' tab, then the 'Edit' button. Click the 'Set costume
center' button
then click at the level of the bottom of the feet of the lander,
halfway between the left edge of the lander and its right edge. Once you have made that change the lander should
stop a short distance above the bottom edge of the stage.
Part 4
In this part we will add the landing pad and
then check whether the lander has landed correctly on the central
part of the pad. Click on 'Paint New Sprite' to create a new sprite
in the Paint Editor. Make a red and yellow rectangular shape like that in the
animation below. Make sure that the red part of the pad is just slightly wider than
the lander itself. By controlling how much wider the red part is than the
lander you can control the difficulty of landing successfully. The height of the pad shape doesn't matter much. Place the
'costume center' at the centre of the top surface of the pad.
Let's take a look at the scripts I used (they are
all attached to the lander sprite - the other sprite and the stage
have no scripts).

Look at the green flag script. First it
broadcasts a 'reset' message to the corresponding script which sets
the position and both velocities of the lander to their starting
values. Then a
'forever' loop continually checks whether the bottom of the
lander is higher than the top of the pad (remember how we placed the
'rotation centres' carefully?). If this is the case then the
horizontal and vertical positions are adjusted as in part 3 and 0.01
is deducted from the upwards velocity vy, as in part 3.
If the lander is NOT above the pad then we know the
lander has landed, but did it land in the right place? This is
checked by the second 'If... then... else' structure, which
is the most important new addition to this project. For a good
landing the lander sprite must be touching the red part of the
landing pad but must not be touching the yellow part (ask yourself
why the yellow part needs to be so wide).
My image above also shows a 'PostIt' note (comment)
that I put in to help people understand my program. It's very
important to 'document' your programs in this way because in a
professional context it is very likely that someone else will want
to modify your program one day and that person will need help to
understand how your program works. You can add comments anywhere in
the scripts area by right-clicking and choosing 'add comment'.
Part 5
The simulation below uses a sprite with text on it
to launch the game. Text works well enough in Scratch except that
you can only have one block of text on each sprite or background and
there is no option of centering text (I cheated a bit). Add such a
sprite-with-text to your own project.
The main improvement in the simulation below is that it
uses a fuel variable. This is initially set to 25 but every time you
use a rocket thruster you use up one unit of fuel. When there is
no fuel left the thrusters no longer work, just as would be the case in
a real lander. Try to add such a fuel variable to your own lander
and improve this project in other original ways. If you think this
lander simulation is too easy then reduce the fuel allowance. You
could offer different levels of difficulty with different levels of
fuel, or different gravity. And don't forget to add some sound
effects, of course!