PyGame Guide/Printable version

From Wikibooks, open books for an open world
Jump to navigation Jump to search
Book logo

PyGame Guide

The current, editable version of this book is available in Wikibooks, the open-content textbooks collection, at

Permission is granted to copy, distribute, and/or modify this document under the terms of the Creative Commons Attribution-ShareAlike 3.0 License.


Rachel making the peace sign

Hey there!

Hi! My name is Rachel. I'm a game developer and a teacher, and I'm here to teach you a bit about making 2D video games with Python and PyGame!

What is Python and PyGame?

Well, Python is a programming language and PyGame is a game development library.

Wait... what's a library??

Woah, one step at a time! We will go over game development terminology as well as basic concepts that you'll need to know for how a 2D game works -- How you place an image at a particular spot on the screen, how to know when two objects are touching, how to tell when a button is clicked, etc.

But, for now, let's just start off with introductions! This is only the first page of the tutorial and I've gotta get a few things out of the way!

OK, what's up?

Well, I should probably tell you who I am, how to contact me if you find an error in this document, the document's license, and... you konw, maybe my website in case you want to check out some games I've made.

Contact[edit | edit source]

IF you have questions, comments, or fixes for this document, please feel free to email me at !

License[edit | edit source]

CC BY SA icon

This book is licensed under the CC-BY-SA 3.0 License license

This means that you can share the book with anyone, for any reason. Just make sure my name (and any other future contributors) show up in the text (that is, that we are attributed!)

About the author[edit | edit source]

Rachel Wil Sha Singh is a programmer/teacher/game developer from the Kansas City area. Rachel grew up in the Raytown, MO area and spent their tween and teen years learning to make video games - first with Visual Basic 5, then with C++, and learning lots of other things from there! Rachel's most popular tutorial is the YouTube-based series, "Beginner's Guide to Game Programming", made in 2008.

Rachel has worked as a web- and software-developer since 2010 after receiving their B.S. in Computer Science from UMKC. Rachel also runs a small startup called Moosader LLC.

Getting Ready

About this guide[edit | edit source]

Example game screenshot

What does this guide cover?

First, this guide covers the basic syntax and usage of the Python language in case you are coming from another language. If you've already spent time programming in Python, you can skip the "Python Crash Course" section.

Second, this guide also covers the PyGame basics that you will need in order to build a functioning 2D game. The "PyGame Crash Course" runs through all the basic functionality pretty quickly, complete with example code.

After we get the basics of Python and PyGame down, we will dive into building a few simple 2D games in "The PyGame Cook Book".

Finally, there is a "Quick Reference" guide for both Python and PyGame, followed by a Glossary in case you need a refresher on any terms used in this book.

Prerequisites[edit | edit source]

What prior experience do I need? This guide works best if you have already had some prior programming experience in an object oriented language, such as C++, C#, and/or Java. In the "Python Crash Course" chapter, I go over some of the basics of Python so that you can be familiar with its syntax, but it is not an introductory programming course and it doesn't cover theory and the basics you would have had in a previous course.

What if I haven't programmed before?

You might be able to get started with 2D programming using just this guide if you haven't had any programming classes before, but you will hit a wall on the difficulty of problems that you can solve -- but don't worry, there are plenty of free guides online that you can use to study up!

What is Python and PyGame?[edit | edit source]

Python Logo

Python is an interpreted high-level programming language. In this case, "high level" means further from machine code. "High level" doesn't mean it is harder - actually, high-level languages are generally easier to use than low-level languages like C. As a language, Python can be written in an Object-Oriented Style (which should be familiar if you're from the C++/C#/Java side of things), but it also supports other programming paradigms - or other ways of structuring and writing code. I prefer writing games using Object Oriented techniques.

PyGame is a library that can be used with Python. A library is pre-written code that can be reused in multiple programs. This usually includes functions and classes that provide new functionality.

PyGame handles features like:

  • Loading and drawing graphics
  • Loading and playing sounds
  • Loading fonts and drawing text
  • Detecting keyboard and mouse input

Additionally, PyGame is built to be cross-platform, so you can write a game on your machine, and your friends can run the game on Linux, Mac, Windows, or even mobile devices!

Setting up Python and PyGame[edit | edit source]

The PyGame Logo.

Downloading PyGame[edit | edit source]

