Chapter 2. Getting Started with Pygame: The Pie Game

This chapter introduces a game library called Pygame that was developed to make it possible to draw graphics, get user input, do animation, and use a timer to make the game run at a consistent frame rate. We’re going to just get started with Pygame in this chapter, learn the basics of drawing shapes and text, and will be writing quite a bit of code along the way. As you will see, Pygame does more than just provide drawing functions for shapes and bitmaps. Pygame also provides services for getting user input, handling audio playback, and polling the mouse and keyboard. We will get to these additional topics in due time.

Here are the topics covered in this chapter:

  • Using the Pygame library

  • Printing text with fonts

  • Using looping to repeat actions

  • Drawing circles, rectangles, lines, and arcs

  • Creating The Pie Game

Examining the Pie Game

Our example in this chapter is called The Pie Game. The Pie Game uses Pygame to draw filled-in pie slices. To draw a pie slice in our Pie Game with Pygame, the user presses number keys corresponding to the pie pieces. We then use Pygame drawing functions to draw the pie pieces. The player wins by pressing the keys for all of the pieces without making a mistake.

The Pie Game.

Figure 2.1. The Pie Game.

Note

The Pie Game.

Pygame must be installed before you can use it, because Pygame is not packaged with Python. Download Pygame from http://www.pygame.org/download.shtml. It is important to get the right version of Pygame that goes with the version of Python you are using. This book uses Python 3.2 with Pygame 1.9. If you need help getting it installed, please see Appendix A for more details.

Using Pygame

The first step to using Pygame is to import the Pygame library into our Python program so it can be used.

import pygame

The next step is to import all of the constants in Pygame so they are more readily accessible in our code. This is optional but tends to make the code cleaner. Some Python programmers dislike importing everything from a library due to efficiency concerns, but this makes our code a whole lot easier to read.

from pygame.locals import *

Now we can initialize Pygame:

pygame.init()

Now that Pygame has been initialized, we have access to all of the resources of the library. The next order of business is to gain access to the display system and create a window. The resolution is up to you, but did you note that the screen width and height parameters are enclosed in parentheses? The (600,500) pair becomes a point with an x and y property. In Python, source code syntax is loosely enforced by the interpreter, so we can write code like this where a more strongly typed language—such as C++—would not allow it.

screen = pygame.display.set_mode((600,500))

Note

Using Pygame

An excellent Pygame reference manual is found online at: http://www.pygame.org/docs/index.html.

Printing Text

Pygame supports text output to the graphics window using pygame.font. To draw text, we must first create a font object:

myfont = pygame.font.Font(None,60)

The name of a TrueType font can be supplied to the pygame.font.Font() constructor, such as “Arial”, but using None (no quotes) causes the default Pygame font to be used. A point size of 60 is quite large, but this is a simple example. Now, drawing text is not a light process with Pygame; it’s a heavy process. Meaning, text is not just quickly drawn to the screen, it is rendered onto a surface which is then drawn to the screen. Because this is a rather time-consuming process, it is advised to create the text surface (or image) in memory first, and then draw the text as an image. When we simply must draw text in real time, that’s okay, but if the text doesn’t change, it’s better to pre-render the text onto an image.

white = 255,255,255
blue = 0,0,255
textImage = myfont.render("Hello Pygame", True, white)

The textImage object will be a surface that can be drawn with screen.blit(), our die-hard drawing function that will be used extensively in all of our games and demos! The first parameter is obviously the text message; the second parameter is a flag to anti-alias the font (to improve quality); the third parameter is the color (an RGB value).

To draw the text, the usual process is to clear the screen, do our drawing, and then refresh the display. Let’s see all three lines of code:

screen.fill(blue)
screen.blit(textImage, (100,100))
pygame.display.update()

Now, if you run the program at this point, what happens? Go ahead and give it a try. Did you see the window come up after running the program? Since there is no delay anywhere in our code, the window should come up and then close just as quickly. A delay is needed. But, instead of a delay, we’ll go a step further.

Looping

There are two problems with the simplistic example we’ve just seen. First, it just runs once and then quits. Second, there’s no way to get any user input (even if it did not just immediately exit). So, let’s look into correcting that oversight. First, we need a loop. This is done in Python with the while keyword. The while statement will execute the code following the colon until the condition is false. As long as the while condition is true, it will keep running:

while True:

Next, we will create an event handler. At this early stage, all we want to happen is for the window to stay up until the user closes it. The close event can be clicking the “X” at the upper-right corner of the window, or by just pressing any key. Note that the code is indented within the while loop. Any code that is indented after this point will be contained in the while loop.

while True:
    for event in pygame.event.get():
        if event.type in (QUIT, KEYDOWN):
            sys.exit()

