Россия |
Graphics and Animation
Topics Covered In This Chapter:
- Software Libraries
- Installing Pygame
- Graphical user interfaces (GUI)
- Drawing primitives
- Creating a GUI window with Pygame
- Color in Pygame
- Fonts in Pygame
- Aliased and Anti-Aliased Graphics
- Attributes
- The pygame.font.Font Data Type
- The pygame.Surface Data Type
- The pygame.Rect Data Type
- The pygame.PixelArray Data Type
- Constructor Functions
- The type() Function
- Pygame's Drawing Functions
- The blit() Method for Surface Objects
- Events
- The Game Loop
- Animation
So far, all of our games have only used text. Text is displayed on the screen as output, and the player types in text from the keyboard as input. This is simple, and an easy way to learn programming. But in this chapter, we will make some more exciting games with advanced graphics and sound using the Pygame library. Chapters 17, 18, and 19 will teach you how to use the Pygame library to make games with graphics, animation, and sound. In these chapters we'll find source code for simple programs that are not games but demonstrate the Pygame concepts we've learned. "Dodger" will present the source code for a complete Pygame game using all the concepts you've learned.
A software library is code that is not meant to be run by itself, but included in other programs to add new features. By using a library a programmer doesn't have to write the entire program, but can make use of the work that another programmer has done before them. Pygame is a software library that has modules for graphics, sound, and other features that games commonly use.
Installing Pygame
Pygame does not come with Python. Like Python, Pygame is available for free. You will have to download and install Pygame, which is as easy as downloading and installing the Python interpreter. In a web browser, go to the URL http://pygame.org and click on the "Downloads" link on the left side of the web site. This book assumes you have the Windows operating system, but Pygame works the same for every operating system. You need to download the Pygame installer for your operating system and the version of Python you have installed (3.1).
You do not want to download the "source" for Pygame, but rather the Pygame for your operating system. For Windows, download the pygame-1.9.1.win32-py3.1.msi file. (This is Pygame for Python 3.1 on Windows. If you installed a different version of Python (such as 2.5 or 2.4) download the .msi file for your version of Python.) The current version of Pygame at the time this book was written is 1.9.1. If you see a newer version on the website, download and install the newer Pygame. For Mac OS X and Linux, follow the directions on the download page for installation instructions.
On Windows, double click on the downloaded file to install Pygame. To check that Pygame is install correctly, type the following into the interactive shell:
>>> import pygame
If nothing appears after you hit the Enter key, then you know Pygame has successfully been installed. If the error ImportError: No module named pygame appears, then try to install Pygame again (and make sure you typed import pygame correctly).
This chapter has five small programs that demonstrate how to use the different features that Pygame provides. In the last chapter, you will use these features for a complete game written in Python with Pygame.
A video tutorial of how to install Pygame is available from this book's website at http://inventwithpython.com/videos/.
Hello World in Pygame
We are going to create a new "Hello World!" program, just like you created at the beginning of the book. This time, we will use Pygame to make "Hello world!" appear in a graphical user interface (GUI, which is pronounced "gooey") window. A graphical user interface gives you a window that color, shapes, and images can be drawn on by your program, as well as accepting mouse input (and not just keyboard input). The basic shapes that we draw on the screen are called drawing primitives. GUI windows are used instead of the text window (also called a console window or a terminal window) that we used for all our previous games.
Pygame does not work well with the interactive shell because it relies on a game loop (we will describe game loops later). Because of this, you can only write Pygame programs and cannot send commands to Pygame one at a time through the interactive shell.
Pygame programs also do not use the input() function. There is no text input and output. Instead, the program displays output in a window by drawing graphics and text to the window. Pygame program's input comes from the keyboard and the mouse through things called events, which we will go over in the next chapter. However, if our program has bugs that cause Python to display an error message, the error message will show up in the console window.
You can also use print() calls to display text in the console window, however in Pygame the print() function is only used for temporarily printing messages to help you find bugs in your program. It can be useful to print out the values of variables while your program is running so that you can make sure it is working correctly.
You can also look up information about how to use the Pygame library by visiting the web site http://pygame.org/docs/ref/.
Hello World's Source Code
Type in the following code into the file editor, and save it as pygameHelloWorld.py. Or you can download this source code by going to this book's website at http://inventwithpython.com/chapter17
pygameHelloWorld.py
This code can be downloaded from http://inventwithpython.com/pygameHelloWorld.py If you get errors after typing this code in, compare it to the book's code with the online diff tool at http://inventwithpython.com/diff or email the author at al@inventwithpython.com
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, 2 55) 17 . 18. # set up 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, (12 0, 60), (60, 120) ) 36. pygame.draw.line(windowSurface, BLUE, (60, 120), (12 0, 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()
Running the Hello World Program
When you run this program, you should see a new GUI window appear which looks like Figure 17.2.
What is nice about using a GUI instead of a console is that the text can appear anywhere in the window, not just after the previous text we have printed. The text can be any color or size.
One thing you may notice is that Pygame uses a lot of tuples instead of lists. Remember that tuples are almost the same as lists (they can contain other values) except they are typed with parentheses ( and ), instead of square brackets [ and ]. The main difference is that once you create a tuple, you cannot change, add, or remove any values in the tuple. For technical reasons, knowing that the contents of the tuple never change allows Python to handle this data more efficiently, which is why Pygame uses tuples instead of lists.
Importing the Pygame Module
Let's go over each of these lines of code and find out what they do.
1. import pygame, sys 2. from pygame.locals import *
First we need to import the pygame module so we can call the functions in the Pygame software library. You can import several modules on the same line by delimiting the module names with commas. Line 1 imports both the pygame and sys modules.
The second line imports the pygame.locals module. This module contains many constant variables that we will use with Pygame such as QUIT or K_ESCAPE (which we will explain later). However, using the form from moduleName import * we can import the pygame.locals module but not have to type pygame.locals in front of each time we use the module's functions and variables in our program. The * symbol means we should import everything inside the module.
The pygame.locals module contains some constant variables we will use in this program . 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 is better to use the full function name so that you know which module the exit() is in.)
The pygame.init() Function
4. # set up pygame 5. pygame.init()
The Pygame software library has some initial code that needs to be run before we can use it. All Pygame programs must run this code by calling the pygame.init() after importing the pygame module but before calling any other Pygame functions.
The pygame.display.setmode() and pygame.display.setcaption() Functions
7. # set up the window 8. windowSurface = pygame.display.set_mode((500, 400), 0, 32) 9. pygame.display.set_caption('Hello world!')
Line 8 creates a GUI window for our program by calling the set_mode() method in the pygame.display module. (The display module is a module inside the pygame module. Pygame is so advanced that even the pygame module has its own modules!)
Just to avoid confusion, you should know the difference between the window that is created is different and the Windows operating system. The graphical user interface is printed as "window" (lower case and singular) and the Microsoft operating system is "Windows" (upper case and plural).
There are three parameters to the set_mode() method. The first parameter is a tuple of two integers for the width and height of the window, in pixels. A pixel is the tiniest dot on your computer screen. A single pixel on your screen can turn into any color. All the pixels on your screen work together to display all the pictures you see. To see how tiny a pixel is, look at the bottom right corner of the "Hello World!" window. This program sets just one pixel as white.
We want the window to be 500 pixels wide and 400 pixels high, so we use the tuple (500, 400) for the first parameter. To get the total number of pixels in our window, multiply the width and the height. Our window is made up of 20,000 pixels, and it doesn't even take up the entire computer screen!
The second parameter is for advanced GUI window options. You won't really need this for your games, so you can always just pass 0 for this parameter. The third parameter is another advanced option called the color depth. You can just pass the value 32.
The set_caption() call returns a pygame.Surface object (which we will call Surface objects for short). Objects are values of a data type that have methods as well as data. For example, strings are objects in Python because they have data (the string itself) and methods (such as lower() and split()). You can store objects in variables just like any other value. The Surface object represents the window and we will include the windowSurface variable in all of our calls to drawing functions.