Skip to navigation | Skip to content

Share your knowledge. Make a difference.

Pygame in 10 Easy Steps

1 - I can do better 2 - Jury's out 3 - Pretty darn good 4 - Splendiferous 5 - Awesometastic (by 1 person)   Your rating: 1 - I can do better 2 - Jury's out 3 - Pretty darn good 4 - Splendiferous 5 - Awesometastic

Ranked #896 in How-To, #9274 overall

Rated G. (Control what you see)

Pygame in 10 Easy Steps

 

This is a line-by-line tutorial that will guide you through the basics of creating a simple game using the popular Pygame library. If you know Python and want to learn how to make games, start here!

Welcome to Python 

What is Python and what is this page for?

Python is a concise, rapid, easy-to-use, easy-to-learn, object-oriented, cross-platform, high-level programming language. In fact, as of 2008, it is the 6th most popular language available (Tiobe) .

This tutorial will teach you the basics of creating games in Python using the Pygame library. No prior game development experience is necessary, however, some minimal knowledge of Python will be needed. If you are looking for a good place to start "A Bite of Python" by Swaroop CH is an excellent freely available e-book.

Who is this Tutorial For? 

This tutorial is for those who have some programming experience, but, have not taken that leap into the world of coded game development. It is very deep, as to give you a good grounding in the concepts of game programming, and my goal is provide you with enough background information for you to reach out into other languages beyond Python. If you don't need such a deep introduction but want to stick with Python check this tutorial out. Also, if you are not ready for code you might want this lens.