Lastly, we add the drawing code and screen refresh indented in the while loop, and this wraps up the program. Just for the sake of learning, here is the complete program without any blank lines or comments. The output of the program is shown in Figure 2.2.

The Hello Pygame program.

Figure 2.2. The Hello Pygame program.

import pygame
from pygame.locals import *
white = 255,255,255
blue = 0,0,200
pygame.init()
screen = pygame.display.set_mode((600,500))
myfont = pygame.font.Font(None,60)
textImage = myfont.render("Hello Pygame", True, white)
while True:
    for event in pygame.event.get():
        if event.type in (QUIT, KEYDOWN):
            sys.exit()
    screen.fill(blue)
    screen.blit(textImage, (100,100))
    pygame.display.update()

Drawing Circles

We can draw many different shapes with the pygame.draw library. Figure 2.3 shows the circle drawn by the example code shown. To draw a circle, we use pygame.draw.circle(), and pass a number of parameters to customize the size, color, and position of the circle.

The Drawing Circles example.

Figure 2.3. The Drawing Circles example.

import pygame
from pygame.locals import *
pygame.init()
screen = pygame.display.set_mode((600,500))
pygame.display.set_caption("Drawing Circles")
while True:
    for event in pygame.event.get():
        if event.type in (QUIT, KEYDOWN):
            sys.exit()

    screen.fill((0,0,200))

    #draw a circle
    color = 255,255,0
    position = 300,250
    radius = 100
    width = 10
    pygame.draw.circle(screen, color, position, radius, width)

    pygame.display.update()

Drawing Rectangles

To draw a rectangle, we use the pygame.draw.rect() function with a number of parameters. The window displayed by this program is shown in Figure 2.4. This example is a little more advanced than the one before. Instead of just drawing a rectangle at the center of the screen, this example moves the rectangle! The way this works is, we keep track of the rectangle’s position outside of the while loop (with pos_x and pos_y), and create a pair of velocity variables (vel_x and vel_y). Inside the while loop, we can update the position using the velocity, and then some logic keeps the rectangle on the screen. The way this works is, any time the rectangle reaches an edge of the screen, the velocity is reversed!

The Drawing Rectangles example.

Figure 2.4. The Drawing Rectangles example.

import pygame
from pygame.locals import *
pygame.init()
screen = pygame.display.set_mode((600,500))
pygame.display.set_caption("Drawing Rectangles")

pos_x = 300
pos_y = 250
vel_x = 2
vel_y = 1
while True:
    for event in pygame.event.get():
        if event.type in (QUIT, KEYDOWN):
            sys.exit()

    screen.fill((0,0,200))

    #move the rectangle
    pos_x += vel_x
    pos_y += vel_y

    #keep rectangle on the screen
    if pos_x > 500 or pos_x < 0:
        vel_x = -vel_x
    if pos_y > 400 or pos_y < 0:
        vel_y = -vel_y

    #draw the rectangle
    color = 255,255,0
    width = 0 #solid fill
    pos = pos_x, pos_y, 100, 100
    pygame.draw.rect(screen, color, pos, width)

    pygame.display.update()

Drawing Lines

We can draw straight lines using the pygame.draw.line() function. Line drawing is a little more complex than drawing other shapes, only because both the start position and end position of the line must be supplied. We can draw the line in any color and with any desired line width. Figure 2.5 shows the example running.

The Drawing Lines example.

Figure 2.5. The Drawing Lines example.

import pygame
from pygame.locals import *
pygame.init()
screen = pygame.display.set_mode((600,500))
pygame.display.set_caption("Drawing Lines")

while True:
    for event in pygame.event.get():
        if event.type in (QUIT, KEYDOWN):
            sys.exit()

    screen.fill((0,80,0))

    #draw the line
    color = 100,255,200
    width = 8
    pygame.draw.line(screen, color, (100,100), (500,400), width)

    pygame.display.update()

Drawing Arcs

An arc is a partial circle that can be drawn with the pygame.draw.arc() function. This is another rather complex shape that requires additional parameters. We have to supply a rectangle that represents the boundary of the arc, beginning with the upper-left corner and then the width and height, within which the arc will be drawn. Next, we have to supply the starting angle and ending angle. Normally, we tend to think about angles in terms of degrees, but trigonometry works with radians, and that is the form of circle measurement we must use. To convert an angle to radians, we can use the math.radians() function, with the degree angle as the parameter. Since the math library is required, we have to import math at the top of the program. Figure 2.6 shows the output of the example listed below.

The Drawing Arcs example.

Figure 2.6. The Drawing Arcs example.