The PyGame website has the downloads for PyGame, as well as a tutorial on getting started, documentation for PyGame, and even a directory of games made with PyGame. Once you create a game, you can put your game on the directory, too! The PyGame website is at

Windows[edit | edit source]

For Windows, you will download a version of PyGame from here:

Look for the "Windows" header and download the version of PyGame that contains "py2.7" in the title. At the time of writing, the latest version is pygame-1.9.1.win32-py2.7.msi.

Python Versions

Version 2 and Version 3 of Python have a lot of differences and are not always compatible between each other. This version of PyGame uses Python 2.7.

(Windows instructions work in progress)

Linux[edit | edit source]

(Linux instructions work in progress)

Linux screenshot - PyGame install in the package manager.png

If you're using Ubuntu, Linux Mint, or Debian, you should be able to install Python via the Synaptic Package Manager, or even the Software Manager.

Search for "pygame", and you should download the python-pygame package. It should also install the Python dependencies at the same time.

Mac[edit | edit source]

(Mac instructions work in progress)

For Mac, you will download a version of PyGame from here:

Look for the "Macintosh" header and download the version for py2.7.

Downloading a text editor[edit | edit source]

Source code is all text, so you will need a decent text editor to write with. The Windows default Notepad is a terrible program, so you should download something else.

Geany[edit | edit source]

Geany is a free, cross-platform editor. You can also install additional plugins into Geany to customize it. Download it at:

(Text editor instructions work in progress)

Testing it out[edit | edit source]

Let's make sure that Python and PyGame are working correctly with some small example programs. You can re-type the code given in this document, or you can download the files from the guide repository at

Making sure Python works[edit | edit source]