If none of this is what you are looking for, you might want to look at the links section at the bottom of the page (it's constantly being updated)!

All the code in this tutorial is released under this license. By continuing you agree to its terms.

Now, enough of the boring stuff, let's get cracking!

What's going on? 

The goal of this tutorial

The goal of this tutorial is to create a simple game that showcases some of the features of Pygame.

Here is the basic idea: Snowflakes are falling from the top of the screen and the user must stop them from hitting the ground. The user controls a turret that can fire bullets at the snowflakes. Each time a snowflake is hit, the user's score increases.

A screen shot of the final copy is above. It was taken in Ubuntu Linux.

Also, before you continue, you need to make sure that you have Pygame on your computer. Click here to download it.

Finally, there is a new glossary at the bottom of this page. It contains all of the italicized terms used in this tutorial. This is in response to some user feedback I received recently.

Step 1: The grocery list 

Don't write more than you need to

This is not too exciting, but our program will need to get some things.

To import the libraries needed you will want the this code.

Here are the things we are bringing in:

os: This adds some OS specific functions to your game. We will use this for opening files.

pygame: This is Pygame (kinda self explanatory)

random: We will use this to make random integers for the purposes of AI.

from pygame.locals import *: This gets the the most used things in Pygame which are saved in pygame.locals. This is optional but recommended.

random.seed(): This line initiates a random number maker.

Step 2: Defining loadImage 

How to make create sprites

Before we actually start creating the game we need to define some functions. The good news is that if we define them right you can use them in your other games as well. There are three big ones that we will need: loadImage, startGame, and gameObject.

So, without further delay here is the code for loading an image.

Go ahead and take a look at it. When you are ready, here is an explanation of what everything does:

completeName = os.path.join('resources',name): This gets the location for the folder in the variable "name". I am assuming that we will be putting all of the pictures for the game in a directory called resources. This folder needs to be in the same place as the source code (that is why it is called joining the path). If you are not calling the folder "resources", you just need to change the first argument in the command. More information on joining paths is available in the glossary section.

image = pygame.image.load(completeName): Basically this will load an image and store it to a variable. We call a loaded image a surface.

image = image.convert(): This converts the surface so that the program will draw it more quickly on the screen. Converting images is important, but somewhat trivial. If you are curious there is more information in the glossary.

The colorkey stuff: When making games, normally you will want your images to be transparent. We can do this using the color key. This is to avoid drawing the picture's background. So, if you are using a color key (if colorKey != None) and if it is not specified by the programmer (if colorKey == -1) then the program will get the color of the pixel in the top left hand corner of the picture (colorKey = image.get_at((0,0)). That color will be made the color key (image.set_colorkey(colorKey)). We are saying that -1 means that the user does not know the colorKey beforehand. If you are confused, there is more information on color keys in the glossary section.

return image, image.get_rect(): This returns the variable holding the image and the bounding box (rect) of the picture. We will discuss the bounding box in more detail later, but for now, just understand that it determines when objects collide and where objects are placed on the screen. Just so you know, the bounding box is defined in more detail in the glossary section.

Note: it is only fair to say that I based this certain piece of code off of this tutorial.

Step 3: Getting the game started 

Another function we will want to define

This is the function that we will later use to kick start our game.

Here is what it does:

pygame.init(): This will initiate (start) Pygame

We will discuss the purpose of the global variables at a later time

screen = pygame.display.set_mode((screenX, screenY)):
This creates an object (we will call it the screen) that acts like a Cartesian Coordinate System. However, the origin (when x is 0 and y is 0) is in the upper left hand corner instead of the center. The two arguments specify how large the x (horizontal) and y (vertical) values for the screen need to be. All of the images we will use will be placed by assigning x and y coordinates to their bounding boxes (rects). The picture above describes this. Please note that in Pygame coordinates are combined into one variable. So, it would look like function((xValue,yValue)). Pygame and Python both consider (xValue,yValue) as one variable. Please make sure you understand how this kind of coordinate system works, as it is used by almost every game development system available. This Wikipedia article should help.

pygame.display.set_caption(caption): sets the caption for the window

background_image, background_rect = loadImage(background): This creates the background using that loadImage command we made earlier.

screen.blit(background_image, (0,0)): Blit is like draw. It takes a surface and outputs it onto the screen with the given x and y coordinates.

pygame.mouse.set_visible(False): This makes it so that the mouse is not visible when it is in the game window.

Test drive 

Finally see what you have made.

Now we can finally run our first Pygame creation! Here is what we are going to do:

1. Make a file called "resources" in the same directory as the source code.

2. Save this image in that folder and call it background.jpg

3. Put this code in:

startGame(300, 300, 'SnowStorm', 'background.jpg', False)
pygame.display.flip()
pygame.time.delay(3000)

Now give it a shot and see what happens! If you are using linux you will want to put this at the top: #!/usr/bin/env python

Hopefully you were greeted by the lovely snow flake and a screen that magically disappeared after 3 seconds of glory.

Here is what was going on:

startGame(300, 300, 'SnowStorm', 'background.jpg', False): This calls the startGame function we created earlier. It tells the program to give a 300 x 300 pixel window the caption of SnowStorm and to use background.jpg in the resources folder as the background. Finally, it turns off the mouse cursor.

pygame.display.flip(): This updates the screen.

pygame.time.delay(3000): This tells the game to pause for 3000 milliseconds (3 seconds) so that we can look at our work.

Test Drive Troubleshooting 

Ask away!

Can't get your test drive to work? Post questions here and maybe someone can help you out.

If nothing else, here is the test drive code and resources.

Samnsparky

On second thought, I think I will just add onto this one so that I am not spamming up Squidoo. However, if you have some specific questions that may help me out.

Posted February 01, 2008

Samnsparky

Hey, sorry if the tutorial is confusing. So, I am going to be making a more simplified version . . . when I am done I will post here again and put a link at the top of this page. Thanks for the feedback!

Posted February 01, 2008

Kel Brady

Do you have a version of this tutorial that uses the english language. I'm not sure what language it is you are speaking.

Posted February 01, 2008

Step 4: the gameObject class 

The class that will save your life.

The gameObject will be a major life saver. The good news is, because of our earlier functions this is going to be a breeze. So, here is the code. Also, before continuing make sure that you delete the test drive stuff (the last 3 commands you added).

While this might seem a bit overwhelming, it really is simple:

class gameObject(pygame.sprite.Sprite): The only thing different about this is that it interfaces or inherits pygame.sprite.Sprite.

pygame.sprite.Sprite.__init__(self): This makes a sprite object which tells Pygame that it is more than just an image, it needs to have collisions and will be moving around a lot. You will need sprites for all of your game objects. Note: The meaning of sprite changes between languages and in Pygame it is just a enhanced version of an image. For more information on sprites see the glossary.

self.image, self.rect = loadImage(image, colorKey): This just gets the image and bounding box for the sprite we just made.

self.rect.centerx = x and self.rect.centery = y: This sets the x and y position of the object. Just in case you are worried, the image stays inside the bounding box (rect), so, everything is tidy.

self.maxX = maxX, self.maxY = maxY, self.minX = minX, and self.minY = minY: This sets the bounds of the object. We will talk more about this in a second.

That takes care of the creation of an object! So, let's move on to updating it.

self.rect.move_ip((xMove,yMove)): This moves the bounding box and picture that is surrounds. This is different than setting the x and y values as it changes relatively from where it previously was. So, if the x value is 5 and we execute self.rect.move_ip((5,0)) then the new x value will be 10.

Bounds Checking: Sometimes we don't want objects to go to certain places, like off the screen. These lines just make sure that it is not out of the bounds we set for it earlier.

Almost half way done!!!

Step 5a: Bring in the objects 

Really starting on the game

Update: Below this section I have added a more object-orientated approach to this step. If you are familiar with inheritance, it may be a better solution for you.

Now that we have the necessary functions and classes prepared, we can finally get to making the game! Here is the code.

This is what's going on:

turret = gameObject('turret', 'turret.gif', 150, 275, 300, 300): Makes a turret object using our handy dandy gameObject class. You will need this picture for the turret.

turretSprites = pygame.sprite.RenderPlain(turret): This just creates a list of sprites to render, or draw, that are associated with the turret. Because there is only one sprite we can put it in the initialization statement. Not a big deal.

createSnowflake(): This little method makes a snowflake with a random x value so that we can mix things up a bit.

snowflakeSprites = pygame.sprite.RenderPlain() and snowflakeSprites.add(createSnowflake()): This makes another list of sprites for the snowflakes and makes the first item. You will need this picture for the snowflakes.

def createLazer(x,y): This will make the lazer that will be fired by our turret. You will need this lazer image.

Easy enough right? If you are not sure about what everything does then cross reference the numbers and their corresponding place in their functions.

Once again, please notice that we are keeping all of the lazers and snowflakes in lists. That will be really important.

Step 5b: Make more classes 

Inheritance

If you prefer to approach this program in a more object-orientated way, you can make classes that inherit our gameObject class. This is the code that uses that approach.

Intro to the Game Loop 

Part 1 in the Game Loop saga

The game loop is the real engine behind the game. It handles just about everything after the game gets going. So, we are going to break it down into a couple parts.

Step 6: Game Loop: Clean up 

Play nice in the sandbox

Before drawing everything in its new position we need to make sure that the old stuff is gone. Otherwise you might have a couple of turrets drawn across the bottom of the screen. Think about it this way: You have a chalkboard and you draw a ball. If you want to move the ball, you need to erase and redraw it in its new position.

So, this is the code.

This is what this means:

Variables: I just stuck these in so you wont have to jump around later. You don't need to worry about any of them just yet, except, for active.

while active: This starts the game loop with active being the determining variable.

clearing stuff: This is reasonably self explanatory. For each of the gameObjects, in the lists we defined earlier, we erase or clear them from the screen.

Step 7: The keyboard 

Getting key presses

Obviously the user will want to interact with the game. We are going to do that with the keyboard.

Please use this text file for the code (if you used the object-orientated approach in step 5b, you will want this code).

Here is the explanation:

for event in pygame.event.get(): This gets a list of all of the events (things) going on in Pygame at the time the statement is executed.

elif event.type == KEYDOWN: If a key is pressed down.

if event.type == QUIT: active = 0: and if event.key == K_ESCAPE: active = 0 If the user is quitting the game (clicked the x or pressed escape) we exit the game loop.

elif event.key == K_LEFT: movement = -5: This sets the movement variable that will later be used in the turret's update method. Basically this is saying subtract five from the turret's x position to get it to move to the left.

elif event.key == K_RIGHT: movement = 5: Same thing as above except it moves to the right.

elif event.key == K_SPACE: This creates a new lazer. You might notice that it checks to see if i is greater than 5. i counts the number of iterations. This is to avoid going bullet crazy, so think of it as a reload time. Don't worry at the end of the game loop, 1 will be added to i.

elif event.key == K_p: If p is pressed a new font is created, a surface is rendered , and then painted on the screen. For more information on the text rendering process click here. The p key is obviously to pause the game.

elif event.type == KEYUP: When the player lets go of a key, the movement variable is reset. Also, if the game is paused, it holds the game in a temporary loop. When r is pressed, the background is redrawn to get rid of the text we created just a moment ago, and the program continues with the game loop.

If events are confusing you please see the glossary section.

Step 8: A Very Important Step 

When a program becomes a game

This next step is like a child's transformation into an adult. Here is the all important code (here it is for those using the object-orientated approach of step 5b).

For such an important piece of code, you may notice that it is reasonably simple.

turretSprites.update(movement, 0, True): This moves the turret using the update method we made earlier. The variable, movement, is added to the previous x value. The y value is left alone. True shows that we need bounds checking.

turretSprites.draw(screen): This draws the sprite to the screen.

lazerSprites.update(0, -5, False): The moves the lazers up five pixels each iteration. Bounds checking is not needed.

lazerSprites.draw(screen): The draws the lazers.

snowflakeSprites.update(0, 2, False): This moves the snowflakes down 2 pixels per iteration. Once again, bounds checking is not necessary.

snowflakeSprites.draw(screen): This draws the snowflakes.

for hit in pygame.sprite.groupcollide(lazerSprites, snowflakeSprites, 0, 1): This checks for collisions between the lazers and the snowflakes. The last two numbers show which ones we want to get rid of. I choose to let the lazer live on and obviously I decided to get rid of the snowflake.

score = score + 1: This adds 1 point to the user's score.

snowflakeSprites.add(createSnowflake()): I do this twice so that each time a snowflake is shot, 2 new snowflakes are made.

pygame.display.set_caption("Score:" + str(score)): I am having the window caption tell the user what their score is.

for sprite in lazerSprites: For each lazer . . .

if sprite.rect.top < 0: sprite.kill(): If the sprite's top (y) is less than 0 (off the top of the screen) then the lazer is killed. This is not necessary, it just is a good practice to clean up the sprites that the user can not see anymore.

for sprite in snowflakeSprites: For each snowflake . . .

if sprite.rect.top > 300: If its top (y) is larger than 300 (off the screen) . . .

print "game over" and active = False: The game is over and the game loop needs to end.

Step 9: Debug and Test 

Almost done

Go ahead and test out your game.

If everything is working then congratulations! You can go ahead and move on to the next step.

Otherwise, it may be time to knock out some bugs. If you have any problems go ahead and post them below. Hopefully someone can help.

If nothing else here is a copy of everything done so far (gameb.py is the version that uses the code from step 5b).

The Board of Frustration 

Post any problems you had here.

Hey! Hopefully the tutorial is going well. But, if there is something you need help with, go ahead and ask away!

Step 10: Spice it up 

Making it more challenging, nicer looking, and more complex.

We have a working game! However, it still seems a little too generic. So lets add some stuff to finish it off:

1. Making the snow fall faster as points increase: This is easy enough. Just use the snowSpeed variable we made earlier for the speed of the snow. Each time a snowflake is shot add to that speed. Note: You will need to change the snowflakeSprites.update command accordingly.

2. Taking a point away for each shot: When the lazer is off the screen take a point away. Don't forget to update the caption as well.

3. Display the score at the end: After the game loop ends just display the score using the code we used to pause the game earlier.

Here is the final product (gameb.py is the version that uses the code from step 5b). Of course, you may want to mess with the numbers a little bit.

Making Executables 

Just as a little note, Pygame things can be made into executables using: py2exe and Pygame2exe (the link is half way down the page).

Too much talking? 

Loading poll. Please Wait...

A Book on the Topic 

Hand picked and ready to go!

Other Websites 

Some good game development websites

Here are some websites on game development. Feel free to add (even if it's yours)!!!

Swaroop C H, The Dreamer ยป A Byte of Python

If you need to learn Python then this is a great e more...1 point

Python Programming Language -- Official Website

Home page for Python, an interpreted, interactive, more...0 points

Game Maker 7

This is a wonderful tool that can make games at a more...0 points

DarkBASIC

If you are not ready for the object orientated wor more...0 points

Pygame Homepage

This is the Pygame homepage. It is a great library more...0 points

A briefer Pygame Tutorial

If you already have some experience making games w more...0 points

Soya3D

This is a 3D library for Python.0 points

Reader Feedback 

Comments, questions, or concerns.

The easiest way you can help out the tutorial is by telling me what you thought about this web page. Thanks.

Glossary and Further Explanations 

Additional help...

Here are the italicized terms and a further explanation for each.

Bounding box (rect): Images might have transparency, however the computer sees it in terms of a rectangle. Programmers call this rectangle the bounding box. So when things in a game touch, the bounding boxes are touching. Think of it this way: Let's say we have a ball with the size of 2 pixels that has a bounding box of 20 pixels. Then, we have a triangle the size of 5 pixels with a bounding box of 10 pixels. The computer sees the circle and triangle touching when the bounding boxes touch, not when the user sees the actual circle and triangle touch. Still confused? Try these pages: CNET glossary and Compulabel glossary.

Caption: This is the text that is at the top of a window.

Color key: The color key sounds intimidating, but it really is not. It is the color of the background of an image. Any pixels in an image with the color of the color key are not drawn to the screen.

Converting a surface: This is extremely trivial, however, when an average jpeg image is loaded into a game it tends not to put painted onto the screen as quickly as it could be. Converting the surface turns it into a very fast/optimized format. It is important to realize that it is only applies to the image loaded into the game, not the actual file that was originally imported.

Events: Pygame programs rely upon events. That is why you will often hear that a lot of game development is event-driven. By this, programmers mean that what the computer does relies, in part, on what the user is doing at the time. Events are read in by sensors, which in our application is the keyboard.

Joining the path: If the source code for the program is in C:/ then completeName = os.path.join('resources',name) would make completeName equal C:/resources/.

Sprite: As said before, the meaning of a Sprite changes between languages. In Pygame a Sprite is just a enhanced version of an image that will be moving around and having collisions.
X
Samnsparky

About Samnsparky

Hello Squidoo! I teach small classes of 2D Game Development, CGI, 3D Game Development, basic CAD, and basic HTML. For a while I was just printing out lessons, but, then I found Squidoo and decided it was time to save some trees and some money! Hopefully, you will find some of my work on this site to be useful in your computer science studies.

Samnsparky's Pages

See all of Samnsparky's pages