import math
import pygame
from pygame.locals import *
pygame.init()
screen = pygame.display.set_mode((600,500))
pygame.display.set_caption("Drawing Arcs")

while True:
    for event in pygame.event.get():
        if event.type in (QUIT, KEYDOWN):
            sys.exit()

    screen.fill((0,0,200))

    #draw the arc
    color = 255,0,255
    position = 200,150,200,200
    start_angle = math.radians(0)
    end_angle = math.radians(180)
    width = 8
    pygame.draw.arc(screen, color, position, start_angle, end_angle, width)

    pygame.display.update()

The Pie Game

The Pie Game is a very simple game that does not have much by way of difficulty, but it does have a rudimentary level of gameplay and a minor “goodie” when the player “wins.” The gameplay involves just pressing the number keys 1, 2, 3, and 4, in any order. As each number is pressed, the corresponding pie piece is drawn. When all four pie pieces are completed, then the pie changes color. The game is shown in Figure 2.7.

The Pie Game with two pieces drawn.

Figure 2.7. The Pie Game with two pieces drawn.

When the player finishes the entire pie, then the color changes to bright green and the numbers and pie shapes are drawn in bright green to reflect that the player has won! This might be a simple game, but it demonstrates a lot of important Pygame concepts that we must learn to become proficient with this library. This game also demonstrates basic logic code in Python, and believe it or not, the very important subject of state-based programming. You see, the four pie pieces are not drawn automatically just when the player presses the correct key (1, 2, 3, or 4). Instead, a state flag is set when a key is pressed, and that flag is used later to draw the pie pieces based on that flag. This is a very important concept, as it demonstrates how to handle events and user interaction indirectly.

import math
import pygame
from pygame.locals import *
pygame.init()
screen = pygame.display.set_mode((600,500))
pygame.display.set_caption("The Pie Game - Press 1,2,3,4")
myfont = pygame.font.Font(None, 60)

color = 200, 80, 60
width = 4
x = 300
y = 250
radius = 200
position = x-radius, y-radius, radius*2, radius*2

piece1 = False
piece2 = False
piece3 = False
piece4 = False

while True:
    for event in pygame.event.get():
        if event.type == QUIT:
            sys.exit()
        elif event.type == KEYUP:
            if event.key == pygame.K_ESCAPE:
                sys.exit()
            elif event.key == pygame.K_1:
                piece1 = True
            elif event.key == pygame.K_2:
                piece2 = True
            elif event.key == pygame.K_3:
                piece3 = True
            elif event.key == pygame.K_4:
                piece4 = True
               
    #clear the screen
    screen.fill((0,0,200))
   
    #draw the four numbers
    textImg1 = myfont.render("1", True, color)
    screen.blit(textImg1, (x+radius/2-20, y-radius/2))
    textImg2 = myfont.render("2", True, color)
    screen.blit(textImg2, (x-radius/2, y-radius/2))
    textImg3 = myfont.render("3", True, color)
    screen.blit(textImg3, (x-radius/2, y+radius/2-20))
    textImg4 = myfont.render("4", True, color)
    screen.blit(textImg4, (x+radius/2-20, y+radius/2-20))

    #should the pieces be drawn?
    if piece1:
        start_angle = math.radians(0)
        end_angle = math.radians(90)
        pygame.draw.arc(screen, color, position, start_angle, end_angle, width)
        pygame.draw.line(screen, color, (x,y), (x,y-radius), width)
        pygame.draw.line(screen, color, (x,y), (x+radius,y), width)
    if piece2:
        start_angle = math.radians(90)
        end_angle = math.radians(180)
        pygame.draw.arc(screen, color, position, start_angle, end_angle, width)
        pygame.draw.line(screen, color, (x,y), (x,y-radius), width)
        pygame.draw.line(screen, color, (x,y), (x-radius,y), width)
    if piece3:
        start_angle = math.radians(180)
        end_angle = math.radians(270)
        pygame.draw.arc(screen, color, position, start_angle, end_angle, width)
        pygame.draw.line(screen, color, (x,y), (x-radius,y), width)
        pygame.draw.line(screen, color, (x,y), (x,y+radius), width)
    if piece4:
        start_angle = math.radians(270)
        end_angle = math.radians(360)
        pygame.draw.arc(screen, color, position, start_angle, end_angle, width)
        pygame.draw.line(screen, color, (x,y), (x,y+radius), width)
        pygame.draw.line(screen, color, (x,y), (x+radius,y), width)
       
    #is the pie finished?
    if piece1 and piece2 and piece3 and piece4:
        color = 0,255,0

    pygame.display.update()

Summary

This chapter introduced the Pygame library, which will really make our exploration of Python a lot more fun than otherwise plain text output to the console would have been!

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.137.217.17