First, create a directory on your computer for your Python projects, and create a folder for this project (\Testing Python" or something). First we will build just a Python program, and then we will build a PyGame program.

In Geany, create a new file, and save it to your project directory as simple Make sure it has the .py extension - all Python source files must end with this.

Windows note!

If you're in Windows, your folder options might be set so that file extensions are hidden by default. You might want to set all extensions to be visible so that you don't get confused!

Add the following code into your source file:

print( "Hello, world!" )
for i in range( 1, 10 ):
  print( i )

If you're using Geany, you can run the Python program by hitting F5.

Example output[edit | edit source]

Once it has run, the Python program output should look like this:

Hello, world!

Making sure PyGame works[edit | edit source]

Next we will create a simple PyGame test to make sure we can get a window open. Create another source file named simple Paste in the following code. Don't worry if you don't understand the code yet - this is just to make sure everything was set up properly!

import pygame, sys
from pygame.locals import *

timer = pygame.time.Clock()
window = pygame.display.set_mode( ( 300, 300 ) )
pygame.display.set_caption( "Testing out PyGame!" )

# Game loop
while True:
  window.fill( pygame.Color( 50, 200, 255 ) )
  # Check input
  for event in pygame.event.get():
    if ( event.type == QUIT ):
  # Update screen
  timer.tick( 30 )

Once you run it, you should get a small window with a light blue background.

A small window with a light blue background

You can close the window once you're done.

What if it's not working?!

Sometimes this happens! If you're having trouble running the program, there are a few things you can do to debug it...

  • Double-check all text and symbols for typos - these kinds of errors are easy to make! Also make sure your capitalization is regular, PyThOn Is CaSe SeNsItIvE!
  • Download the files from repository and try running that instead. Compare my code and your code to see what differs.
  • Do a search for the error message that you're getting - chances are that somebody else has had that same problem!

How do I download the files from the repository?

You can find the repository at this link: Once there, you can use the Clone button if you're familiar with Git, or you can click on Downloads to find a link to download all the files to your computer.

What's next?

Good work! Next we will run through some of the features of Python so you can become familiar with its syntax!

Python Crash Course

A simple Hello World program:

print("Hello World")

2D Game Development Concepts

Birds-eye-view: How game programs work[edit | edit source]

If you’ve taken a programming class before, you might already understand that a program runs from the top → down, line-by-line, until it hits the end of the source code file. While it’s stepping through code, it will pause when waiting for the user’s input, then resume once it has it. Once the end of the file is hit, the program automatically quits, unless you’ve added some kind of loop in there to keep it running.

If we don’t want a program to quit automatically, we will usually put a program loop somewhere within, where the same kinds of tasks are done every cycle... This could be displaying a menu, having the user select where to go, and doing some operation, and then returning back to the menu. Similarly, a game isn’t very playable if it exits immediately once you launch it. A game also has a game loop where some common events are done every cycle of the game.

A program loop; The menu has three options: (1) Add, (2) Subtract, and (3) Exit. If the user selects (1), it goes to the Add function, then returns to the menu. If the user selects (2), it goes to the Subtract function, then returns to the menu. If the user selects (3), it leaves the loop and exits the program.

During a game, the set of code it does first - before the game loop begins - is setup or initialization code. This is where variables are initialized, assets are loaded into memory, and things get prepared for the game. Once it enters the game loop, the game will always check for player input (Did the player press the “right” arrow key? Did the player click a button?), update the game objects (Move all enemies towards the player by 5 pixels), and draw to the screen (Draw the background, the world, the player, and the enemies). We will write code for each of these types of events, but PyGame will help us out.

Of course, we can also write functions to handle specific tasks, but once a function is done executing, program flow continues at the line after the function call was made.

The coordinate plane[edit | edit source]

In computer graphics, (x, y) coordinates are used to place images and text on the screen. You might remember coordinate planes from algebra. While the same idea applies here, the coordinate plane is laid out a bit differently.

In computer graphics, the origin of the coordinate plane is commonly found at (0, 0). As you move to the right, the x value increases, and as you move down, the y coordinate increases.

A program loop for a game; First, there is the SETUP section. After SETUP, we enter the game loop, which contains: “handle player input”, “update game objects”, and “draw to the screen”. If the user quits, then we will leave the loop, clean up the game, and exit the program.

Variables[edit | edit source]

An illustration of sprite placement on a computer screen. The origin (0, 0) is at the top-left corner.

Variables are locations in memory where we can store data . This data can be as simple as numbers, or a string of text, or it can be more complicated, such as a coin-object or a non-player-character-object. As an example, each of our game characters will have an (x, y) coordinate so that the game knows where to draw the character to on the screen. A character might also have a score variable, or a name variable, or many other things.

It is better to use variables rather than hard-coding values throughout your entire program. It is easier to go back and make fixes or changes if the data is stored in variables - What if your character’s starting position in the level was wrong and you had to go back and update those coordinates in every level of the game? There are also rules you have to follow when naming your variables. You cannot have spaces in a variable name, you cannot start a variable name with a number (though it may contain numbers), and it cannot be a keyword (like if).

Functions[edit | edit source]

Functions are collections of instructions that can be run. A function has a name (like “AddToScore”), which can be used over and over. This way, you don’t have to write the same code every time you want to do the task: you just call the function!

Functions can have inputs and outputs. Inputs are usually called parameters and outputs are called the return values.

For example, if we had an AddToScore function, its input might be “How much do we add to the score?” and its output could be “What is the score after we add this amount?”

In code form, it would look something like this in Python:

def AddToScore( score, amount ):  # score and amount are the inputs
  score = score + amount          # adding onto the score variable
  return score                    # return the result of the math

Functions don’t always need to have inputs or outputs, it depends on what the function’s task is.

Classes[edit | edit source]

Classes are a way that we, the programmers, can create our own variable data-types. By default, we can use variables like integers (whole numbers) and strings (text in double-quotes), but if we want to make a game character that has multiple attributes, such as name, coordinates, level, etc., we can write a class to do this.

A class can contain member functions and variables, so that we can have functionality and attributes associated with our object.

Bunny object

Cool bunny sprite


  • score (integer)
  • xCoordinate (integer)
  • yCoordinate (integer)
  • name (string)


  • Move( direction )
  • AddToScore( amount )
  • DrawToScreen( window )

The great thing about classes is that, once you’ve defined one class, you can create as many variables of that class type as you want. In other words, once you implement a Player class, you could reuse the same code to make your player1, player2, player3, and player4!

PyGame Crash Course

The bare-minimum PyGame program[edit | edit source]

Your project folder and files[edit | edit source]

For the time being, we will store all of our source code in one .py file. Once your projects get larger, it is good to break out code into separate files, such as everything related to a given class in its own .py file.

When creating a new project in PyGame, all you need is one source file, but it is good to create a folder to contain the source code and all your images, fonts, and audio files in.

Usually, I'll create a folder named content or assets to store these multimedia files in, and keep the source code at the base level of my project folder. For example:

    • content/
      • graphics/
        • girl.png
        • gem.png
      • sounds/
        • hit.ogg
        • music.ogg

To access items within these paths, we use relative pathing. Anything in the base folder ("GAME FOLDER") is at the current directory, where your source file is. If you want to load an image, as part of the path you'd include the two folders within your "GAME FOLDER" base path.

pygame.image.load( "content/graphics/girl.png" );

Making a basic PyGame program[edit | edit source]

For a very basic PyGame program, we will at least need to do the following:

  1. Import the PyGame files
  2. Initialize the window
  3. Initialize the timer
  4. Create a game loop
  5. Check for input
  6. Update the game
  7. Draw to the screen
  8. Use the timer to regulate the framerate

We will cover loading files more in-depth later on, but for now let's look at the parts of my basic PyGame template. You can download the source code from repository, or follow along coding each little piece as I explain it.

Importing libraries[edit | edit source]

A library is code that has already been written ahead of time, and is packaged up so that it can be used in multiple programs. There are a lot of libraries for Python, and you can use multiple libraries at a time, but for now we just want the PyGame library.

import pygame
from pygame.locals import *

To pull in another library in Python, we use the import command. PyGame has a bunch of functions we can use to load in graphics, handle program speed, detect input, and more. The pygame.locals part contains shortcut named constants that are used as labels for event types, keyboard keys, and more. For now, you can take it for granted.

Initializing PyGame[edit | edit source]

To initialize PyGame, we need to use the following functions:

timer = pygame.time.Clock()
window = pygame.display.set_mode( ( 320, 320 ) )
pygame.display.set_caption( "Testing out PyGame!" )

Here, timer and window are variables. Variables are locations in memory where we can store data, and in this case the timer variable is an object that is responsible for making sure we have a constant frame-rate, and the window variable is where we will draw our text and graphics to. In Python, we don't need to declare variables before we use them (like we would in C++, Java, or C#). To create a variable, we just start using it. When we assign a value to the variable, it will figure out what the data type is on its own.

pygame.init() , pygame.display.set mode( ... ) , and pygame.display.set_caption( ... ) are all function calls. These are functions that are part of PyGame. Functions perform actions for us, though we don't need to know exactly how it works behind-the-scenes.

Within the parentheses of the functions we pass in arguments , which are essentially the inputs of the function. For example, in the set mode function, it takes in a width and height value, and it will set the screen to these dimensions. In this case, I've hard-coded it to 320 x 320 pixels.

The set caption function takes in a string, or a string of text. A string literal must be contained within double-quotes. This function sets the window's title bar text.

If you ran just the initialization code, a window would pop up and immediately close - that's because the program will read from top-to-bottom, and once it hits the bottom of the source file it will quit. This is where a game loop comes in.

The basic game loop[edit | edit source]

We want to make sure that the program keeps running until the user decides to quit. In order to do this, we can use a while loop.

done = False
while done == False:
  # Contents of the game loop

Contents of a code block are indented

In Python, the contents of a function, if statement, or loop must be indented by one level. In C++, you might be used to these internal code-blocks being contained in curly braces {}, but this rule is different for Python.

As another example to illustrate t his:

print( "Before the if statement" )

if ( a == b ):
  print( "Inside the if statement" )

print( "After the if statement" )

Within the if statement, the print( “Inside the if statement” ) is indented forward by one level. Once the if statement is done, we indent backward once. This is required, as part of Python’s syntax.

Detecting a quit event[edit | edit source]

Since we are sitting inside of a while loop, each cycle something might happen. You might update your character to move forward by a few pixels, or a timer might go down, or the user might hit one or more keys.

In order to detect user input, we iterate through all of the events, which are captured by PyGame. If we detect a QUIT event, we know the user wants to quit – they’ve hit the “X” button in the corner.

while done == False:
    # Check events...
    for event in pygame.event.get():
        if event.type == QUIT:
            done = True

Updating the screen[edit | edit source]

At the end of the game loop cycle, we will want to update the screen so it will actually re-draw everything to the screen. We also want to regulate the framerate so that we stick to 30 or 60 frames per second, and the speed of the game doesn’t change from computer-to-computer.

while done == False:
    # Check events...
    # [...]
    # Update screen
    timer.tick( 30 )

First test[edit | edit source]

The code so far should look like this. Right now if you run it, the game window will just be a small black screen.

import pygame
from pygame.locals import *

# Initialization
timer = pygame.time.Clock()
window = pygame.display.set_mode( ( 300 , 300 ) )
pygame.display.set_caption( "Testing out PyGame!" )

# Game loop
done = False
    while done == False:
    # Check input
    for event in pygame.event.get():
        if ( event.type == QUIT ):
            done = True
    # Update screen
    timer.tick( 30 )

Once it runs, it will look like this:

An empty PyGame window with a black background

Cleaning it up a little[edit | edit source]

It is good to organize your code, and periodically go back and refactor it to clean it up. If you never clean up your code, it will get messier and messier and messier, and be difficult to maintain or to keep adding on to it.

Additionally, it is better to use variables for data instead of hard-coding it in your function calls. This means you only have to update the data in one location (the variable assignment), and you won't have to go update a bunch of areas if you decide to change the data later on.

To refactor means to spend time cleaning up your code without modifying the core functionality - not adding any new features, simply cleaning up what you already have.

So, let's clean up the code above and add some variables to store information about the program.

Top of the program[edit | edit source]
import pygame
from pygame.locals import *

# Global variables
screenWidth = 300
screenHeight = 300
timer = None
window = None
fps = 30

Now if we need to know the dimensions of our game window, we simply need to use the screenWidth and screenHeight variables, instead of hard-coding 300 at every location.

Now we can change the initialization code to use these variables:

timer = pygame.time.Clock()
window = pygame.display.set_mode( ( screenWidth , screenHeight ) )
pygame.display.set_caption( "Testing out PyGame!" )

And at the end of the game loop, make sure to update the timer.tick function:

# (Inside the game loop...)
timer.tick( fps )

Creating color[edit | edit source]

Next, create a color so we aren’t just staring at a black empty window anymore. To create a color, we use the pygame.Color class. The variable we store the data in then becomes an object-variable.

# Create a color to use (text, drawing shapes)
bgColor = pygame.Color( 50, 200, 255 ) # Red (0-255), Green (0-255), Blue (0-255)

Within the parentheses, we’re passing in values for red, green, and blue. The color above will be a light blue. If you want to re-use the same color many times (for example, when drawing text), it is good to store the color in a variable so you can adjust the color in one place without updating it over and over everywhere in the code.

Within the game loop (right after while done == False:while done is False:), add the following:

# (Inside the game loop...)
window.fill( bgColor )

When you run the program, the game screen should be blue now.

An empty game screen, but it is blue this time.

Loading images[edit | edit source]

We can also load images and store these images in variables. Save the following two graphics to your Python project. Ideally, create a content folder and a graphics folder within it.

Simple cool bunny sprite
Pixel art grass image

When you’re loading images, it should be outside of the game loop. Think of all of the code before the while done == False: as initialization code.

Load images:

# Load graphics
imgGrass = pygame.image.load( "content/graphics/grass.png" )
imgBunny = pygame.image.load( "content/graphics/bunny.png" )

And then draw them to the screen within the game loop with:

while done == False:
    # (Get input) [...]
    # Draw images
    window.blit( imgGrass, imgGrass.get_rect() )
    window.blit( imgBunny, imgBunny.get_rect() )
    # Update screen
    # [...]

Second test[edit | edit source]

Here is the full code, though I have created a function called InitPygame and put my init code within it.

import pygame, sys
from pygame.locals import *

screenWidth = 300
screenHeight = 300
timer = None
window = None
fps = 30

# Blank color
bgColor = pygame.Color( 50, 200, 255 )

# Load graphics
imgGrass = pygame.image.load( "content/graphics/grass.png" )
imgBunny = pygame.image.load( "content/graphics/bunny.png" )

# Initialization function
def InitPygame( screenWidth, screenHeight ):
    global window
    global timer
    timer = pygame.time.Clock()
    window = pygame.display.set_mode( ( screenWidth, screenHeight ) )
    pygame.display.set_caption( "Testing out PyGame!" )

# Call the initialization function
InitPygame( screenWidth, screenHeight )

# Game loop
done = False
while done == False:
    # Check input
    for event in pygame.event.get():
        if ( event.type == QUIT ):
            done = True
    # Draw graphics
    window.fill( bgColor )
    window.blit( imgGrass, ( 0, 0 ) ) # draw at (0,0)
    window.blit( imgBunny, ( 0, 0 ) ) # draw at (0,0)
    # Update screen
    timer.tick( fps )

Example PyGame window with graphics

Documentation links[edit | edit source]

Images[edit | edit source]

In the last example we loaded some images, but let’s look closer at these functions, and some other image-related functions that PyGame provides for us. To load an image into the program, you will use the pygame.image.load function.

Load an image[edit | edit source]


  • Inputs: filename (string)
  • Outputs: image surface object (store it in a variable)

When making a function call, any inputs go within the parentheses ( ) of the function. Since the input here is a string, the path to your image file should be contained within double-quotes like


And any outputs should be stored in a variable using an assignment statement.

returnStorage = FunctionCall( inputs )

The call to pygame.image.load will look like this:

imgGrass = pygame.image.load( "content/graphics/grass.png" )


  • The file path is relative - this means that it’s in relation to the

current path of the source code file you’re working in. For me, content is a folder at the same level as my .py file. Use forward-slashes, /, to differentiate between folders; the graphics folder is inside the content folder, and the grass.png image is within the graphics folder.

  • Store the result of the function in a variable - otherwise, it will

load the image but you won’t be able to access it! Here, we are storing it in the variable imgGrass using the assignment operator, =.

  • String-literals belong in double-quotes - when you’re hard-

coding the path of an image to load, you need to make sure to write the path within double quotes. If text is not within double-quotes, Python will think that it is some sort of command or name, and it will give you errors.

Draw an image[edit | edit source]


  • Inputs: source surface (pygame.image), destination rectangle (pygame.Rect)
  • Outputs: image surface object (store it in a variable)

Remember that we create a variable named window:

window = pygame.display.set_mode( ( screenWidth, screenHeight ) )

The window variable is technically a pygame.Surface object. To draw our image to the screen, we use the window.blit function, passing in the image variable and a rectangle, which contains the (x, y) coordinates, as well as width and height.

window.blit( imgGrass, ( 320, 240 ) )

In this example, it hard-codes the position of the image to (320, 240). For movable characters, you will usually want to store their position and dimensions in a pygame.Rect variable so it can change during the game's run.

We can change the position at which an image is drawn by changing the rectangle input. If you want to be able to modify the position of your image while the program is running, it makes more sense to store this information in a variable.

During the game initialization, you could set up a rectangle like this:

# Near beginning of the program. 
# pygame.Rect( x, y, width, height )
bunnyRect = pygame.Rect( 200, 100, 64, 64 )

And then update your window.blit to use this rectangle variable:

window.blit( imgBunny, bunnyRect )

Eventually, we will create a class for our characters, where their coordinates are stored as a variable, and we will use this for the draw function.

Draw part of an image[edit | edit source]

Orange haired girl sprite

Sometimes you might want to draw only a portion of an image to the screen. Often, when working with animated sprites, all the sprites’ frames of animation are stored in one image file like this one.

To draw just a portion of the image at a time, we have to call the blit function with an extra argument: window.blit( IMAGE, ( X, Y ), SUB IMAGE RECT )

Where in the SUB IMAGE RECT, you will specify the (x, y) of the pixel to begin at in the image, as well as the width and height of the region you want to draw.

So with this sprite sheet, if we wanted to draw the girl in row 3 and column 2, we would draw it like...

frameWidth = 32
frameHeight = 48

# pygame Rect arguments: ( x, y, width, height )

# Position on the screen itself
position = pygame.Rect( 100, 200, frameWidth, frameHeight )

# Rectangle region from sprite sheet to draw
frame = pygame.Rect( 1 * frameWidth, 2 * frameHeight, frameWidth, frameHeight )

window.blit( image, position, frame )

This will draw just the image on the spritesheet at the coordinate (1*frameWidth, 2*frameHeight), width the dimensions frameWidth x frameHeight.

Orange haired girl sprite - drawing a subsprite

Documentation links[edit | edit source]

Audio[edit | edit source]

In PyGame, we will treat sound effects and music a bit differently. Usually, you only have one background song playing at a time, while there might be multiple sound effects playing at once. For music you load in one music file at a time, while with sound files you store the sounds in variables to be played at any time.

Load a music file[edit | edit source]

  • Inputs: filename (string)
  • Outputs: none

Similarly to images, we can load in music files by passing in the path to your sound file. The path should be contained within double-quotes. "content/audio/song.mp3" )

