Part 3 Importing PyGame and Creating the window

Creating a PyGame project

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:

The file-system tree, showing the main project folder, then a content subfolder, and graphics and audio subfolders within that.

The file-system tree, showing the main project folder, then a content subfolder, and graphics and audio subfolders within that.

To access items within these paths, we use relative pathing. Anything in the base folder (for me, “03 Creating a PyGame project”) is at the current directory – if you wanted to load an image from this location, you would just specify “myimage.png”. If you want to load an image from the graphics folder, then you’d include the two folders: “content/graphics/myimage.png”.

You can also use absolute pathing, where you write out the entire path (e.g., “C:\pictures\doggie.png”), but it is better to store all your project files in the same directory for easier access.

Within my graphics folder, I will be using the following files:

bunny.png

bunny.png

grass.png

grass.png

Save these images in your project folder and create your .py source file and then continue.


 

Basics of a PyGame program

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. Draw to the screen
  7. Update 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…

Importing libraries

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

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

pygame.init()
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 set_mode, 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×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.

Basic game loop

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

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.

Another example to illustrate this is:


print( "Before the if statement" )

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

print( "Outside 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 (inside the game loop)

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.

Note that this code is inside the game loop, so the for loop is indented forward by one tab.


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

 

Updating the screen (inside the game loop)

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.

Again, this code is indented forward by one level because it is within the game loop.


    # Update screen
    pygame.display.update()
    timer.tick( 30 )

 

Test 1

A small empty black screen

A small empty black screen

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 *

pygame.init()
timer = pygame.time.Clock()
window = pygame.display.set_mode( ( 320, 320 ) )
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
    pygame.display.update()
    timer.tick( 30 )

Cleaning it up a little

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 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.

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

Top of the program

import pygame, sys
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 320 at every location.

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

pygame.init()
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:

timer.tick( fps )

Creating color

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

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

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
bgColor = pygame.Color( 50, 200, 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 is False:”), add the following:

    window.fill( bgColor )

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

Loading images

The game window with a grassy background and a cool bunny.

The game window with a grassy background and a cool bunny.

We can also load images and store these images in variables. When you’re loading images, it should be outside of the game loop. Think of all of the code before the “while done is False:” as initialization code.

Load the images that were saved above with:

# 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:

    # Draw images
    window.blit( imgGrass, imgGrass.get_rect() )
    window.blit( imgBunny, imgBunny.get_rect() )

This should be right before the # Update screen area.

Test 2

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 *

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

# Create a color to use
bgColor = pygame.Color( 50, 200, 255 )

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

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

# Program start
InitPygame( screenWidth, screenHeight )

# Game loop
done = False
while done == False:
    window.fill( bgColor )

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

    # Draw images
    window.blit( imgGrass, imgGrass.get_rect() )
    window.blit( imgBunny, imgBunny.get_rect() )

    # Update screen
    pygame.display.update()
    timer.tick( fps )

Function documentation


<< Previous: Introduction, class files, & glossary | Next: Loading and displaying images >>

Back to main page


Download this lesson’s source code at https://github.com/Rachels-Courses/Intro-to-PyGame

Print Friendly