Pygame Tutorial
Pygame Tutorial
1
Pygame
Audience
This tutorial is designed for software programmers who want to develop video games using
Python Programming language.
Prerequisites
Before proceeding with this tutorial, you need a basic knowledge on Python Programming
language, and an understanding of the game that is to be developed is also essential.
All the content and graphics published in this e-book are the property of Tutorials Point (I)
Pvt. Ltd. The user of this e-book is prohibited to reuse, retain, copy, distribute or republish
any contents or a part of contents of this e-book in any manner without written consent
of the publisher.
We strive to update the contents of our website and tutorials as timely and as precisely as
possible, however, the contents may contain inaccuracies or errors. Tutorials Point (I) Pvt.
Ltd. provides no guarantee regarding the accuracy, timeliness or completeness of our
website or its contents including this tutorial. If you discover any errors on our website or
in this tutorial, please notify us at contact@tutorialspoint.com
2
Pygame
Table of Contents
About the Tutorial ........................................................................................................................................... 2
Audience .......................................................................................................................................................... 2
Prerequisites .................................................................................................................................................... 2
3
Pygame
4
1. Pygame — Overview Pygame
Pygame is a popular Python library used for developing video games. It is free, open source
and cross-platform wrapper around Simple DirectMedia Library (SDL). Abstraction of SDL
functions provided by Pygame makes development of multi-media applications using
Python very easy.
Originally developed by Peter Shinners, Lenard Lindstrom, René Dudfield and others in Oct
2000, latest version of Pygame is 2.0.1, released in Dec 2020. In addition to SDL
functionality, Pygame also provides other features such as vector maths, collision
detection, camera and MIDI support etc. Pygame applications can be used on Android
based mobile phones also.
Environment Setup
Easiest way to install Pygame on any machine is by using PIP installer that comes with
standard Python distribution. Ensure that you have latest version of pip. It is recommended
to install Pygame in a new virtual environment using following command:
To verify if Pygame has been successfully installed, try and import pygame package and
check its version.
(pygmenv) C:\pygmenv>python
Python 3.7.4 (tags/v3.7.4:e09359112e, Jul 8 2019, 20:34:20) [MSC v.1916 64 bit
(AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import pygame
pygame 2.0.1 (SDL 2.0.14, Python 3.7.4)
5
Pygame
6
Pygame
7
2. Pygame — Hello World Pygame
First step is to import and initialize pygame modules with the help of init() function.
import pygame
pygame.init()
We now set up Pygame display window of preferred size, and give it a caption.
This will render a game window which needs to be put in an infinite event loop. All event
objects generated by user interactions such as mouse movement and click etc. are stored
in an event queue. We shall terminate the event loop when pygame.QUIT is intercepted.
This event is generated when user clicks the CLOSE button on the title bar.
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
Complete code for displaying Pygame window with Hello World caption is as follows:
pygame.init()
screen = pygame.display.set_mode((640, 480))
pygame.display.set_caption("Hello World")
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
8
Pygame
This window will be closed only if the close (X) button is clicked.
9
3. Pygame — Display modes Pygame
The size parameter is a tuple of width and height in pixels. If size is not set, the surface
will have the size of current resolution.
The flags parameter controls the type of display represented by following predefined
constants:
If the vsync parameter is set to 1, it is possible to get a display with vertical sync, but you
are not guaranteed to get one. The request only works at all for calls to set_mode() with
the pygame.OPENGL or pygame.SCALED flags set.
The display index 0 means the default display is used. Depth parameter will default to the
best and fastest color depth for the system. For given width and height, Pygame will
choose best mode available from list_modes().
pygame.display.mode_ok()
This function Pick the best color depth for a display mode. It is used to determine if a
requested display mode is available. It will return 0 if the display mode cannot be set.
Otherwise it will return a pixel depth that best matches the display asked for.
pygame.display.update()
This function will update the contents of the entire display.
10
4. Pygame — Locals module Pygame
import pygame,sys
from pygame.locals import *
pygame.init()
canvas=pygame.display.set_mode((400,300))
pygame.display.set_caption("Hello")
canvas.fill((0,0,0))
while True:
for event in pygame.event.get():
if(event.type == QUIT):
pygame.quit()
sys.exit(1)
11
5. Pygame — Color object Pygame
The Color class in Pygame is used to represent color of screen background, text, shapes
and all other Pygame objects. It constructed by passing color values for Red, Green, Blue
colors and optionally alpha value that represents opaque value. Each of these values range
between 0 to 255.
Default value of alpha is 255, meaning fully opaque. Individual attributes are accessible
and can be set.
Alternative color models like CMY, HSVA, HSLA and i1i2i3 can also be used.
We can use predefined string constants to represent RGBA color combinations. Some of
the predefined colors are listed below:
for k, v in THECOLORS.items():
THECOLORS[unicode_(k)] = v
13
6. Pygame — Event objects Pygame
QUIT None
VIDEORESIZE size, w, h
VIDEOEXPOSE None
USEREVENT Code
14
7. Pygame — Keyboard events Pygame
Pygame recognizes KEYUP and KEYDOWN events. The pygame.key module defines
functions useful for handling keyboard interaction. pygame.KEYDOWN and pygame.KEYUP
events are inserted in event queue when the keys are pressed and released. key attribute
is an integer ID representing every key on the keyboard.
pygame.init()
screen = pygame.display.set_mode((640, 480))
pygame.display.set_caption("Hello World")
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
if event.type == pygame.KEYDOWN:
key=pygame.key.name(event.key)
print (key, "Key is pressed")
if event.type == pygame.KEYUP:
key=pygame.key.name(event.key)
print (key, "Key is released")
Run the above code and press various keys while the Pygame window is active. Following
is a sample output on Python console.
q Key is pressed
q Key is released
right shift Key is released
1 Key is pressed
1 Key is released
enter Key is pressed
enter Key is released
backspace Key is pressed
backspace Key is released
x Key is pressed
x Key is released
15
Pygame
As we see, event.key attribute returns a unique identifier associated with each key. The
arrow keys left, right, up and down are used very often in a game situation. We can right
appropriate logic if a particular key press is detected.
16
8. Pygame — Mouse events Pygame
To obtain the coordinates of position of button down, we can use get_pos() function
associated with event object.
pygame.init()
screen = pygame.display.set_mode((640, 480))
pygame.display.set_caption("Hello World")
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
if event.type == pygame.MOUSEBUTTONDOWN:
pos=pygame.mouse.get_pos()
btn=pygame.mouse
print ("x = {}, y = {}".format(pos[0], pos[1]))
Run above code and press the mouse button at random positions on the game window.
x = 192, y = 160
x = 419, y = 245
x = 204, y = 405
x = 449, y = 17
x = 12, y = 15
if event.type == pygame.MOUSEMOTION:
pos=event.pos
17
Pygame
pygame.SYSTEM_CURSOR_ARROW arrow
pygame.SYSTEM_CURSOR_IBEAM i-beam
pygame.SYSTEM_CURSOR_WAIT wait
pygame.SYSTEM_CURSOR_CROSSHAIR crosshair
pygame.SYSTEM_CURSOR_HAND hand
pygame.mouse.set_system_cursor(pygame.SYSTEM_CURSOR_CROSSHAIR)
18
9. Pygame —Drawing shapes Pygame
Different shapes such as rectangle, circle, ellipse, polygon and line can be drawn on the
game window by using functions in pygame.draw module:
import pygame
pygame.init()
done = False
red = (255,0,0)
green = (0,255,0)
blue = (0,0,255)
white = (255,255,255)
if event.type == pygame.QUIT:
done = True
pygame.draw.polygon(screen, blue,
((25,75),(76,125),(275,200),(350,25),(60,280)))
19
Pygame
pygame.display.update()
Output
If an optional integer parameter is added to the functions, the shape will be drawn with
specified color as outline color. Number corresponds to thickness of the outline and
background color inside the shape.
Result
20
Pygame
21
10. Pygame — Loading image Pygame
The pygame.image module contains functions for loading and saving images from file or
file like object. An image is loaded as a Surface object which eventually is rendered on
Pygame display window.
img = pygame.image.load('pygame.png')
Next we obtain a rect object out of this Surface and then use Surface.blit() function to
render the image:
rect = img.get_rect()
rect.center = 200, 150
screen.blit(img, rect)
The complete program for displaying Pygame logo on the display window is as follows:
import pygame
pygame.init()
screen = pygame.display.set_mode((400, 300))
img = pygame.image.load('pygame.png')
done = False
bg = (127,127,127)
while not done:
for event in pygame.event.get():
screen.fill(bg)
rect = img.get_rect()
rect.center = 200, 150
screen.blit(img, rect)
if event.type == pygame.QUIT:
done = True
pygame.display.update()
Output
The output for the above code is as follows:
22
Pygame
The blit() function can take an optional special-flags parameter with one of the following
values:
BLEND_RGBA_ADD
BLEND_RGBA_SUB
BLEND_RGBA_MULT
BLEND_RGBA_MIN
BLEND_RGBA_MAX
BLEND_RGB_ADD
BLEND_RGB_SUB
BLEND_RGB_MULT
BLEND_RGB_MIN
BLEND_RGB_MAX
The pygame.Surface module also has a convert() function which optimizes the image
format and makes drawing faster.
The pygame.image module has a save() function that saves contents of Surface object to
an image file. Pygame supports the following image formats:
JPG BMP
PNG TGA
BMP JPEG
23
Pygame
PCX
TGA (uncompressed)
TIF
XPM
Following program draws three circles on the display surface and save it as a circles.png
file using image.save() function.
import pygame
pygame.init()
screen = pygame.display.set_mode((400, 300))
done = False
white=(255,255,255)
red = (255,0,0)
green = (0,255,0)
blue = (0,0,255)
bg = (127,127,127)
while not done:
for event in pygame.event.get():
screen.fill(bg)
if event.type == pygame.QUIT:
done = True
pygame.draw.circle(screen, red, (200,150), 60,2)
pygame.draw.circle(screen, green, (200,150), 80,2)
pygame.draw.circle(screen, blue, (200,150), 100,2)
pygame.display.update()
pygame.image.save(screen, "circles.png")
Output
24
Pygame
25
11. Pygame — Displaying Text in Window Pygame
To display text on the Pygame window, we need to obtain a font object first, with the help
of SysFont() function defined in pygame.font module.
fonts = pygame.font.get_fonts()
for f in fonts:
print(f)
Next we obtain a new Surface object for rendering Hello World text in the newly created
font with render() method of Font object.
We now need to blit the text Surface at the center of screen window.
import pygame
pygame.init()
screen = pygame.display.set_mode((400, 300))
done = False
white=(255,255,255)
red = (255,0,0)
green = (0,255,0)
blue = (0,0,255)
bg = (127,127,127)
26
Pygame
Output
In addition to SysFont() method, a Font object can also be obtained from a font file (having
.ttf extension) or a Python file object pointing towards the ttf file. It is also possible to
construct a font object with .ttc file. The font class defines following methods:
27
Pygame
Given below is example to use ttf and ttc files to render text
pygame.display.update()
In the above example, a predefined string has been rendered as a surface object. However,
it is possible to read key value of KEYDOWN event to interactively enter a string and
display it.
To begin with, we render an empty string. Next, we define the bounding rectangle and
then a cursor rectangle which is placed to overlap the text bounding rectangle. Each
keystroke identified in KEYDOWN event is appended to original empty string and
repeatedly rendered.
Following code initially displays a blank window. Each letter pressed will be displayed
alongside each other.
import pygame
pygame.init()
screen = pygame.display.set_mode((400, 300))
done = False
white=(255,255,255)
28
Pygame
red = (255,0,0)
green = (0,255,0)
blue = (0,0,255)
bg = (127,127,127)
text=""
while not done:
for event in pygame.event.get():
screen.fill(bg)
if event.type == pygame.QUIT:
done = True
if event.type == pygame.KEYDOWN:
text=text+event.unicode
font = pygame.font.SysFont("Arial", 36)
img = font.render(text, True, white)
rect = img.get_rect()
cursor = pygame.Rect(rect.topright, (3, rect.height))
img = font.render(text, True, white)
rect.size=img.get_size()
cursor.topleft = rect.topright
screen.blit(img,(200 - img.get_width() // 2, 150 - img.get_height() //
2))
pygame.display.update()
Run the above code and enter some text. Sample output is as follows:
29
Pygame
30
12. Pygame — Moving an image Pygame
image_filename = 'pygame.png'
import pygame
from pygame.locals import *
from sys import exit
pygame.init()
screen = pygame.display.set_mode((400,300), 0, 32)
pygame.display.set_caption("Moving Image")
img = pygame.image.load(image_filename)
x = 0
while True:
screen.fill((255,255,255))
for event in pygame.event.get():
if event.type == QUIT:
exit()
screen.blit(img, (x, 100))
x= x+0.5
if x > 400:
x = x-400
pygame.display.update()
The Pygame logo image starts displaying at left border and repeatedly shifts towards right.
If it reaches right border, its position is reset to left.
31
Pygame
In the following program, the image is displayed at (0,150) position to begin with. When
user presses arrow keys (left, right, up, down), the image changes its location by 5 pixels.
If a KEYDOWN event occurs, the program checks if the key value is K_LEFT, K_RIGHT,
K_UP or K_DOWN. The x coordinate changes by +5 or -5 if it is K_LEFT or K_RIGHT. Value
of y coordinate changes by -5 or +5 if key value is K_UP or K_DOWN.
image_filename = 'pygame.png'
import pygame
from pygame.locals import *
from sys import exit
pygame.init()
screen = pygame.display.set_mode((400,300))
pygame.display.set_caption("Moving with arrows")
img = pygame.image.load(image_filename)
x = 0
y= 150
while True:
screen.fill((255,255,255))
screen.blit(img, (x, y))
for event in pygame.event.get():
if event.type == QUIT:
exit()
if event.type == KEYDOWN:
if event.key == K_RIGHT:
32
Pygame
x= x+5
if event.key == K_LEFT:
x=x-5
if event.key == K_UP:
y=y-5
if event.key == K_DOWN:
y=y+5
pygame.display.update()
33
13. Pygame — Moving with Numeric pad keys Pygame
K_KP1 keypad 1
K_KP2 keypad 2
K_KP3 keypad 3
K_KP4 keypad 4
K_KP5 keypad 5
K_KP6 keypad 6
K_KP7 keypad 7
K_KP8 keypad 8
K_KP9 keypad 9
For left, right, up and down arrow press, x and y coordinates are
incremented/decremented as before. For diagonal movement, both coordinates are
changed as per direction. For instance, for K_KP7 key-press, both x and y are decremented
by 5, for K_KP9 x is incremented and y is decremented.
image_filename = 'pygame.png'
import pygame
from pygame.locals import *
from sys import exit
pygame.init()
screen = pygame.display.set_mode((400,300))
pygame.display.set_caption("Moving with arrows")
img = pygame.image.load(image_filename)
x = 0
y= 150
while True:
screen.fill((255,255,255))
screen.blit(img, (x, y))
for event in pygame.event.get():
if event.type == QUIT:
exit()
34
Pygame
if event.type == KEYDOWN:
if event.key == K_KP6:
x= x+5
if event.key == K_KP4:
x=x-5
if event.key == K_KP8:
y=y-5
if event.key == K_KP2:
y=y+5
if event.key == K_KP7:
x=x-5
y=y-5
if event.key == K_KP9:
x=x+5
y=y-5
if event.key == K_KP3:
x=x+5
y=y+5
if event.key == K_KP1:
x=x-5
y=y+5
pygame.display.update()
35
14. Pygame — Moving with mouse Pygame
(mx,my) = pygame.mouse.get_pos()
After capturing mx and my positions, the image is rendered with the help of bilt() function
on the Surface object at these coordinates.
Following program continuously renders the given image at moving mouse cursor position.
filename = 'pygame.png'
import pygame
from pygame.locals import *
from sys import exit
pygame.init()
screen = pygame.display.set_mode((400,300))
pygame.display.set_caption("Moving with mouse")
img = pygame.image.load(filename)
x = 0
y= 150
while True:
mx,my=pygame.mouse.get_pos()
screen.fill((255,255,255))
screen.blit(img, (mx, my))
for event in pygame.event.get():
if event.type == QUIT:
exit()
pygame.display.update()
36
15. Pygame — Moving Rectangular objects Pygame
The Pygame.Rect class has functionality to store and manipulate rectangular areas. A Rect
object can be constructed from left, top, width and height values. Functions in Rect class
enable copying, moving nd resizing the Rect object.
In addition to movement, Rect class has methods to test collision between rectangles.
copy() Returns a new rectangle having the same position and size as the
original.
move() Returns a new rectangle that is moved by the given offset. The x
and y arguments can be any integer value, positive or negative.
inflate(x,y) Returns a new rectangle with the size changed by the given offset.
Negative values will shrink the rectangle.
union(Rect) Returns a new rectangle that completely covers the area of the
two provided rectangles.
contains(Rect) Returns true when the argument is completely inside the Rect.
37
Pygame
In the following program, a Rect object is drawn with red outline. Using copy() method,
its clone is created for movement. The movement is effected by move_ip() method. The
arrow keys move the position of copied rectangle by incrementing/decrementing x/y
coordinate by + or -5 pixels.
import pygame
pygame.init()
screen = pygame.display.set_mode((400,300))
rect2=rect1.copy()
running = True
x=0
y=0
while running:
if event.type == QUIT:
running = False
if event.type == KEYDOWN:
if event.key==K_LEFT:
x= -5
y=0
if event.key == K_RIGHT:
x=5
y=0
if event.key == K_UP:
x=0
y = -5
if event.key == K_DOWN:
x=0
y=5
rect2.move_ip(x,y)
38
Pygame
screen.fill((127,127,127))
pygame.display.update()
pygame.quit()
The following output shows rectangle with red outline is the original rectangle. Its copy
keeps moving responding to arrow keys and has blue outline
while running:
for event in pygame.event.get():
if event.type == QUIT:
running = False
if event.type == KEYDOWN:
if event.key==K_LEFT:
x= -5
y=0
if event.key == K_RIGHT:
x=5
39
Pygame
y=0
if event.key == K_UP:
x = 0
y = -5
if event.key == K_DOWN:
x = 0
y = 5
rect2.inflate_ip(x,y)
screen.fill((127,127,127))
pygame.draw.rect(screen, (255,0,0), rect1, 1)
pygame.draw.rect(screen, (0,0,255), rect2, 5)
pygame.display.update()
To make the rectangle move by detecting MOUSEMOTION event, we need to first press
the mouse inside the original rectangle. To verify whether mouse position is inside the
rectangle, we use collidepoint() method of the Rect object. While the mouse is in motion,
the rectangle object is moved in place by move_ip() method. Movement shall stop when
mouse is released.
import pygame
from pygame.locals import *
40
Pygame
41
Pygame
import pygame
from pygame.locals import *
from sys import exit
pygame.init()
screen = pygame.display.set_mode((400,300))
pygame.display.set_caption("Draw Rectangle with Mouse")
42
Pygame
screen.fill((127,127,127))
x=0
y=0
w=0
h=0
drawmode=True
running = True
while running:
for event in pygame.event.get():
if event.type == QUIT:
running = False
if event.type == MOUSEBUTTONDOWN:
x,y = pygame.mouse.get_pos()
drawmode = True
if event.type == MOUSEBUTTONUP:
x1,y1 = pygame.mouse.get_pos()
w=x1-x
h=y1-y
drawmode= False
rect = pygame.Rect(x,y,w,h)
if drawmode == False:
pygame.draw.rect(screen, (255,0,0), rect)
pygame.display.flip()
pygame.quit()
Output
43
Pygame
44
16. Pygame — Use Text as Buttons Pygame
Button is an important element in a typical game window. We can use a text or image
surface object as button, so that when clicked it can fire a certain action.
In order to draw a border around these buttons obtain their Rect object.
rect1 = text1.get_rect(topleft=(10,10))
rect2 = text2.get_rect(topleft= (100,10))
rect3 = text3.get_rect(topleft= (200,10))
Inside the event loop, blit the text buttons with red border around them.
screen.blit(text1, rect1)
pygame.draw.rect(screen, (255,0,0),rect1,2)
screen.blit(text2, rect2)
pygame.draw.rect(screen, (255,0,0),rect2,2)
pygame.draw.rect(screen, (255,0,0),rect3,2)
screen.blit(text3, rect3)
Use collidepoint() function of Rect object to identify which button has been clicked.
if event.type == pygame.MOUSEBUTTONDOWN:
if rect1.collidepoint(event.pos):
msg = "START Button was pressed"
if rect2.collidepoint(event.pos):
msg = "PLAY Button was pressed"
if rect3.collidepoint(event.pos):
msg = "STOP Button was pressed"
45
Pygame
import pygame
pygame.init()
screen = pygame.display.set_mode((400, 300))
done = False
rect1 = text1.get_rect(topleft=(10,10))
rect2 = text2.get_rect(topleft= (100,10))
rect3 = text3.get_rect(topleft= (200,10))
bg = (127,127,127)
msg=" "
screen = pygame.display.set_mode((400,300))
screen.fill(bg)
while not done:
for event in pygame.event.get():
screen.blit(text1, rect1)
pygame.draw.rect(screen, (255,0,0),rect1,2)
screen.blit(text2, rect2)
pygame.draw.rect(screen, (255,0,0),rect2,2)
pygame.draw.rect(screen, (255,0,0),rect3,2)
screen.blit(text3, rect3)
if event.type == pygame.QUIT:
done = True
if event.type == pygame.MOUSEBUTTONDOWN:
if rect1.collidepoint(event.pos):
msg = "START Button was pressed"
if rect2.collidepoint(event.pos):
46
Pygame
pygame.display.update()
When each button is clicked, display window shows the following output:
47
Pygame
48
17. Pygame — Transforming Images Pygame
This function can flip the surface object either horizontally, vertically or both. The
orientation is decied by two bool parameters.
pygame.transform.flip(img2,True, False)
pygame.transform.flip(img2,False, True)
49
Pygame
In the following example, pygame logo image is displayed normally and flipping in both
directions. First obtained flipped surface from original image object, fetch its Rect object
and then blit it. To render horizontally fliiped image,
img1 = pygame.image.load('pygame.png')
img2=img1
img2=pygame.transform.flip(img2,True, False)
#inside event loop
rect2 = img2.get_rect()
rect2.center = 200, 150
screen.blit(img2, rect2)
The complete code for rendering original Pygame logo and its flipped images is as follows:
import pygame
pygame.init()
screen = pygame.display.set_mode((400, 300))
pygame.display.set_caption("Flip image")
img1 = pygame.image.load('pygame.png')
img2=img1
img3=img1
img2=pygame.transform.flip(img2,True, False)
img3=pygame.transform.flip(img3, False, True)
done = False
bg = (127,127,127)
while not done:
for event in pygame.event.get():
screen.fill(bg)
rect1 = img1.get_rect()
rect1.center = 200, 50
screen.blit(img1, rect1)
rect2 = img2.get_rect()
rect2.center = 200, 150
screen.blit(img2, rect2)
rect3 = img3.get_rect()
rect3.center = 200, 250
screen.blit(img3, rect3)
50
Pygame
if event.type == pygame.QUIT:
done = True
pygame.display.update()
rotate(Surface, angle)
import pygame
pygame.init()
screen = pygame.display.set_mode((400, 300))
pygame.display.set_caption("rotate image")
img1 = pygame.image.load('pygame.png')
img2=img1
img3=img1
img2=pygame.transform.rotate(img2,90)
img3=pygame.transform.rotate(img3, -90)
done = False
bg = (127,127,127)
while not done:
for event in pygame.event.get():
screen.fill(bg)
51
Pygame
rect1 = img1.get_rect()
rect1.center = 200, 50
screen.blit(img1, rect1)
rect2 = img2.get_rect()
rect2.center = 100, 200
screen.blit(img2, rect2)
rect3 = img3.get_rect()
rect3.center = 300,200
screen.blit(img3, rect3)
if event.type == pygame.QUIT:
done = True
pygame.display.update()
The laplacian() function extracts outline of the surface object. The function just takes one
argument, the image object itself.
import pygame
pygame.init()
screen = pygame.display.set_mode((400, 300))
pygame.display.set_caption("Laplacian of image")
img1 = pygame.image.load('pygame.png')
52
Pygame
img2=img1
img2=pygame.transform.laplacian(img2)
done = False
bg = (127,127,127)
while not done:
for event in pygame.event.get():
screen.fill(bg)
rect1 = img1.get_rect()
rect1.center = 200, 50
screen.blit(img1, rect1)
rect2 = img2.get_rect()
rect2.center = 200, 200
screen.blit(img2, rect2)
if event.type == pygame.QUIT:
done = True
pygame.display.update()
To make the Surface object move along with mouse movement, calculate the x, y
coordinates from the center of the image. We also calculate the center-mouse distance d.
The atan2(y, x) math function allows to find the rotation angle. We need to transform
radians in degrees. From the distance mouse-center we calculate the scale argument.
mouse = event.pos
53
Pygame
x = mouse[0] - 200
y = mouse[1] - 150
d = math.sqrt(x ** 2 + y ** 2)
angle = math.degrees(-math.atan2(y, x))
scale = abs(5 * d / 400)
Finally, we use rotzoom() function which performs combined rotation and scaling
transform.
Following code renders Pygame logo image that can be rotated in accordance with mouse
movement.
if event.type == pygame.QUIT:
done = True
if event.type == MOUSEMOTION:
mouse = event.pos
x = mouse[0] - 200
y = mouse[1] - 150
d = math.sqrt(x ** 2 + y ** 2)
angle = math.degrees(-math.atan2(y, x))
scale = abs(5 * d / 400)
img2 = pygame.transform.rotozoom(img1, angle, scale)
rect = img2.get_rect()
rect.center = (200,150)
screen.blit(img2, rect)
54
Pygame
pygame.display.update()
Run above code, try and move mouse cursor along display window. The image shall rotate
and either shrink or grow accordingly.
55
18. Pygame — Sound objects Pygame
Use of music and sounds make any computer game more engaging. Pygame library
supports this feature through pygame.mixer module. This module contains Sound class
for loading Sound objects and controlling playback. All sound playback is mixed in
background threads. For less laggy sound use a smaller buffer size.
To obtain Sound object from a sound file or file object, use following constructor:
stop() This will stop the playback of this Sound on any active
Channels.
fadeout(time) This will stop playback of the sound after fading it out over
the time argument in milliseconds.
In following example, a text button is rendered at the bottom of display window. A space
key fires an arrow upwards accompanied by a sound playing.
Inside the game event loop, for a space key detected, an arrow object is place above the
SHOOT button and repeatedly rendered with decrementing y coordinate. The shooting
sound is also played at the same time.
sound=pygame.mixer.Sound("sound.wav")img=pygame.image.load("arrow.png")
rect2=img.get_rect(midtop=(200, 270))
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_SPACE:
56
Pygame
print ("space")
if kup==0:
screen.blit(img, (190,y))
kup=1
if kup==1:
y=y-1
screen.blit(img, (190,y))
sound.play()
if y<=0:
kup=0
y=265
import pygame
from pygame.locals import *
pygame.init()
screen = pygame.display.set_mode((400, 300))
done = False
white = (255,255,255)
bg = (127,127,127)
sound=pygame.mixer.Sound("sound.wav")
font = pygame.font.SysFont("Arial", 14)
text1=font.render(" SHOOT ", True, bg)
rect1 = text1.get_rect(midbottom=(200,300))
img=pygame.image.load("arrow.png")
rect2=img.get_rect(midtop=(200, 270))
kup=0
psmode=True
screen = pygame.display.set_mode((400,300))
screen.fill(white)
y=265
while not done:
if event.type == pygame.QUIT:
sound.stop()
done = True
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_SPACE:
print ("space")
if kup==0:
screen.blit(img, (190,y))
kup=1
if kup==1:
y=y-1
screen.blit(img, (190,y))
sound.play()
if y<=0:
kup=0
y=265
pygame.display.update()
58
19. Pygame — Mixer channels Pygame
The Sound object can be played on a specific channel instead of the default channel
automatically chosen. First create a channel object using the following command:
pygame.mixer.Channel(id)
59
20. Pygame — Playing music Pygame
The mixer also has a special streaming channel for music playback and is accessed through
the pygame.mixer.musicpygame module for controlling streamed audio module. The
difference between the music playback and regular Sound playback is that the music is
streamed, and never actually loaded all at once. The mixer system only supports a single
music stream at once.
First of all, we need to load the music from a music file. Pygame can load WAV, MP3, or
OGG files.
pygame.mixer.music.load(filename or object)
This will load a music filename/file object and prepare it for playback. If a music stream is
already playing it will be stopped. This does not start the music playing. The playback is
controlled by following functions:
This will play the loaded music stream. If the music is already playing it will be restarted.
loops argument tells how many times to repeat the music. The music repeats indefinitely
if this argument is set to -1. start denotes the music starts playing from. The position as
time in seconds. fade_ms argument makes the music start playing at 0 volume and fade
up to full volume over the given time.
unpause() This will resume the playback of a music stream after it has been
paused.
set_pos(pos) This sets the position in the music file where playback will start.
In the following program, a music file starts playing on clicking PLAY button. The PAUSE
button acts as a toggle to pause/unpause play. Click on STOP stops the playback.
import pygame
pygame.init()
screen = pygame.display.set_mode((400, 300))
60
Pygame
done = False
white = (255,255,255)
pygame.mixer.music.load("mario_theme.wav")
font = pygame.font.SysFont("Arial", 14)
text1=font.render(" PLAY ", True, white)
text2=font.render(" PAUSE ", True, white)
text3=font.render(" STOP ", True, white)
rect1 = text1.get_rect(topleft=(10,10))
rect2 = text2.get_rect(topleft= (100,10))
rect3 = text3.get_rect(topleft= (200,10))
bg = (127,127,127)
psmode=True
screen = pygame.display.set_mode((400,300))
screen.fill(bg)
while not done:
for event in pygame.event.get():
screen.blit(text1, rect1)
pygame.draw.rect(screen, (255,0,0),rect1,2)
screen.blit(text2, rect2)
pygame.draw.rect(screen, (255,0,0),rect2,2)
pygame.draw.rect(screen, (255,0,0),rect3,2)
screen.blit(text3, rect3)
if event.type == pygame.QUIT:
done = True
if event.type == pygame.MOUSEBUTTONDOWN:
if rect1.collidepoint(event.pos):
pygame.mixer.music.play()
if rect2.collidepoint(event.pos):
if psmode==True:
pygame.mixer.music.pause()
psmode=False
else:
if psmode==False:
pygame.mixer.music.unpause()
psmode=True
61
Pygame
if rect3.collidepoint(event.pos):
pygame.mixer.music.stop()
pygame.display.update()
62
21. Pygame — Playing Movie Pygame
Pygame has discontinued support for video files in its latest version. However, earlier
versions on Python 2.7 distributions, it can be still used. For this section, Pygame 1.9.2
and Python 2.7.18 has been used.
The pygame.movie module supports playback video and audio from basic encoded MPEG-
1 video files. Movie playback happens in background threads, which makes playback easy
to manage. the pygame.mixerpygame module for loading and playing sounds module must
be uninitialized if the movie’s sound is to be played.
movie = pygame.movie.Movie('sample.mpg')
import pygame
FPS = 60
63
Pygame
pygame.init()
clock = pygame.time.Clock()
movie = pygame.movie.Movie('sample_640x360.mpg')
screen = pygame.display.set_mode(movie.get_size())
movie_screen = pygame.Surface(movie.get_size()).convert()
movie.set_display(movie_screen)
movie.play()
playing = True
while playing:
for event in pygame.event.get():
if event.type == pygame.QUIT:
movie.stop()
playing = False
screen.blit(movie_screen,(0,0))
pygame.display.update()
clock.tick(FPS)
pygame.quit()
64
22. Pygame — Using Camera module Pygame
Earlier versions of Pygame upto 1.9.6 contain pygame.camera module. This module
contains functionality to capture camera feed on the game window and grab an image
from it. The camera devices available to the system are enumerated in a list returned by
list_cameras() method.
pygame.camera.list_cameras()
To initialize a camera object, use camera id, resolution and format arguments.
The default format is RGB. Width and height parameters are by default 640x480.
Following programs captures live feed from computer’s default web camera.
import pygame
import pygame.camera
pygame.init()
gameDisplay = pygame.display.set_mode((640,480))
pygame.camera.init()
print (pygame.camera.list_cameras())
cam = pygame.camera.Camera(0)
cam.start()
65
Pygame
while True:
img = cam.get_image()
gameDisplay.blit(img,(0,0))
pygame.display.update()
for event in pygame.event.get() :
if event.type == pygame.QUIT :
cam.stop()
pygame.quit()
exit()
Please note that on Windows OS, you may have to install Videocapture module.
66
23. Pygame — Load cursor Pygame
Pygame can let you control system cursor. Onlu black and white cursors can be used in
Pygame. The pygame.cursors module defines contain predefined cursor enumerations.
pygame.cursors.arrow
pygame.cursors.diamond
pygame.cursors.broken_x
pygame.cursors.tri_left
pygame.cursors.tri_right
The arrow cursor is the default choice. To use another cursor, we use set_cursor() function
in pygame.mouse module.
pygame.mouse.set_cursor(pygame.cursors.broken_x)
In the following example, this cursor can be seen on the display window.
import pygame,sys
from pygame.locals import *
pygame.init()
pygame.mouse.set_cursor(pygame.cursors.broken_x)
canvas=pygame.display.set_mode((400,300))
pygame.display.set_caption("Cursor")
while True:
for event in pygame.event.get():
if(event.type == QUIT):
pygame.quit()
sys.exit(1)
Output
67
Pygame
This module also contains a few cursors as formatted strings. To use them, use
pygame.cursors.compile() function.
pygame.cursors.thickarrow_strings
pygame.cursors.sizer_x_strings
pygame.cursors.sizer_y_strings
pygame.cursors.sizer_xy_strings
pygame.cursor.textmarker_strings
cursor = pygame.cursors.compile(pygame.cursors.textmarker_strings)
pygame.mouse.set_cursor((10,10), (0, 0), *cursor)
68
24. Pygame — Access CDROM Pygame
The pygame library has pygame.cdrom module that enables the program to manage
playback from audio CDs and DVDs. We need to explicitly initialize this module for its use.
The module defines all important CD class to represent the CDROM device. The constructor
requires ID of CDROM drive available, starting with 0.
>>> obj=pygame.cdrom.CD(0)
The CDROM object has access to following useful functions to control the playback.
>>> obj.init()
To find out how many tracks are present in the current CD:
>>> obj.get_numtracks()
8
69
Pygame
To start playing the required track, give its number to play() function.
>>> obj.play(4)
To pause, resume and stop the playback, we can use relevant functions listed above.
70
25. Pygame — The Sprite Module Pygame
Any bitmap that is drawn in our game window and that can move around is called a Sprite.
The pygame.sprite module contains classes and functionality useful in game development.
Along with a Sprite class to create collection of sprite objects, there are functions that
enable collision of sprite objects.
The Sprite class serves as a base class for different objects in the game. You may have to
put one more objects in groups. for that purpose, group classes are also provided.
Let us first develop a Sprite class by subclassing the sprite.Sprite class. Each object of this
Block class is a rectangular block filled with black color.
class Block(pygame.sprite.Sprite):
self.rect = self.image.get_rect()
for i in range(50):
block = Block(BLACK, 20, 15)
We create a block with red color call it player, and add it too to the list.
71
Pygame
all_sprites_list.add(player)
Inside the game’s event loop, detect the collision of red block (player) as it moves along
with mouse motion and black block and count the collisions.
72
Pygame
pygame.quit()
Run the above code. Move the player block to capture as many black blocks. The score
will be echoed on the console.
73
26. Pygame — PyOpenGL Pygame
First we shall import functions from OpenGL.GL and OpenGL.GLU (utility functions)
modules.
OpenGL specifies objects within the space by defining vertices or nodes. Lines between
vertices are called edges. The OpenGL code is written between glBegin and glEnd.
In our example, we shall draw a cube with following vertices and edges:
verticies = (
(1, -1, -1),
(1, 1, -1),
(-1, 1, -1),
(-1, -1, -1),
(1, -1, 1),
(1, 1, 1),
(-1, -1, 1),
(-1, 1, 1)
)
edges = (
(0,1),
(0,3),
(0,4),
(2,1),
(2,3),
(2,7),
(6,3),
(6,4),
(6,7),
(5,1),
74
Pygame
(5,4),
(5,7)
)
def Cube():
glBegin(GL_LINES)
for edge in edges:
for vertex in edge:
glVertex3fv(verticies[vertex])
glEnd()
We need to specify OPENGL and DOUBLEBUF flags in set_mode() function that sets up the
display.
pygame.display.set_mode(display, DOUBLEBUF|OPENGL)
Then call the gluPerspective() determines the perspective. The first parameter is the
degree of the field of view. The second value is the aspect ratio. The next two values here
are the znear and zfar, which are the near and far clipping planes.
Inside the Pygame event loop, first rotate the current matrix, clear the color buffer and
depth buffer, and call cube() function. Finally, we update the display window.
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
quit()
glRotatef(1, 3, 1, 1)
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT)
Cube()
pygame.display.flip()
pygame.time.wait(10)
import pygame
75
Pygame
verticies = (
(1, -1, -1),
(1, 1, -1),
(-1, 1, -1),
(-1, -1, -1),
(1, -1, 1),
(1, 1, 1),
(-1, -1, 1),
(-1, 1, 1)
)
edges = (
(0,1),
(0,3),
(0,4),
(2,1),
(2,3),
(2,7),
(6,3),
(6,4),
(6,7),
(5,1),
(5,4),
(5,7)
)
def Cube():
glBegin(GL_LINES)
for edge in edges:
for vertex in edge:
glVertex3fv(verticies[vertex])
76
Pygame
glEnd()
def main():
pygame.init()
display = (800,600)
pygame.display.set_mode(display, DOUBLEBUF|OPENGL)
glTranslatef(0.0,0.0, -5)
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
quit()
glRotatef(1, 3, 1, 1)
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT)
Cube()
pygame.display.flip()
pygame.time.wait(10)
main()
Run the above code. You will see a rotating cube on Pygame’s window surface. This is a
short demonstration of capability of PyOpenGL. A detailed discussion of this library is
beyond the scope of this tutorial.
77
Pygame
78
27. Pygame — Errors and Exception Pygame
Top level pygame module defines pygame.error as a standard Pygame exception. This
exception is raised whenever a pygame or SDL operation fails. You can catch any
anticipated problems and deal with the error. The exception is always raised with a
descriptive message about the problem.
Being derived from the RuntimeError exception, which can also be used to catch these
raised errors.
>>> try:
screen = pygame.display.set_mode((640, -1))
except pygame.error as e:
print ("unable to set display: ", e)
There are two more functions in this module to set and retrieve error message.
set_error(error_msg)
SDL maintains an internal error message. When pygame.error()standard pygame
exception is raised, this string is used as error message.
get_error()
It returns the string as error message of pygame.error() message.
79