Play the music[edit | edit source]

  • Inputs: none
  • Outputs: none

Once a song has been loaded, we can then play it with this function.

Pause the music[edit | edit source]

  • Inputs: none
  • Outputs: none

This will pause whatever music is currently playing on the channel.

Un-pause the music[edit | edit source]

  • Inputs: none
  • Outputs: none

Resume the music that is currently paused on the channel.

Set the music volume[edit | edit source]

  • Inputs: volume (0.0 = none, 1.0 = full)
  • Outputs: none

This sets the volume that the music will play at. 0.5 is half-volume, 1.0 is full volume, and 0.0 is no volume. 0.5 )

Get the music volume[edit | edit source]

  • Inputs: none
  • Outputs: volume (0.0 = none, 1.0 = full)

This will return the current volume the music channel is at

currentVolume =

Create a sound file[edit | edit source]


  • Inputs: filename (string)
  • Outputs: Sound-object (store it in a variable)

We may have multiple sound effects we want to load into our game at any one time, so we will store each sound effect in a variable.

sfx = pygame.mixer.Sound( "content/audio/collect.wav" )

Play a sound file[edit | edit source]

  • Inputs: none
  • Outputs: none

This function must be called as part of a variable that stores a Sound object. When calling a function from the object, use the . operator.

Set the sound volume[edit | edit source]


  • Inputs: volume (0.0 = none, 1.0 = full)
  • Outputs: none

