So far, all of our games have used only text. Text is displayed on the screen as output, and the player enters text as input. Just using text makes programming easy to learn. But in this chapter, we’ll make some more exciting programs with advanced graphics using the pygame module.
Chapters 17, 18, 19, and 20 will teach you how to use pygame to make games with graphics, animations, mouse input, and sound. In these chapters, we’ll write source code for simple programs that demonstrate pygame concepts. Then in Chapter 21, we’ll put together all the concepts we learned to create a game.
TOPICS COVERED IN THIS CHAPTER
• Colors and fonts in pygame
• Aliased and anti-aliased graphics
• The pygame.font.Font , pygame.Surface , pygame.Rect , and pygame.PixelArray data types
• pygame ’s drawing functions
• The blit() method for surface objects
The pygame module helps developers create games by making it easier to draw graphics on your computer screen or add music to programs. The module doesn’t come with Python, but like Python, it’s free to download. Download pygame at https://www.nostarch.com/inventwithpython/, and follow the instructions for your operating system.
After the installer file finishes downloading, open it and follow the instructions until pygame has finished installing. To check that it installed correctly, enter the following into the interactive shell:
If nothing appears after you press ENTER, then you know pygame was successfully installed. If the error ImportError: No module named pygame appears, try to install pygame again (and make sure you typed import pygame correctly).
NOTE
When writing your Python programs, don’t save your file as pygame.py. If you do, the import pygame line will import your file instead of the real pygame module, and none of your code will work.
First, we’ll make a new pygame Hello World program like the one you created at the beginning of the book. This time, you’ll use pygame to make “Hello world!” appear in a graphical window instead of as text. We’ll just use pygame to draw some shapes and lines on the window in this chapter, but you’ll use these skills to make your first animated game soon.
The pygame module doesn’t work well with the interactive shell, so you can only write programs using pygame in a file editor; you can’t send instructions one at a time through the interactive shell.
Also, pygame programs don’t use the print() or input() functions. There is no text input or output. Instead, pygame displays output by drawing graphics and text in a separate window. Input to pygame comes from the keyboard and the mouse through events, which are covered in “Events and the Game Loop” on page 270.
When you run the graphical Hello World program, you should see a new window that looks like Figure 17-1.
Figure 17-1: The pygame Hello World program
The nice thing about using a window instead of a console is that text can appear anywhere in the window, not just after the previous text you have printed. The text can also be any color and size. The window is like a canvas, and you can draw whatever you like on it.
Enter the following code into the file editor and save it as pygameHelloWorld.py. If you get errors after typing in this code, compare the code you typed to the book’s code with the online diff tool at https://www.nostarch.com/inventwithpython#diff.
1. import pygame, sys
2. from pygame.locals import *
3.
4. # Set up pygame.
5. pygame.init()
6.
7. # Set up the window.
8. windowSurface = pygame.display.set_mode((500, 400), 0, 32)
9. pygame.display.set_caption('Hello world!')
10.
11. # Set up the colors.
12. BLACK = (0, 0, 0)
13. WHITE = (255, 255, 255)
14. RED = (255, 0, 0)
15. GREEN = (0, 255, 0)
16. BLUE = (0, 0, 255)
17.
18. # Set up the fonts.
19. basicFont = pygame.font.SysFont(None, 48)
20.
21. # Set up the text.
22. text = basicFont.render('Hello world!', True, WHITE, BLUE)
23. textRect = text.get_rect()
24. textRect.centerx = windowSurface.get_rect().centerx
25. textRect.centery = windowSurface.get_rect().centery
26.
27. # Draw the white background onto the surface.
28. windowSurface.fill(WHITE)
29.
30. # Draw a green polygon onto the surface.
31. pygame.draw.polygon(windowSurface, GREEN, ((146, 0), (291, 106),
(236, 277), (56, 277), (0, 106)))
32.
33. # Draw some blue lines onto the surface.
34. pygame.draw.line(windowSurface, BLUE, (60, 60), (120, 60), 4)
35. pygame.draw.line(windowSurface, BLUE, (120, 60), (60, 120))
36. pygame.draw.line(windowSurface, BLUE, (60, 120), (120, 120), 4)
37.
38. # Draw a blue circle onto the surface.
39. pygame.draw.circle(windowSurface, BLUE, (300, 50), 20, 0)
40.
41. # Draw a red ellipse onto the surface.
42. pygame.draw.ellipse(windowSurface, RED, (300, 250, 40, 80), 1)
43.
44. # Draw the text's background rectangle onto the surface.
45. pygame.draw.rect(windowSurface, RED, (textRect.left - 20,
textRect.top - 20, textRect.width + 40, textRect.height + 40))
46.
47. # Get a pixel array of the surface.
48. pixArray = pygame.PixelArray(windowSurface)
49. pixArray[480][380] = BLACK
50. del pixArray
51.
52. # Draw the text onto the surface.
53. windowSurface.blit(text, textRect)
54.
55. # Draw the window onto the screen.
56. pygame.display.update()
57.
58. # Run the game loop.
59. while True:
60. for event in pygame.event.get():
61. if event.type == QUIT:
62. pygame.quit()
63. sys.exit()
Let’s go over each of these lines of code and find out what they do.
First, you need to import the pygame module so you can call its functions. You can import several modules on the same line by separating the module names with commas. Line 1 imports both the pygame and sys modules:
1. import pygame, sys
2. from pygame.locals import *
The second line imports the pygame.locals module. This module contains many constant variables that you’ll use with pygame , such as QUIT , which helps you quit the program, and K_ESCAPE , which represents the ESC key.
Line 2 also lets you use the pygames.locals module without having to type pygames.locals. in front of every method, constant, or anything else you call from the module.
If you have from sys import * instead of import sys in your program, you could call exit() instead of sys.exit() in your code. But most of the time it’s better to use the full function name so you know which module the function is in.
All pygame programs must call pygame.init() after importing the pygame module but before calling any other pygame functions:
4. # Set up pygame.
5. pygame.init()
This initializes pygame so it’s ready to use. You don’t need to know what init() does; you just need to remember to call it before using any other pygame functions.
Line 8 creates a graphical user interface (GUI) window by calling the set_mode() method in the pygame.display module. (The display module is a module inside the pygame module. Even the pygame module has its own modules!)
7. # Set up the window.
8. windowSurface = pygame.display.set_mode((500, 400), 0, 32)
9. pygame.display.set_caption('Hello world!')
These methods help set up a window for pygame to run in. As in the Sonar Treasure Hunt game, windows use a coordinate system, but the window’s coordinate system is organized in pixels.
A pixel is the tiniest dot on your computer screen. A single pixel on your screen can light up in any color. All the pixels on your screen work together to display the pictures you see. We’ll create a window 500 pixels wide and 400 pixels tall by using a tuple.
Tuple values are similar to lists, except they use parentheses instead of square brackets. Also, like strings, tuples can’t be modified. For example, enter the following into the interactive shell:
>>> spam = ('Life', 'Universe', 'Everything', 42)
➊ >>> spam[0]
'Life'
>>> spam[3]
42
➋ >>> spam[1:3]
('Universe', 'Everything')
➌ >>> spam[3] = 'Hello'
➍ Traceback (most recent call last):
File "", line 1, in
TypeError: 'tuple' object does not support item assignment
As you can see from the example, if you want to get just one item of a tuple ➊ or a range of items ➋ , you still use square brackets as you would with a list. However, if you try to change the item at index 3 to the string 'Hello' ➌ , Python will raise an error ➍ .
We’ll use tuples to set up pygame windows. There are three parameters to the pygame.display.set_mode() method. The first is a tuple of two integers for the width and height of the window, in pixels. To set up a 500- by 400-pixel window, you use the tuple (500, 400) for the first argument to set_mode() . The second and third parameters are advanced options that are beyond the scope of this book. Just pass 0 and 32 for them, respectively.
The set_mode() function returns a pygame.Surface object (which we’ll call Surface objects for short). Object is just another name for a value of a data type that has methods. For example, strings are objects in Python because they have data (the string itself) and methods (such as lower() and split() ). The Surface object represents the window.
Variables store references to objects just as they store references for lists and dictionaries (see “List References” on page 132).
The set_caption() method on line 9 just sets the window’s caption to read 'Hello World!' . The caption is in the top left of the window.
There are three primary colors of light for pixels: red, green, and blue. By combining different amounts of these three colors (which is what your computer screen does), you can form any other color. In pygame , colors are represented by tuples of three integers. These are called RGB color values, and we’ll use them in our program to assign colors to pixels. Since we don’t want to rewrite a three-number tuple every time we want to use a specific color in our program, we’ll make constants to hold tuples that are named after the color the tuple represents:
11. # Set up the colors.
12. BLACK = (0, 0, 0)
13. WHITE = (255, 255, 255)
14. RED = (255, 0, 0)
15. GREEN = (0, 255, 0)
16. BLUE = (0, 0, 255)
The first value in the tuple determines how much red is in the color. A value of 0 means there’s no red in the color, and a value of 255 means there’s a maximum amount of red in the color. The second value is for green, and the third value is for blue. These three integers form an RGB tuple.
For example, the tuple (0, 0, 0) has no red, green, or blue. The resulting color is completely black, as in line 12. The tuple (255, 255, 255) has a maximum amount of red, green, and blue, resulting in white, as in line 13.
We’ll also use red, green, and blue, which are assigned in lines 14 to 16. The tuple (255, 0, 0) represents the maximum amount of red but no green or blue, so the resulting color is red. Similarly, (0, 255, 0) is green and (0, 0, 255) is blue.
You can mix the amount of red, green, and blue to get any shade of any color. Table 17-1 has some common colors and their RGB values. The web page https://www.nostarch.com/inventwithpython/ lists several more tuple values for different colors.
Table 17-1: Colors and Their RGB Values
Color
RGB value