Mark Cunningham - Game Programming With Code Angel - Learn How To Code in Python On Raspberry Pi or PC PDF
Mark Cunningham - Game Programming With Code Angel - Learn How To Code in Python On Raspberry Pi or PC PDF
Game
Programming
with Code Angel
Learn how to code in Python on
Raspberry Pi or PC
—
Mark Cunningham
Game Programming
with Code Angel
Learn how to code in Python
on Raspberry Pi or PC
Mark Cunningham
Game Programming with Code Angel: Learn how to code in Python on
Raspberry Pi or PC
Mark Cunningham
Edinburgh, Scotland
Chapter 1: Introduction������������������������������������������������������������������������1
Coding a game������������������������������������������������������������������������������������������������������3
Python and Pygame����������������������������������������������������������������������������������������������4
Choosing an IDE����������������������������������������������������������������������������������������������������4
Python IDLE�����������������������������������������������������������������������������������������������������4
Thonny�������������������������������������������������������������������������������������������������������������5
PyCharm Edu���������������������������������������������������������������������������������������������������5
Bugs and debugging���������������������������������������������������������������������������������������������5
Common mistakes������������������������������������������������������������������������������������������������6
Indentation������������������������������������������������������������������������������������������������������6
Variable and function names���������������������������������������������������������������������������7
Case�����������������������������������������������������������������������������������������������������������������7
Brackets and quotes����������������������������������������������������������������������������������������7
Missing colons�������������������������������������������������������������������������������������������������8
Comments�������������������������������������������������������������������������������������������������������������8
Time to get started…�������������������������������������������������������������������������������������������8
v
Table of Contents
vi
Table of Contents
vii
Table of Contents
viii
Table of Contents
ix
Table of Contents
Step 8: Scoreboard�������������������������������������������������������������������������������������������167
Fixed loops��������������������������������������������������������������������������������������������������������169
Display the scoreboard�������������������������������������������������������������������������������������170
Wrapping up������������������������������������������������������������������������������������������������������171
Index�������������������������������������������������������������������������������������������������173
x
About the Author
Mark Cunningham is the founder of Code Angel and a Computing
Science teacher with over 20 years experience teaching in Scotland.
Working with high school students, Mark has learned which coding
concepts new coders find difficult to understand, learn, and master. He has
recognized that students want to learn to code by writing programs which
will motivate and engage them. His work with Code Angel has allowed
him to take his teaching beyond the classroom and reach a much wider
audience online. Mark is also the co-founder of Hashtag Learning who
develop online resources for schools.
xi
About the Technical Reviewer
Massimo Nardone has more than 22 years of experiences in Security,
Web/Mobile Development, Cloud, and IT Architecture. His true IT
passions are Security and Android.
He has been programming and teaching how to program with Android,
Perl, PHP, Java, VB, Python, C/C++, and MySQL for more than 20 years.
He holds a Master of Science in Computing Science from the
University of Salerno, Italy.
He has worked as a Project Manager, Software Engineer, Research
Engineer, Chief Security Architect, Information Security Manager, PCI/
SCADA Auditor, and Senior Lead IT Security/Cloud/SCADA Architect for
many years.
His technical skills include Security, Android, Cloud, Java, MySQL,
Drupal, Cobol, Perl, Web and Mobile Development, MongoDB, D3,
Joomla, Couchbase, C/C++, WebGL, Python, Pro Rails, Django CMS, Jekyll,
Scratch, and so on.
He currently works as Chief Information Security Officer (CISO) for
Cargotec Oyj.
He worked as Visiting Lecturer and Supervisor for exercises at the
Networking Laboratory of the Helsinki University of Technology (Aalto
University). He holds four international patents (PKI, SIP, SAML, and Proxy
areas).
Massimo has reviewed more than 40 IT books for different publishing
companies, and he is the coauthor of Pro Android Games (Apress, 2015).
xiii
CHAPTER 1
Introduction
Welcome to Python game programming with Code Angel. In this book, you
will write the Python program code required to build four amazing games,
learning how to code as you go along.
The four games you will make are shown in the following.
Figure 1-1 shows the Forest Bomber game.
2
Chapter 1 Introduction
C
oding a game
Each game is built up steadily over several chapters. Take your time
working through each chapter, adding the program code as instructed.
New concepts will be explained as they are introduced.
As you finish each game, you should run your program to check that
it works as expected. If it doesn't, don't worry. It's quite common for a
program to contain errors which are known as bugs. If your program has
a bug, carefully compare your code with the code from this book and try
to spot any differences. Missing out just one single character or typing a
character in the wrong place can prevent a program from running.
Have fun playing your finished game or impress your friends by letting
them play the game that you have programmed!
3
Chapter 1 Introduction
P
ython and Pygame
In order to run any of the code in this book, you will need to install
the Python programming language on your computer. This is a fairly
straightforward process. Follow the installation instructions on the Python
web site: www.python.org.
Once you have installed Python, you need to install the Pygame library
which extends Python and provides many of the functions required to
make games. Visit the web site for information on how to download and
install Pygame: www.pygame.org.
Both Python and Pygame are open source and completely free.
C
hoosing an IDE
Now that you have installed Python and Pygame, you are ready to begin
coding. You are probably wondering where to actually type your Python code.
The best way to do this is by using an IDE. IDE stands for integrated
development environment. It's what programmers use to enter, run, and
debug their code.
There are lots of different IDEs to choose from. At Code Angel, we
recommend one of the following IDEs to get you started. They are all free
and available for Windows, MacOS, and Linux.
P
ython IDLE
Pros: Installed with Python, fine for small projects
Cons: Basic, limited debugging, not great for larger projects
Rating 3/5
4
Chapter 1 Introduction
Thonny
Pros: Easy to use
Cons: Not as polished as PyCharm
Rating 4/5
Windows, Mac, or Linux
PyCharm Edu
Pros: Works well for large projects
Cons: More complex interface and menu options, steep learning curve
Installation: Needs Pygame to be added under Settings ➤ Project
Interpreter
Rating 5/5
Once you install whichever IDE you think best meets your needs, you
are ready to start coding.
Bugs and debugging
A bug is simply an error in a computer program. Bugs are so called
because early computers were very large and insects would get inside the
system and cause a short circuit. Nowadays, a bug refers to program code
which contains an error.
A bug may cause a program to crash or prevent it from working in
the way that was expected. Debugging means finding and fixing bugs in
program code.
When a program crashes, it may display an error message. Sometimes
the message can be difficult to understand. The most important thing to
note is the line number at which the error occurred. Find the line number
in your program, and compare it very closely with the same line of code
from this book. Look for any differences. Your program code must be
5
Chapter 1 Introduction
exactly the same as the code from the book. Also check that the lines
above and below the reported line number are correct.
A logic error is an error which causes a program to run incorrectly but
does not necessarily cause the program to crash. Because there is no error
message, logic errors can be difficult to find.
With logic errors, you need to work out where in the program code
the error might be. For example, imagine a game where the objective is
to shoot a spaceship. Each time that the player hits the spaceship, they
should have ten points added to their score. However, you find when
running the game that ten points are subtracted each time a spaceship is
hit. This would be an example of a logic error.
This logic error must have occurred when the program updated the
game score. It is likely that a minus sign has been used instead of a plus
sign, and that is what has caused the error. The game will not actually
crash, but the player will soon get fed up losing points every time they hit
a spaceship!
Common mistakes
While bugs can be caused in many different ways, there are some common
mistakes you should look out for.
Indentation
In Python, indentation levels are very important. Indentation errors can
cause a program to crash or not work correctly. Each level of indentation
should be either four spaces or a single tab.
while True:
⎵⎵⎵⎵for event in pygame.event.get():
⎵⎵⎵⎵⎵⎵⎵⎵key_pressed = pygame.key.get_pressed()
6
Chapter 1 Introduction
Make sure that you carefully check indentation levels as you enter new
lines of code.
score ✓
csore ×
plane_exploded ✓
plane exploded ×
Case
Python is case sensitive. This applies to Python commands, as well as
function and variable names.
So in a Python program, score, Score, and SCORE are three completely
different things.
Brackets and quotes
Brackets and quotes come in pairs.
If there is an opening bracket, there must also be a closing bracket
()
The same applies to quotes
“ ” or ‘ ’
7
Chapter 1 Introduction
Missing colons
if statements, for statements, def function declarations, and class
definitions all end in a colon. It’s common for beginners to miss the colon
out by mistake – if you are getting an error, make sure that the colon is not
missing.
Comments
A comment is a note or explanation included in the program code.
In Python, comments begin with the # hash symbol and will often be
displayed in a different color by the IDE.
Comments are ignored by the computer when the program is being run.
All of the programs in this book include comments to help explain what the
program code is doing. These comments don’t affect the program and so do
not actually have to be entered, but it is good practice to include them.
8
CHAPTER 2
G
etting started
We have an idea for a game, Forest Bomber. In Forest Bomber, an airplane
is running out of fuel and has to land safely at the bottom of the screen.
However, there are trees in the forest which will cause the plane to explode
if it crashes into one. So the pilot of the plane – our player – has to try and
bomb the trees to clear a landing strip.
OK, so we have an idea for a game, and it seems simple enough. That’s
a good start. Now what?
Before we even begin writing any of the Forest Bomber code, we need
to design the game in more detail by taking the idea and breaking it down
into smaller steps, covered here and in Chapters 3 to 5 as follows:
I’ve split the steps over four chapters so we could gradually build up
the game. The first two steps might seem a little odd, but the remaining
seven steps should make some sense.
By the end of step 4, we will have designed and coded the layout for the
first level of Forest Bomber.
Let’s begin by sketching out how the game screen will look (Figure 2-1).
The plane should start in the top left-hand area of the screen, and the forest,
which the player must clear in order to land, will run along the bottom of
the screen. As this will be the first level, we will start with four trees in the
forest, but the number of trees will increase in each level making the game
progressively more difficult.
10
Chapter 2 Forest Bomber part 1: A first level
11
Chapter 2 Forest Bomber part 1: A first level
We won’t worry too much about the code at this stage, but if you want
to know more, the following explains what it does:
• Lines 1–3 are called comments. They are ignored by
the computer.
• Lines 5–8 tell the computer that we are going to use
some additional Python code which has to be imported.
• Lines 11–15 are some of the colors we will be using later
in the program.
• Lines 18–32 set up some values which will be used
throughout the program. For example, SCREEN_
WIDTH and SCREEN_HEIGHT will be used to draw the
actual game screen at 640 × 480 pixels, TREE_SPACING
will be used to keep a 40-pixel space between each of
the trees, and PLANE_START_Y will be used to start the
plane 54 pixels down from the top of the screen.
12
Chapter 2 Forest Bomber part 1: A first level
Again, enter the lines of code shown in code listing 2 in Figure 2-3.
S
core and lives
We will begin by gaining an understanding of variables. A variable stores a
piece of information or data to be used in a program. Think of a variable as
being like a box. Each variable must have its own unique name.
13
Chapter 2 Forest Bomber part 1: A first level
We will also need to keep track of the game level. Again, we use a
variable, but this time we will call it level and initialize it with 1, because
the game will begin at level 1 (Figure 2-5).
14
Chapter 2 Forest Bomber part 1: A first level
Variables can store different types of data. Our score and level variables
are both integers. An integer is a whole number which can be positive,
negative, or zero.
Enter the code to initialize all of the game variables, as shown in code
listing 3 in Figure 2-6.
15
Chapter 2 Forest Bomber part 1: A first level
Key learning A variable is like a box which can store some data or
information. Each variable has its own unique name and is initialized
as follows:
score = 0
lives = 1
Figures 2-7 to 2-10 show how the four forests are stored as lists and
how each list is then mapped to a tree drawn on the screen. We will learn
later in this chapter how we actually draw the trees.
16
Chapter 2 Forest Bomber part 1: A first level
Notice that as we move from forest 1 through to forest 4, there are more
trees. This is so that each level is harder than the one before. If you wish,
you can customize Forest Bomber by changing the combination of ‘T’s and
‘-’s in the list to change the formation of trees in a level (although probably
best not to do that just yet).
17
Chapter 2 Forest Bomber part 1: A first level
Notice that line 94 and lines 102–105 are indented (which means
they are spaced in from the left of the page). Also notice that line 97 has
a double indent, and lines 98–99 have three levels of indentation. Python
is very specific about each level of indentation. Each level of indentation
should be exactly four spaces (or one tab).
Let’s take a closer look at line 102.
This is the line of code which draws our game background. It uses
the blit command to display the background image in the top left-hand
corner of the game window. The background image itself is 640 × 480
pixels which is exactly the same size as the Forest Bomber window, so it
fits in place perfectly.
Pygame uses a coordinate system to draw graphics on screen, and the
point (0,0) is in the upper left-hand corner as can be seen in Figure 2-12.
18
Chapter 2 Forest Bomber part 1: A first level
There are a couple of other things to note about the way in which the
background image is displayed by line 102:
Now it’s time to test our program. Run Forest Bomber, and if you have
entered the code correctly, the background image should be displayed.
If you get an error, carefully check that all code has been entered correctly.
Even the slightest mistake will cause the program to not run.
19
Chapter 2 Forest Bomber part 1: A first level
Some lines of code listing 5 in Figure 2-13 are quite complicated, and
so the techniques used will be picked up later in the book.
For now, we will concentrate on lines 106–108 because they actually
draw the trees in our forest.
20
Chapter 2 Forest Bomber part 1: A first level
When column is 0:
tree.x = FIRST_TREE + column ∗ TREE_SPACING
= 140 + 0 ∗ 40
= 140
When column is 1:
tree.x = FIRST_TREE + column ∗ TREE_SPACING
= 140 + 1 ∗ 40
= 180
21
Chapter 2 Forest Bomber part 1: A first level
When column is 2:
tree.x = FIRST_TREE + column ∗ TREE_SPACING
= 140 + 2 ∗ 40
= 220
And so on. This is how we work out the x coordinate of each of the
12 trees.
Notice the use of the double equals (==) in line 107. In Python, we use ==
to check if two things are equal.
Line 107 doesn’t actually draw anything though; it is only making the
decision. If the forest_item is equal to ‘T’, then line 108 will be executed,
and line 108 is the line which draws the tree on the screen.
Notice that line 108 is indented. If the forest_item is a ‘T’, then all
indented lines directly below the line will be executed. In this case, the only
indented line is 108, so that will be executed if the forest_item is a ‘T’.
22
Chapter 2 Forest Bomber part 1: A first level
Line 108 uses the blit command to draw a tree_image onto the
game_screen at coordinates (tree.x,tree.y). But where do all of these
commands and values come from?
Let’s ignore lines 109–110. They will display the image of a tree on fire if
it has been hit by a bomb. As we have not written the code to drop a bomb
yet, these lines won’t actually do anything.
We can summarize lines 105–108 as follows:
Run the program. The four trees of Forest Bomber level 1 should be
displayed along the bottom of the game window.
23
Chapter 2 Forest Bomber part 1: A first level
Double equals (==) are used to check if two things are equal.
Summary
Phew! No one said learning to code would be easy. We have covered a lot
of complex programming in this first chapter because we prefer to dive
right in. Don’t worry if it all seems difficult to understand. It is, but it will get
easier, and we will revisit many of these topics as we work through the book.
So far, we have written lots of lines of code, and all we have to show for
it is our game background and some trees. The Forest Bomber game will
begin to take a bit more shape in the next chapter.
24
CHAPTER 3
Let’s take a closer look at lines 113 and 114 in Figure 3-2.
Figure 3-2. Forest Bomber code listing lines 113 and 114
We can see another if statement has been used here, so we know that
the program code is making a decision. It is checking to see if plane_
exploded is False. If we look all the way back to line 63, we can see that
plane_exploded is a variable and it is initialized to False.
What is False? In programming, there is a variable type known as a
Boolean, and it can have one of only two possible values: True or False.
Boolean variables are useful in game programming, because they can only
be one or the other. There is no in-between. They can only be either True
or False. Later in the program, we will set the value of the plane_exploded
Boolean variable to True when our plane crashes into a tree. But for now,
it’s False.
Given that the value of plane_exploded is False (at least for now), then
line 114 will execute. Line 114 uses the blit command to draw the plane
image at coordinates (plane.x,plane.y).
26
Chapter 3 Forest Bomber part 2: Is it a bird…?
Key learning A Boolean variable can store one of two values: True
or False.
27
Chapter 3 Forest Bomber part 2: Is it a bird…?
28
Chapter 3 Forest Bomber part 2: Is it a bird…?
Figure 3-5. Forest Bomber code listing lines 122 and 123
Line 122 redraws the screen, while line 123 determines how many
times the screen should be redrawn in one second, in this case 30.
So our program now draws the plane, moves it 5 pixels right, redraws
the plane, moves it another 5 pixels right, and so on, creating the illusion of
the plane moving.
Test this by running the program.
Fantastic, right? Except for one thing. Our plane flies off the end of the
screen never to be seen again, and that won’t make for much of a game!
Add the code to fly the plane down the screen shown in code listing 8,
Figure 3-6.
29
Chapter 3 Forest Bomber part 2: Is it a bird…?
Run the program. Now the plane should fly to the right edge of the
screen and then drop down by 100 pixels beginning again on the left-hand
side, except now it flies all the way to the bottom of the screen and then
disappears. We will fix this in a later chapter.
Now we are going to make a couple of minor changes to the code that
flies our plane and which will be useful later.
First, adapt line 102 so that it reads as in Figure 3-7.
Figure 3-8. Forest Bomber code listing line 102 with if statement
The purpose of this line is to make sure we only move the plane if
30
Chapter 3 Forest Bomber part 2: Is it a bird…?
The code should now look like code listing 9 in Figure 3-9. One very
important thing to note – because we added an if statement at line 102,
lines 103, 105, 106, and 107 have all had one extra indentation.
31
CHAPTER 4
34
Chapter 4 Forest Bomber part 3: Bombs away…
We already know that lines 97 and 98 check to see if the spacebar was
pressed. Lines 99–102 is the code which will run when the spacebar is
pressed.
Let’s examine line 99 more closely. It is another if statement. This
statement checks for three things. It checks if
• bomb_dropped is False
• level_cleared is False
• plane_exploded is False
• bomb_dropped is False
35
Chapter 4 Forest Bomber part 3: Bombs away…
If all three statements are False, then lines 100 and 102 are executed:
36
Chapter 4 Forest Bomber part 3: Bombs away…
When and is used, all the statements have to work out as being true
for the if statement to execute.
Now run the program and try hitting the spacebar. A bomb should
appear where the plane is – it just doesn’t move yet.
M
ove the bomb
In Chapter 3, we learned how to move the plane by changing its
coordinates and then redrawing the screen. We will move the bomb in
exactly the same way.
Add code listing 12 (Figure 4-4) at line 117.
37
Chapter 4 Forest Bomber part 3: Bombs away…
Test the game by running it. If we press the spacebar, the bomb drops.
The only problem is it keeps going off the screen and we can never launch
another bomb. This is because the bomb_dropped Boolean variable is set to
True when the bomb is launched and never changed back to False.
Remember the code that tests if a bomb can be dropped (Figure 4-5)?
• Line 122 tests to see if the bomb has gone below the
bottom of the screen.
• Line 125 tests to see if the bomb has gone beyond the
right-hand side of the screen.
If the bomb has disappeared off the bottom, or off the right of the
screen, bomb_dropped will be set to False which means we can now use
the spacebar to drop a new bomb.
38
Chapter 4 Forest Bomber part 3: Bombs away…
Let’s take a closer look at line 122. It compares the y coordinate of the
bomb (bomb.y) with the SCREEN_HEIGHT. But how does the program know
what SCREEN_HEIGHT is?
Look back to lines 18 and 19 of the program. SCREEN_WIDTH is set to
640 and SCREEN_HEIGHT is set to 480. We don’t have to do this, but it makes
our code easier to read. And if we decided we wanted a bigger screen for
our game, say 800 × 600, then we would just have to set SCREEN_WIDTH and
SCREEN_HEIGHT to 800 and 600, respectively, at the start of the program.
You may be also wondering why we use capital letters for some
variable names, like SCREEN_WIDTH and SCREEN_HEIGHT. This is because
they are constants. A constant is assigned a value at the start of the
program, and it doesn’t change. Python’s naming convention suggests
we should use capital letters to indicate the use of constants. That way we
know that we are dealing with a constant value, and therefore its value
should not be changed by the program.
There is one other part of line 122 that merits a closer look. Previously
when comparing values, we have used the double equals sign (==) to
check whether two values are equal. In line 122 (and also in line 125), we
use the greater than (>) symbol. So line 122 actually reads
== Is equal to
> Is greater than
>= Is greater than or equal to
< Is less than
<= Is less than or equal to
!= Is not equal to
39
Chapter 4 Forest Bomber part 3: Bombs away…
Python has a range of comparison operators: ==, >, >=, <, <=,
and !=.
Run the program to test that a new bomb can be dropped once the
previous bomb has disappeared off the edge of the screen.
E xploding trees
The code to blow up a tree is quite complex, and given we are only just
beginning to learn how to code, we will only focus on a small part of it.
Let’s begin by adding code listing 14 (Figure 4-7) at line 128.
40
Chapter 4 Forest Bomber part 3: Bombs away…
Let’s take a brief overview of lines 128–139 to see what they do:
• If it has
41
Chapter 4 Forest Bomber part 3: Bombs away…
We will learn how to display the score and level in the next chapter.
The code between lines 142 and 147 uses a timer to display the
burning tree image for a series of ten frames before removing it from the
game altogether. The code is beyond the scope of this chapter, so we will
skip past it.
Test the game again. You should find that if the bomb hits a tree, it
explodes.
G
round level
Our game of Forest Bomber is starting to take shape. The big problem now
is that when our plane reaches the ground level, it flies through the trees
and off the screen.
Code listing 15 (Figure 4-8) addresses this. Insert the code at line 149.
42
Chapter 4 Forest Bomber part 3: Bombs away…
• Line 152 says if the plane has got beyond the right-hand
side of the screen, then the level has been cleared, so
set the Boolean variable level_cleared to True.
Test the game. Now the plane will come to a halt if the player manages
to clear all of the trees from the forest, or it will explode if it hits a tree.
43
Chapter 4 Forest Bomber part 3: Bombs away…
Notice the use of the keyword elif at line 105 (Figure 4-10).
It is short for else if and goes with the if statement at line 98. Together,
these lines can be read as
drop a bomb
Also notice that the way in which we test if the return key is pressed is
just the same as the way in which we tested if the space key was pressed.
Looking at the first part of line 108 (Figure 4-11), we are checking to see
if the plane has exploded.
44
Chapter 4 Forest Bomber part 3: Bombs away…
Figure 4-11. Forest Bomber code listing line 108 (first part)
If the plane has exploded, then we know it’s game over. Lines 109–117
reset all the variables back to their start-of-game values.
There is a second part to line 108 (Figure 4-12).
Figure 4-12. Forest Bomber code listing line 108 (second part)
This checks to see if we have cleared the level and also if the current
level is equal to TOTAL_LEVELS, which is 4. In other words, if we have cleared
level 4, we go back to the beginning of the game and start again at level 1.
Now that we have dealt with the game over functionality, let’s add the
functionality to move up a level. Add code listing 17 (Figure 4-13) at line 119
(making sure to check the indentation very carefully).
45
Chapter 4 Forest Bomber part 3: Bombs away…
Line 120 is another elif statement, this time paired with the if
statement at line 108. Together they can be read like this:
level up
• Lines 124–131 load the forest for the new level into
the forest variable. Also note that the speed_boost
variable is set to 1 for levels 3 and 4 to make the plane
fly faster, as discussed in Chapter 3.
46
Chapter 4 Forest Bomber part 3: Bombs away…
• When the plane crashes, the user can press the return
key to begin a new game.
• When all the trees are cleared, the user can press return
to move onto the next level.
All that’s missing now is a scoreboard and some feedback for the user
at the end of each level and the end of the game.
47
CHAPTER 5
S
coreboard background
Let’s begin by drawing a solid background for our scoreboard area. We will
keep the color the same light blue as the sky. Add code listing 18 at line 219.
There are only two lines of code here, but they do quite a lot.
Line 220 creates the rectangle dimensions for our scoreboard
background. We will use a variable to store this shape – scoreboard_
background_rect.
To draw a rectangle, we need four pieces of information:
• The number of pixels from the left of the screen to the
left of the rectangle
50
Chapter 5 Forest Bomber part 4: Wrapping it up
Line 221 draws the rectangle using the Pygame draw.rect command.
It requires three pieces of information to draw the rectangle:
51
Chapter 5 Forest Bomber part 4: Wrapping it up
Display the score
We want to display the game score in the top left-hand corner of the
screen. Add code listing 19 at line 223.
Line 223 initializes the variable score_text. Let’s look at what score_
text will store:
52
Chapter 5 Forest Bomber part 4: Wrapping it up
Run the program, and you should see the score appearing in the top
left-hand corner of the screen.
Display the level
It would be useful if Forest Bomber could display the current level of the
game. We will add four lines of code to display the level in the center of the
scoreboard.
Add code listing 20 at line 227.
53
Chapter 5 Forest Bomber part 4: Wrapping it up
This code is very similar to the code which we used to display the
score. The main difference is the way in which we center the text. To center
a block of text in Pygame, we need to
This will give is the point at which to place our rendered text so that it
is perfectly centered.
Add code listing 21 at line 197 to handle the high score logic.
54
Chapter 5 Forest Bomber part 4: Wrapping it up
Next, add code listing 22 at line 231 to display the high score at the
upper right of the scoreboard.
Display messages
Our final task is to display some messages at the end of the game or when
the level has been cleared to give the player a bit of feedback and to tell
them what to do next.
55
Chapter 5 Forest Bomber part 4: Wrapping it up
In each case, we will also tell the user that they can hit the return key to
continue.
We can work out if the game is over because the variable plane_
exploded will be True.
We can work out if the level has been cleared because the variable
level_cleared will be True.
We can use the following line of code (Figure 5-7) to test if the game is
over or the level has been cleared.
To test if the player has cleared all four levels, use the code in Figure 5-9.
56
Chapter 5 Forest Bomber part 4: Wrapping it up
To test if one of the levels 1–3 has been cleared, we can use an else
statement. An else statement is used with if and elif statements to say
‘Well, if it was none of the above, then do this.’
The logic to an else statement looks like this:
if it is game over
else
So the code following the else statement will run if it is not game over
and the player has not cleared all levels. Therefore, it can only be that the
player has completed one of the levels 1–3.
Displaying a message on screen in Pygame is relatively straightforward.
Getting the message to appear neatly is a bit trickier. We want our
messages to be displayed
• As white text
• On a blue rectangle
• Centered vertically
• Centered horizontally
Add code block 23 (Figure 5-10) at line 241 which will work out the
correct text message to be displayed.
57
Chapter 5 Forest Bomber part 4: Wrapping it up
Now insert code block 24 (Figure 5-11) at line 269. Take particular
care when entering lines 274 and 276. They are actually both single lines
of code, but they are too long to fit a single line, and so they wrap over two
separate lines. To enter these lines, type the code up to and including the
command and then hit return. The cursor will line up in the correct place.
We won’t be examining this code block too closely, but in summary it
does all of the math needed to draw the blue box and center the text neatly
on top of it.
58
Chapter 5 Forest Bomber part 4: Wrapping it up
59
Chapter 5 Forest Bomber part 4: Wrapping it up
60
CHAPTER 6
Snapper part 1:
In the woods
Charlotte was awake even before her alarm clock told her it
was time to get up. She pulled back the curtains just far enough
to see that the sun was already beating down. It was Saturday
morning, and today was going to be a perfect day for it.
Charlotte sprang out of bed, threw on her clothes, and began
packing the equipment that she would need for the day
ahead: a rucksack, a cheese sandwich, plenty of water, and
most importantly her prized possession – the Canon SLR
camera that her grandfather had given her when she was just
8 years old.
G
etting started
Snapper is a simple first-person shooting game where the aim is to target
forest animals. However, as we don’t actually want to kill any of our furry
friends, we will be using a camera instead of a gun.
The animals will appear in random locations around the forest
backdrop. To make the game more challenging, an animal will only appear
for a brief period of time before going into hiding again.
Now that we have the overall game idea, we need to break it down into
smaller steps:
2. Initialize variables.
5. Show an animal.
6. Hide an animal.
7. Take a photograph.
8. Game over.
9. Scoreboard.
You will spot that some of these steps are very similar to the Forest
Bomber design, but steps 4–7 are different.
Let’s check out how the finished game will look (Figure 6-1).
The player will move the camera using the mouse, and the animals (in
this example a rabbit) will appear at a random location on screen.
The player must try and photograph each animal before it hides again.
Clicking the mouse button will take a photograph.
62
Chapter 6 Snapper part 1: In the woods
63
Chapter 6 Snapper part 1: In the woods
As with Forest Bomber, we import some Python and Pygame libraries and
some colors; and then from line 17 onward, we set up some of the constant
values that we will be using in the program. Enter code listing 2 (Figure 6-3).
64
Chapter 6 Snapper part 1: In the woods
We also need to
Notice def main(): at line 59. This indicates that everything that follows
is the main part of the program. Pay particular attention to the indentation
from line 61 onward, and remember that each level of indentation should
be exactly four spaces (or one tab) from the left-hand side.
B
oolean variables
Let’s take a closer look at the first three variables shown in the code listing:
mouse_button_pressed, snap_visible, and miss_visible. Each of these
variables will store one of two possible values:
True or False
65
Chapter 6 Snapper part 1: In the woods
Key learning A Boolean variable can store one of two values: True
or False.
D
ictionaries
There are still some more variables that need to be initialized at the start of
the game. One of these is a special type of variable used in Python called a
dictionary. A dictionary is useful when storing multiple data items about
an object. Each value in a dictionary can be identified by its unique key.
66
Chapter 6 Snapper part 1: In the woods
Care should be taken when typing the animals dictionary into the
program. Every bracket, every comma, and every quote mark must be
included; or the program will not work. Pay attention to the brackets also –
they are curly brackets { } as opposed to curved brackets ( ).
By now you will be wondering what is the point of the animals
dictionary. It stores data about all of the animals in the Snapper game. This
will make more sense if we zoom in on one of the lines. Let’s say line 73.
Line 73 is a dictionary element. It stores information about animal_1.
animal_1 is known as the key of this dictionary element, and everything
after it is the value. The value stored is itself a dictionary which stores the
data about animal_1, specifically
67
Chapter 6 Snapper part 1: In the woods
68
Chapter 6 Snapper part 1: In the woods
69
Chapter 6 Snapper part 1: In the woods
• Finally, lines 127 and 128 will start the main program –
that is everything that comes after the line def main():.
Once again, it has taken us some time to write a lot of code, with only
a single static screen to show for our efforts. In the following chapters, we
will develop the actual Snapper game functionality…
70
CHAPTER 7
5. Show an animal.
6. Hide an animal.
Line 118 gets the current mouse location using the Pygame mouse.get_
pos() function. We store the mouse position in the variable mouse_pos.
The mouse position is stored as two values, one for the x coordinate of
the mouse and the other for the y coordinate. To access the x coordinate, we
use mouse_pos[0], and to access the y coordinate, we use mouse_pos[1].
We set the center of the camera to the x and y coordinates of the mouse
in lines 121 and 122.
Next, we need to actually draw (blit) the camera onto the game
background. Enter code listing 8 (Figure 7-2) at line 130 of the program.
72
Chapter 7 Snapper part 2: Say cheese
Lines 131–134 draw either the normal camera image or the flash
camera image. The if statement at line 131 works out whether snap_
visible or miss_visible is True. We will make use of these variables
later in the code, but for now we can see from looking back at lines 64
and 65, they are both initialized to False and so the camera_image will be
displayed by line 134.
Run the program and move the mouse – the camera should move
around the screen. That’s pretty neat, but notice that the camera disappears
off the edge of the screen. We don’t want that to happen, so let’s fix it. Add
the code from Figure 7-3 at line 124.
73
Chapter 7 Snapper part 2: Say cheese
• Lines 124 and 125 get the camera width and height and
store each in a variable.
• Lines 128 and 129 prevent the camera from going off
the left edge of the screen, while lines 130 and 131
prevent it from going off the right edge of the screen.
• Lines 133 and 134 prevent the camera from moving off
the top of the screen, while lines 135 and 136 stop it
from going below the scoreboard which will appear at
the bottom of the screen.
74
Chapter 7 Snapper part 2: Say cheese
Add the two new lines of code shown in Figure 7-4 at lines 98 and 99.
Line 98 makes use of Python’s random.choice function which picks
an item from a list at random. Our code picks a random animal from the
animals dictionary.
In fact, random.choice actually gets one of the random animal keys,
for example, animal_14 or animal_21. What we really want is the animals
dictionary represented by that key. Line 99 initializes the animal variable
with the dictionary represented by the random key.
For example, let’s say that line 98 randomly selected the key animal_7.
Line 99 stores the dictionary representing animal_7 in the animal variable,
so animal would look like this:
Now that we have a random animals dictionary, let’s use it to display the
animal on screen. Remember that 'type' stores the type of animal to be
displayed, while 'x_loc' and 'y_loc' are the animal’s coordinates.
75
Chapter 7 Snapper part 2: Say cheese
Add the block of code shown in Figure 7-5 at line 143 of the program.
Notice that we are drawing the animal after the background but before
the foreground overlay. With blit, each image is drawn on top of any
previously drawn images. In Snapper we draw the screen elements in the
following order:
• The background
• The animal
Using the foreground overlay in this way, we can partially hide our
animals behind trees, bushes, or even hills.
Examining code listing 11 we can see that:
76
Chapter 7 Snapper part 2: Say cheese
animal.get('type')
77
Chapter 7 Snapper part 2: Say cheese
S
etting a timer
If we look again at the animals dictionary, we will see that each animal has
a key 'time'. The value represented by the key 'time' is the length of time
that the animal will remain on screen.
Before we can hide an animal, we need to first get the time value by
using the 'time' key.
Add line 100 as shown in Figure 7-6.
Line 100 assigns the dictionary value of the animal ‘time’ to the
animal_timer.
Next we have to count down the timer and hide the animal when it
reaches 0. Add code listing 13 as shown in Figure 7-7.
78
Chapter 7 Snapper part 2: Say cheese
Lines 142–148 handle our animal timer, but how do they work?
79
Chapter 7 Snapper part 2: Say cheese
clock.tick(60)
In simple terms, it means that the while True loop will execute 60
times every second. So if we look back at our dictionary, we see that the
time value for animal_1 (a rabbit) is 60. That means it will be displayed on
screen for exactly one second. By comparison, animal_23 (a deer) has the
time value set to 90, so this animal will stay on screen for 1.5 seconds.
(Cheat hint: If you want to make the game easier, increase these time
values.)
R
ectangles
The code in Figure 7-7 has some additional lines which we have not
explained yet.
Lines 150–160 are used to work out the size and location of the animal
image currently on screen. Each image is actually a rectangle. We won’t
go into this code in much detail at the moment other than to say we use it
to work out if the camera is on top of the animal when the player takes a
photograph.
80
Chapter 7 Snapper part 2: Say cheese
Enter the code shown in Figure 7-8 at line 162. Let’s take a look at it:
81
Chapter 7 Snapper part 2: Say cheese
Building a function
Notice how we generated a random animal at two different places in the
program, once at the start of the code and then again when we wanted to
get a new animal to show. Copying code in this way is not considered good
practice. What happens, for example, if we change the code that generates
a random animal? We would have to remember to change the code in both
places.
Instead, it is better practice to build a single block of code to do this. In
programming, it is common to break a program down into smaller blocks
of code that carry out a specific task. In Python, these code blocks are
called functions.
A function is a block of code that carries out a specific job. It may
optionally return a value back into the main program when it has finished.
We will create a function to generate a random animal, and we will
call our function get_random_animal. As with naming variables, we can
82
Chapter 7 Snapper part 2: Say cheese
call a function anything we wish, but it is good practice for the name of the
function to describe what it does. So get_random_animal does exactly what
it says on the tin!
Enter the function code as shown in Figure 7-9 near the foot of the
program. Notice the use of two blank lines above and below the function.
Next, we need to go back to our main program and change the code so
that it makes use of this function instead.
Replace lines 98 and 99 of the program shown in Figure 7-10 with the
single line of code shown in Figure 7-11.
Similarly, replace lines 167 and 168 shown in Figure 7-12 with the
single line of code shown in Figure 7-13.
83
Chapter 7 Snapper part 2: Say cheese
animal = get_random_animal(animals).
def get_random_animal(animals):
84
Chapter 7 Snapper part 2: Say cheese
animal = get_random_animal(animals).
When our main program code runs a function, we say that it calls the
function.
Don’t worry if you find the concept of functions a bit tricky to
understand – we will be revisiting functions again later in the book.
Key learning Functions are blocks of code that carry out a specific
task. Parameters can be passed into a function, and a result can be
returned out of the function back to the main program.
85
CHAPTER 8
7. Taking a photograph
8. Game over
9. Scoreboard
Add the code in Figure 8-1 at line 114. With this code, we check to see
if the mouse button is clicked and if so set the variable mouse_button_
pressed to True. Otherwise, it will remain False.
To find out what will be in the photo, we need to work out what can be
seen through the camera’s viewfinder. The viewfinder is a rectangle, the
dimensions of which we can calculate.
88
Chapter 8 Snapper part 3: Snapped
Add the code from Figure 8-2 at line 145 to calculate the viewfinder
rectangle.
R
ectangles collide
Next, we need to write some code to take a photograph when the mouse
button is pressed. We will build this code block up in smaller parts.
89
Chapter 8 Snapper part 3: Snapped
Insert the code shown in Figure 8-3 at line 184. There are quite a lot of
if statements here, so let’s see what each one does:
90
Chapter 8 Snapper part 3: Snapped
Snapped it!
So the player has taken a photo if all of the following are true:
• The mouse button is pressed.
• It is not game over.
• The animal is in the camera’s viewfinder.
• The animal is actually visible.
The code between lines 191 and 193 is run when these events happen:
• Line 191 calculates how much time was left on the
timer, multiplies that by the points value for the animal,
and adds the result onto the game score.
• Line 192 sets snap_visible to True. When snap_
visible is True, a green tick will display in the camera
viewfinder, and we can’t take another photo.
• Line 193 plays an audio file – the camera shutter effect.
91
Chapter 8 Snapper part 3: Snapped
Run the program and try to take a picture. If you are successful, you
will hear the camera shutter sound effect being played, and the camera
screen will go black. If you are unsuccessful, well, nothing happens, not yet
anyway. Let’s fix that.
O
ops, missed!
Enter the code shown in Figure 8-5. Take particular care to ensure the
indentation is exactly as shown in the code listing.
The first else statement shown at line 195 goes with the statement
if animal_visible is True:
92
Chapter 8 Snapper part 3: Snapped
The second else statement at line 200 goes with the statement
if viewfinder_rect.colliderect(animal_rect):
This else statement will be reached if the viewfinder rectangle did not
collide with the animal rectangle. In other words, the player missed the
animal when they took their photograph. If this happens, lines 201–203
will be run, which as we can see do exactly the same thing as lines 196–198.
Whether the photo was successful or not, we run lines 206–208 to hide
the animal, cancel the animal timer, and start a no animal timer.
Hit or miss?
Finally, we want to use the Boolean variables snap_visible and hit_
visible in order to display a green tick or a red cross over the viewfinder to
indicate whether or not the photograph was successful.
93
Chapter 8 Snapper part 3: Snapped
Insert the Figure 8-6 code at line 237. Take particular care with lines
239–240. This is actually one line of code split over two lines. Key it in
exactly as shown, and when you reach the comma at the end of line 239,
hit return and continue typing line 240:
94
Chapter 8 Snapper part 3: Snapped
Add the game over code at line 119. Let’s take a look at how it works:
• Line 120 gets details of any key presses from the
Pygame get_pressed() function and stores them in
the variable key_pressed,
• Line 121 checks for two things:
• To see if the key pressed was RETURN
• To see if the number of lives remaining equals zero
(in other words, is it game over)
95
Chapter 8 Snapper part 3: Snapped
The remaining block of code will run if the game is over and the player
has pressed RETURN:
And that’s it. A new game is set up ready to go. Run the code to test it.
The only thing that’s missing is a scoreboard.
Step 9: Scoreboard
In Forest Bomber, we saw how to write code to display a scoreboard. We
will use a similar process in Snapper, but this time the scoreboard will be
displayed at the bottom of the screen.
In Snapper, we will break our scoreboard code down into two
functions:
96
Chapter 8 Snapper part 3: Snapped
97
Chapter 8 Snapper part 3: Snapped
98
Chapter 8 Snapper part 3: Snapped
99
CHAPTER 9
G
etting started
Alien Invasion is a space arcade game, where the goal is to prevent earth
being invaded by alien Unidentified Flying Objects (UFOs). The player
controls a moving base and has 20 missiles to shoot down as many UFOs
as possible.
UFOs will move around the upper area of the screen and have the
ability to destroy incoming missiles with a special force field defense ray.
2. Initialize variables.
3. Display background.
5. Launch missile.
6. Move UFOs.
7. Shoot UFOs.
8. Game over.
9. Scoreboard.
102
Chapter 9 Alien Invasion part 1: Under attack
103
Chapter 9 Alien Invasion part 1: Under attack
First, we set up the Python and Pygame libraries and declare a number
of constants for use in the game.
Let’s take a look at some of the more interesting constants:
• MISSILE_SPEED
104
Chapter 9 Alien Invasion part 1: Under attack
• GAME_MISSILES
• UFO_UPPER_Y, UFO_LOWER_Y
The UFOs will only fly between these y coordinates.
• BASE_SPEED
105
Chapter 9 Alien Invasion part 1: Under attack
Let’s take a look at some of these variables and what they will be used
for in the game:
• base_x, base_y
106
Chapter 9 Alien Invasion part 1: Under attack
• missile_firing
• ufo_1, ufo_2
These are dictionaries which store data about each
UFO, namely
• x_loc, y_loc
UFO coordinates
• direction
• hit
• off_time
• ray_time
Length of time the UFO blaster ray can be
operational
• speed
107
Chapter 9 Alien Invasion part 1: Under attack
Test if the game works by running the code. You should see the game
background and be able to quit by closing the game window, but that’s all.
In the next chapter, we will write the code to move the base and fire
missiles.
108
CHAPTER 10
5. Launch missile.
Add the code shown in Figure 10-1 at line 112. We have already seen
how Pygame stores a list of key press events which can be retrieved by
using pygame.key.get_pressed(). As before, we store the key press events
in our variable key_pressed.
Looking at this code block
• Line 113 tests to see if the left arrow key was pressed.
• If the left arrow was pressed, line 114 takes the BASE_
SPEED constant away from the base’s x coordinate.
Remember BASE_SPEED is the number of pixels that the
base will move in one frame (in our game, BASE_SPEED
is set to 6). Also remember we use -= to subtract a value
from a variable.
110
Chapter 10 Alien Invasion part 2: Missile launch is Go
Lines 119–122 do virtually the same thing as in the preceding text, but
instead move the base right instead of left:
• Line 119 tests to see if the right arrow key was pressed.
• Line 121 tests to see if the base has gone beyond the
right-hand edge of the screen.
Now run Alien Invasion. The base will appear at the foot of the screen
and can be moved left or right using the arrow keys.
C
omparison operators
In Python, we can compare two values using comparison operators. We
have already encountered some comparison operators in this book. For
example, the code which tests if the base has gone beyond the left-hand
111
Chapter 10 Alien Invasion part 2: Missile launch is Go
side of the screen uses the less than (<) comparison operator, while the
code which checks if the base has gone beyond the right-hand side of the
screen uses the greater than (>) comparison operator.
This is a good opportunity to review all of the comparison operators
that can be used in Python (Table 10-1).
== Is equal to
!= Is not equal to
> Greater than
< Less than
>= Greater than or equal to
<= Less than or equal to
112
Chapter 10 Alien Invasion part 2: Missile launch is Go
If all three of these conditions are met, we fire a missile with the code
between lines 126 and 132:
113
Chapter 10 Alien Invasion part 2: Missile launch is Go
M
ove the missile
Once the missile has been launched, we need to keep its y coordinate
changing; otherwise, it will not actually move. We subtract MISSILE_SPEED
from the missile’s y coordinate (missile_y).
The code in Figure 10-4 is the code that will do that.
114
Chapter 10 Alien Invasion part 2: Missile launch is Go
D
isplay missile
Finally, in order to see the effect of the missile being fired, we need to draw
it on the screen. Add code listing 9 (Figure 10-5) to your program.
L ogical operators
Logical operators are used with conditions (if statements, while loops) to
build more complex conditions.
115
Chapter 10 Alien Invasion part 2: Missile launch is Go
• and
• or
• not
Let’s look at a simple if condition for a moment, one that we used
back in the Snapper program:
if lives == 0:
display_game_over()
The and logical operator is used here to ensure that each of the three
operands evaluates to true before launching the missile. The missile can
only be launched if
key_pressed[pygame.K_SPACE]
116
Chapter 10 Alien Invasion part 2: Missile launch is Go
game_over is False
117
CHAPTER 11
120
Chapter 11 Alien Invasion part 3: And they came from outer space
There seems like quite a lot of code in the move_ufo function, but most
of it is fairly straightforward. Let’s examine it in more detail.
To understand how move_ufo works, we need first to remind ourselves
what data the UFO dictionary holds. In particular, we are interested in the
following keys:
121
Chapter 11 Alien Invasion part 3: And they came from outer space
For example
• Line 164 tests if the direction is left, and if it is, line 165
subtracts the speed from the x coordinate.
Stay on screen
Remember when we wrote the code to drive the missile launcher, we made
sure that it would not drive off the edge of the screen? We will do the same
thing with our UFOs.
122
Chapter 11 Alien Invasion part 3: And they came from outer space
Time for a change
Next, we will concentrate on the else statement on line 154 and the block of
code below it. This else statement will only be reached if the UFO did not go
off the edge of the screen. In this code block, we will throw in some random
movement changes to make the game more interesting and challenging.
First, we need to understand the purpose of the two constants that are
used by the code:
Line 195 tests to see if the UFO is moving up or down. Notice we have
used the or conditional operator that we described in the previous chapter.
If the UFO is moving up or down, line 196 sets the variable ufo_
direction_chance to a random number between 1 and 20.
If the UFO is not moving up or down, then it must be moving left or
right. In this case, line 198 sets the variable ufo_direction_chance to a
random number between 1 and 100.
Finally, line 200 tests to see if the random ufo_direction_chance
equals 1. If ufo_direction_chance equals 1, we change direction by
picking a random direction from the list of four UFO directions (left, right,
up, down).
In summary, during each frame, there is
123
Chapter 11 Alien Invasion part 3: And they came from outer space
C
all the function
We have written the move_ufo function, but nothing will happen yet
because it does not get called by the main program.
Add the code shown in Figure 11-2 at line 145 which calls the move_ufo
function for each of the UFOs.
D
isplay UFOs
Finally, we need to blit the two UFOs onto the screen.
124
Chapter 11 Alien Invasion part 3: And they came from outer space
The code shown in Figure 11-3 which displays each UFO is just a bit
more complicated than usual:
• At line 164 (and 169), we test to see if the hit key in the
UFO dictionary is False. We will only display the UFO
image if hit is False, that is, the UFO has not been hit
by a missile.
Run the game. If you have written the code correctly, you should see
two UFOs buzzing about the screen. You can try to shoot them, but nothing
will happen if a missile hits them. At least, not yet…
125
CHAPTER 12
Save the planet
They were getting much closer now, and in a few seconds
Commander Fisher knew that the UFOs which she had been
monitoring for the past 20 minutes would be in range of
the MLV.
She took a breath. ‘Wait…’ she whispered to no one in
particular. ‘Wait…’
She knew that it was her time. Everything came down to this.
‘Launch missile 1!’
The first missile sped from the launcher lighting up the night
sky like an enormous firework. Fisher knew instantly that the
projectile was on target. As it shot toward the spaceship she felt
sure it would be a direct hit.
And then, seemingly out of nowhere a defense field appeared
around the spaceship and the missile exploded before making
contact.
Commander Fisher knew that she had only 19 missiles remain-
ing with which to save planet earth.
In this final part of Alien Invasion, we will write the code to shoot the
UFOs and complete the game:
7. Shoot UFOs.
8. Game over.
9. Scoreboard.
© Mark Cunningham 2020 127
M. Cunningham, Game Programming with Code Angel,
https://doi.org/10.1007/978-1-4842-5305-2_12
Chapter 12 Save the planet
128
Chapter 12 Save the planet
There is quite a bit of code here, but hopefully you can see that lines
152–165 deal with the ufo_1, while lines 167–180 are for ufo_2. Given
these are broadly the same, we will only review the code for ufo_1.
129
Chapter 12 Save the planet
130
Chapter 12 Save the planet
If you run the code now, you will see some minor improvements when
a UFO has been hit by a missile, but there is still some work to be done. We
are going to add another function update_hit_ufo as shown in Figure 12-3.
As ever, remember to use double spacing between functions.
131
Chapter 12 Save the planet
Of course, we still have to add the code which will call this function
from our main program. It gets called twice, once for each UFO. Add code
listing 16 (Figure 12-4) to your program.
Run the program again; and you should find that when a UFO is hit by a
missile, it explodes for a short time, disappears briefly, and then respawns.
132
Chapter 12 Save the planet
Of course, we still need to call the function from the main program
which we do as shown in Figure 12-6.
133
Chapter 12 Save the planet
You may already have worked out that this code by itself doesn’t do
much other than change the value of the UFO dictionary ray_time.
We need to add the code shown in Figure 12-7 to the main program to
actually display the rays on screen.
We don’t really want to get into the detail of this code, other than to say
that if the UFO ray_time > 0, then it will draw one of the ray images directly
below the spaceship.
Run the program now, and you will see that the UFOs produce the
defense rays at random. If you shoot a missile at a UFO when its rays are
active, the missile will be destroyed.
134
Chapter 12 Save the planet
Next, we need to add some code which will display the game over
message if the game has finished. Add code listing 21 to your program
(Figure 12-9).
135
Chapter 12 Save the planet
The Boolean variable game_over gets set to True when all of the
missiles have been fired. The reason we check missile_firing is that
we need the last missile to either hit a UFO or go off the screen before
finishing the game.
We have seen lines 232 and 233 in both of the previous games, and line
235 will call our game_over_function.
Test that game over works by firing 20 missiles, after which the message
should be displayed.
However, hitting the return key at the end of the game does nothing.
Let’s fix that. Add the code shown in Figure 12-10 to the program.
By now, it should be fairly obvious what this code does. We test to see
if our key_pressed list contains the return key. If it does and the game_over
Boolean is True, we reset the three variables game_over, score, and
missiles which will start a new game.
Test that the game over process works correctly now.
136
Chapter 12 Save the planet
Step 9: Scoreboard
The last thing we need to do to complete the game is display a scoreboard
at the top of the screen. We have seen how to do this in both the previous
programs, so it shouldn’t require too much explanation.
Add the function display_scoreboard_data as shown in Figure 12-11.
137
Chapter 12 Save the planet
And there we have it. Three hundred and ninety-three* lines of code
later, we have our Alien Invasion game!
*Actually although the listing runs to 393 lines, if you take out all of the
line breaks, it’s actually only 300, but still…
138
CHAPTER 13
G
etting started
If you have made it this far, then well done! And of course, you know
what’s coming next. We have 100 lines of initialization and setup code
before we can get into the game proper. OK, let’s just roll our sleeves up
and crack on with it.
The idea behind Golf is simple. Get the ball from the tee to the hole in
as few strokes as possible. For each hole, the flag will be placed a random
distance from the tee, and the player should work out how hard to hit the
ball using a power meter/slider. The player will play three holes of golf in a
single game.
As with previous projects, let’s list the steps required to build the game
of Golf:
1. Set up the game environment.
2. Initialize variables.
3. Display background.
4. Display flag.
5. Power meter.
6. Move the ball.
7. In the hole.
8. Scoreboard.
Figure 13-1 shows how the screen will look.
140
Chapter 13 Golf part 1: On the tee
While the setup of the constant variables is not the most interesting
part of writing a game, it’s worth taking a moment just to review the
purpose of some of the more interesting constants we will be using:
141
Chapter 13 Golf part 1: On the tee
Enter the code which sets up the Pygame environment and loads in the
images and audio (Figure 13-3).
142
Chapter 13 Golf part 1: On the tee
143
Chapter 13 Golf part 1: On the tee
Constants
But what about these variables that are capitalized? These are known as
constants. Unlike normal variables, the value of a constant is not meant
to change when the program is run. In some programming languages,
it’s simply not possible to change the value of a constant once it has been
declared. In Python, technically the value of a constant can be changed,
144
Chapter 13 Golf part 1: On the tee
but we really don’t want to do that. We use capital letters to make it clear
that a constant is being used, and its value should not be changed by the
program code.
145
Chapter 13 Golf part 1: On the tee
The y coordinate is a bit easier because it remains the same during the
game. There is a constant FLAG_Y which is set to 244 at line 46.
The only consideration now is to decide which flag to display, as there
are three different flag images in the game, one for each hole.
The code in Figure 13-6 draws the correct flag at the correct position.
146
Chapter 13 Golf part 1: On the tee
Run the program a few times, and the flag will appear in a different
location each time.
In the next chapter, we will develop the code to move the power meter
and hit the ball.
147
CHAPTER 14
5. Power meter.
150
Chapter 14 Golf part 2: On the green
If the slider is not moving up, then line 123 tests slider_direction to
see if it equals 'down'.
If the slider is moving down
151
Chapter 14 Golf part 2: On the green
First up, we only want to display the power meter if the ball has not
been hit and the ball is not in the hole. Line 138 checks these conditions
and if they are both met:
• Lines 141 and 142 do some basic math to work out the
y coordinate of the slider depending on the value of
shot_power.
Run the program, and you should see the slider moving up and down
the power meter, and it will move more slowly when it reaches the bottom.
152
Chapter 14 Golf part 2: On the green
We are familiar with the code to test if a key has been pressed. We want
to hit the ball if the following three conditions have happened:
153
Chapter 14 Golf part 2: On the green
• Line 115 tests to see if the ball is moving right and then
calculates the final location of the ball by adding the
shot power onto the current location of the ball.
hole_strokes = [0, 0, 0]
154
Chapter 14 Golf part 2: On the green
hole_strokes[0]
To access the third and last element in our hole_strokes list, we use
hole_strokes[2]
Let’s look again at the code which we used to update the number of
strokes for the hole when the ball was hit. It’s at line 113:
hole_strokes[hole - 1] += 1
Assuming we are on the first hole, the hole will equal 1. We want to
add 1 to the value of the first element of our list. But remember the index
always starts at 0, so actually we want to add one to hole_strokes[0].
Using hole – 1 as the index means we will reference index 0 for hole 1,
index 1 for hole 2, and index 2 for hole 3.
After the first shot has been hit, we add 1 onto hole_strokes[0], and
so the list will become
[1, 0, 0]
155
Chapter 14 Golf part 2: On the green
156
Chapter 14 Golf part 2: On the green
As you can see, there is quite a bit of code in Figure 14-4, so let’s take a
closer look at what it does.
Line 150 checks to see if ball_distance > 0. The variable ball_
distance is greater than zero when the ball is moving. It will become zero
when it reaches its final destination and therefore stop moving.
Lines 152–155 update the ball’s x coordinate (stored in ball_x). If
the ball is moving to the right, we add to the x coordinate, and if the ball
is moving to the left, we subtract from the x coordinate. The amount the
ball moves each time is held in the constant BALL_STEP. BALL_STEP was
initialized to 3 at the start of the program, so the ball moves 3 pixels on
each frame.
There is an if statement at line 158 which tests the ball's x coordinate
to see
The code at lines 161–169 will handle the ball rolling off the edge
of the screen:
157
Chapter 14 Golf part 2: On the green
If however the ball has not rolled off the edge of the screen, then we
need to update its location each frame. The code between lines 172–195
will do this:
If the ball has reached its destination, we check to see if it has ended
up in the hole. This will happen if the final_ball_location is equal to the
flag_distance. If the ball is in the hole, we
D
raw the ball
For us to see all of this code in action, we need to actually draw the ball.
Enter the code from Figure 14-5.
158
Chapter 14 Golf part 2: On the green
159
CHAPTER 15
7. In the hole
8. Scoreboard
Step 7: In the hole
In actual fact, we have already worked out if the ball is in the hole. Look
back at lines 179 and 180 where we set in_the_hole to True if the
final_ball_location was equal to the flag_distance.
First of all, we need to display a message if the ball is in the hole. We
will use a function to do this. Add the in_hole_message function shown in
code listing 11 (Figure 15-1) to your program.
Let’s look more closely at this function. We can split it into three main
parts:
• Lines 229–234 compose the message to be displayed
depending on whether or not all three holes have been
completed.
• Lines 236–240 create a rectangle to give the message a
background and then blit it onto the screen.
162
Chapter 15 Golf part 3: It’s in the hole
There are some useful coding techniques used here which merit
further investigation.
Joining strings
Look again at lines 230 and 233. They use the variable message to store the
message that is to be displayed. message is a string, and it is composed of
three parts:
163
Chapter 15 Golf part 3: It’s in the hole
Line 239 creates the rectangle shape, while line 240 actually draws the
rectangle.
Centering text
In all of our games, we have centered text on the screen, but how do we do
that? There are four steps involved, as we can demonstrate by looking at
lines 238, 246, and 247 of the Golf code:
164
Chapter 15 Golf part 3: It’s in the hole
Add the code shown in Figure 15-2 to display a message once the ball
is in the hole.
So far our game only plays one hole of golf, and we want the final game
to run over three holes. When the ball is in the hole, we need the user to hit
return to continue. Enter the code shown in Figure 15-3.
165
Chapter 15 Golf part 3: It’s in the hole
For this code to run, there are two conditions which have to be met in
the elif statement at line 123:
166
Chapter 15 Golf part 3: It’s in the hole
If all three holes have not yet been played, we will run the else
statement at line 134 and add one onto the current hole number at line 135.
Finally, whether we are starting a new game or just a new hole, we
set the variables for a new hole and ensure that the power meter starts
at position 1 (lines 137–148). Most importantly here, we initialize a new
random flag position at lines 145 and 146.
Step 8: Scoreboard
The final aspect of our game is to display a scoreboard. On the scoreboard,
we want to show
167
Chapter 15 Golf part 3: It’s in the hole
168
Chapter 15 Golf part 3: It’s in the hole
display_scoreboard_data('Total', 6, 0)
This will display the text ‘Total’ at column 6 on line 0 of the scoreboard.
Fixed loops
In programming, a fixed loop will repeat a block of code a specific number
of times. In Python, we use the for keyword when writing a fixed loop.
Let’s take a closer look at the code at line 267:
This code uses a for loop to repeat a fixed number of times, in this
case three. Each time through the loop, the variable hole_number will be
increased by 1. In other words, hole_number will be
169
Chapter 15 Golf part 3: It’s in the hole
It is possible to use different start and stop values for a fixed loop, for
example
D
isplay the scoreboard
We need to add some code to call the display_scoreboard function and
display the scoreboard.
Add the code shown in Figure 15-6 and run the program. Grab your
clubs and go and play a round of golf.
170
Chapter 15 Golf part 3: It’s in the hole
Wrapping up
Congratulations! If you have reached this far in the book, you have
programmed four computer games in Python/Pygame.
Don’t worry if you found some parts of the code hard to understand;
that is only to be expected. Computer programming is not easy, and it
takes time and practice to become a good coder.
Try to take some of the skills you have learned from this book and
create your own game. Don’t try and do everything at once though, but
build your game up in steps, as we have done throughout this book.
Building games and programs in this way allows you to test each stage
before moving on to the next.
Good luck…
171
Index
A Display scoreboard, Forest Bomber
background
Alien invasion, 2
code, 50
game environment setup
game_screen, 51
code, 103
information, 51
constants, 104, 105
rectangle, 50
display background, 108
values, 51
initialize variables, 106, 107
high score, 54, 55
screen design, 103
level, 53, 54
steps, 102
messages
UFOs, 101
circumstances, 56
code, 57, 58
B else statement, 57
Bugs, 3, 5 level_cleared, 56
plane_exploded, 56
Pygame, 57
C tests, 56
check_ufo_hit function, 130 score, 52–53
Comparison operators, 111 display_scoreboard function, 170
Drop bomb, Forest Bomber
Boolean variables, 43
D, E else if, 44
Debugging, 5 exploding trees, 40–42
def main(), 65 ground level, 42, 43
display_game_over if statement, 46
function, 98, 135 key presses
display_scoreboard_data code, 34
function, 98, 169 if statement, 35
174
Index
175
INDEX
176
Index
177