This sets the volume that the music will play at. 0.5 is half-volume, 1.0 is full volume, and 0.0 is no volume.

sfx.set_volume( 0.5 )

Get the sound volume[edit | edit source]


  • Inputs: none
  • Outputs: volume (0.0 = none, 1.0 = full)

This will return the volume that the one specific sound is set to.

currentVolume = sfx.get_volume()

Documentation links[edit | edit source]

Fonts and text[edit | edit source]

To draw text to the screen in PyGame, we must load in the font files that we are going to use. Then, using our font object, we can render text to an image Surface and draw it to the screen.

Loading a font[edit | edit source]


  • Inputs: font path (string), font size (integer)
  • Outputs: none

Like with sound effects and images, to use fonts we want to create a Font object and store it in a variable. When creating the font, you need to pass in the font path, as well as the font size as input values.

mainFont = pygame.font.Font( "content/fonts/text.ttf", 20 )

Creating a text Surface[edit | edit source]


  • Inputs: text (string), antialias (boolean), color (pygame.Color)
  • Outputs: text surface (store it in a variable)

When we want to turn the text into an image of text, we use the font object to render it to a surface.

textSurface = mainFont.render( "Hello, world!", False, pygame.Color( 255, 255, 255 ) )

Drawing a text Surface[edit | edit source]


  • Inputs: source surface (pygame.image object), destination rectangle (pygame.Rect object)
  • Outputs: none

The draw functionality is part of the Surface object, but using the font we turned a text string into an image. You will need a window item created (See The bare-minimum PyGame program) to have something to draw the text to.

window.blit( textSurface, ( 100, 200 ) )

Documentation links[edit | edit source]

Keyboard and mouse input[edit | edit source]

As events occur in your game, Python will detect them and they will be stored and accessed via pygame.event.get(), which you can then iterate through and check what type of event it is. An event might be clicking the mouse button, or pressing down on a key on the keyboard, or even exiting the game. When the mouse is clicked, we can also get its (x, y) coordinates so that we can figure out what was being clicked - a button? A location to move to? And so on. You can also check for joystick/gamepad events, but we will just stick to keyboard and mouse for now.

Event types[edit | edit source]

Event type Name
Quit program QUIT
Key press down KEYDOWN
Key release KEYUP
Mouse button down MOUSEBUTTONDOWN
Mouse button release MOUSEBUTTONUP

Notice that with the events, there is a different for when you’re clicking down on the mouse button or on a keyboard key, and releasing it (or key-up). There might be multiple reasons for wanting to check for one or the other.

Once you’ve detected what kind of event is occurring, you can then get more information about what happened, such as which mouse button was clicked, or which key was pressed.

You can also use events like this to detect keyboard input, but this isn’t how you’ll want to get input for smooth character movement in your game. This would be more for small key presses. I’ll have more on how to get smooth keyboard movement later in this section.

Within the game loop, you will first need to check for events like this:

# Game loop
while done == False:
    # Check input
    for event in pygame.event.get():
        if ( event.type == MOUSEBUTTONDOWN ):
            print( "You clicked!" )

And then within the loop, you will use if statements to figure out (1) what kind of event happened, and (2) which button was pressed.

Mouse events[edit | edit source]

For mouse events, you have will start with the following.

# Game loop
while done == False:
    # Check input
    for event in pygame.event.get():
        if event.type == MOUSEBUTTONDOWN:
            print( "A" )
        elif event.type == MOUSEBUTTONUP:
            print( "B" )
        elif event.type == MOUSEMOTION:
            print( "C" )

Within the if statements is where you will look at which button was pressed and the mouse position.

event.pos gives you the mouse coordinates (x and y), and event.button gives you a number that represents which button was clicked.

# Game loop
while done == False:
    # Check input
    for event in pygame.event.get():
        if event.type == MOUSEBUTTONDOWN:
            mouseX, mouseY = event.pos
            print( "Mouse X: " + str( mouseX ) )
            print( "Mouse Y: " + str( mouseY ) )

With this code, the print statements will just write out text to the console, not the game itself, but you can use this for some light debugging or to experiment with at first.

The (x, y) coordinates also obey the rules of computer graphics, where the origin (0, 0) is at the top-left corner and increases right-ward and down-ward from there.

You can also check which button was pressed in the following way:

# Game loop
while done == False:
    # Check input
    for event in pygame.event.get():
        if event.type == MOUSEBUTTONUP:
            mouseX, mouseY = event.pos
            # Which button?
            if event.button == 1:
                print( "Left click at " + str( mouseX ) + "," + str( mouseY ) )
            elif event.button == 2:
                print( "Middle click at " + str( mouseX ) + "," + str( mouseY ) )
            elif event.button == 3:
                print( "Right click at " + str( mouseX ) + "," + str( mouseY ) )
            elif event.button == 4:
                print( "Scroll up at " + str( mouseX ) + "," + str( mouseY ) )
            elif event.button == 5:
                print( "Scroll down at " + str( mouseX ) + "," + str( mouseY ) )
Mouse button Number Events
Mouse wheel up 4 MOUSEBUTTONUP
Mouse wheel down 5 MOUSEBUTTONUP

Keyboard events[edit | edit source]

You can detect keyboard input similarly to how you detect mouse input, but this isn’t the ideal way to get game input for smooth character movement. That part will be under the Smooth keyboard input section.

Detecting keyboard events in this way is fine for small keyboard features, maybe like typing in your name or hitting a keyboard shortcut, but if you’re going to have your character move around by holding down arrow keys, this is not the way to do it.

Once again, we start by iterating through the events, detecting whether we have a KEYDOWN or KEYUP event.

# Game loop
while done == False:
    # Check input
    for event in pygame.event.get():
        if event.type == KEYDOWN:
            print( "Key press" )

Then, if we have detected one of these events, we can then ask which key was pressed:

# Game loop
while done == False:
    # Check input
    for event in pygame.event.get():
        if event.type == KEYDOWN:
            if event.key == K_q:
                done = True
            elif event.key == K_p:
                pause = True

Smooth keyboard input[edit | edit source]

If your character is going to move by holding down a key on the keyboard, such as the arrow keys or WASD, you will want to use this technique instead. Instead of dealing with key presses as events, we use pygame.key.get pressed to see which keys are currently down.

# Game loop
while done == False:
    # Smooth keyboard movement
    keys = pygame.key.get_pressed()

Then, using the keycodes above, we can detect which keys are currently being held down. This will also work to check more than one key at once (like holding Run + Move).

# Game loop
while done == False:
    # Smooth keyboard movement
    keys = pygame.key.get_pressed()
    if keys[ K_UP ]:
        bunnyPos.y -= 5

    elif keys[ K_DOWN ]:
        bunnyPos.y += 5

    elif keys[ K_LEFT ]:
        bunnyPos.x -= 5

    elif keys[ K_RIGHT ]:
        bunnyPos.x += 5

Key codes[edit | edit source]

Key Name Key Name Key Name
Escape key K_ESCAPE Space bar K_SPACE Return (enter) K_RETURN
"A" key K_a "B" key K_b "C" key K_c
"F1" key K_F1 "F2" key K_F2 "F3" key K_F3
Up arrow K_UP Down arrow K_DOWN
Left arrow K_LEFT Right arrow K_RIGHT
Left shift K_LSHIFT Right shift K_RSHIFT
Left ctrl K_LCTRL Right ctrl K_RCTRL
Left alt K_LALT Right ctrl K_RALT

You can get a list of all the keycodes at

Documentation links[edit | edit source]