When I posted the second screencast, I mentioned that I haven’t been able to post this transcript yet. Thanks to the Post Timestamp feature of WordPress, I was able to position this entry earlier than the said screencast, even though I posted that first :). For the record, this was posted later than the second screencast ;).
The code highlighting was made possible by the Code Snippet WordPress Plugin.
I would like to know what you think about the transcripts :)! Please leave a comment on the site so that I would know how this site can better serve your needs. The transcript for the second screencast should follow shortly ;).


Hello, and welcome to scriptedfun.com Screencast #1 - Making a Barebones Pygame Program. Today, we will make a program that displays an empty screen. Although it isn’t much, it’s the first step to making a game, and this will serve as the foundation for the pygame programs that we will be making in the future.

import pygame
from pygame.locals import *

def main():
    pygame.init()

First, let us import the pygame module, to make the features of pygame available to us.
Then, let us place the most-commonly used pygame constants into our global namespace, so that they can be easily accessed.
Then, let us define our main function.
We have to initialize pygame before using it.

SCREENRECT = Rect(0, 0, 640, 480)

Then we have to make our window appear. Let us define the variable SCREENRECT, and it will just contain a Rect object defining a rectangle whose upper-left corner is at (0, 0), and whose dimensions are 640 by 480. Having a Rect object to represent the screen will help us later on when we actually have to put things on the screen.

screen = pygame.display.set_mode(SCREENRECT.size)

Then, let’s call pygame.display.set_mode, passing to it the size attribute of SCREENRECT, to initialize a 640 by 480 window.
By now, we’ve already done what we want - display an empty screen. However, it would be better if we already prepare the stage for our game by adding a basic game loop, so that sprites may be easily added later on.
We need to accomplish 4 things:

  1. We have to make a background, keep a copy of it, and display it on the screen.
  2. We have to define a sprite group which will contain the elements of our game, such as the enemies, the player, etc.
  3. We have to make sure that the game’s speed is just right by keeping track of time using a pygame Clock object. And finally,
  4. we need to have a game loop, where all the action in our game will take place.

Step 4 can actually be subdivided into 5 more steps.

  1. We need to read the keyboard and the mouse for input, and act accordingly. Animation takes place in steps 2, 3, and 4.
  2. We have to clear the sprites. Then,
  3. we have to update the sprites. This is the part where we make things move, execute enemy AI, etc. Then,
  4. we redraw the sprites on the background. Over these three steps, movement is achieved. Finally,
  5. we have to time each loop iteration by using the Clock object we defined earlier to make sure that our game runs at the right speed. For this project, let’s make sure that our program runs at 30 frames per second, just like TV.
if __name__ == ‘__main__’: main()

At the end of our code, let’s just add this line which will ensure that our program will actually run by calling the main() function.

# make background
    background = pygame.Surface(SCREENRECT.size).convert()
    background.fill((0, 0, 255))
    screen.blit(background, (0, 0))
    pygame.display.update()

Let’s take a step back and fill in the comments with code.
For our background, let us make a pygame Surface object as big as the screen. Then let’s call convert to ensure that’s in the correct pixel format so that things will run fast.
Then, let’s fill the background with the color blue. We can do this by using the fill command, passing it a triple representing red, green, and blue values from 0 to 255. Let’s set the last coordinate, corresponding to blue, to 255, while leaving the other two coordinates at 0.
Then, let us blit the background to the screen. We want the upper left corner of the background to correspond to the upper left corner of the screen, to ensure that the two will completely overlap.
Finally, let’s update the display. This has to be called everytime we want to make the changes that we make to the screen visible to the user. Having this is a good thing because this will prevent the user from seeing the screen while it’s being updated. This is similar to how a stage play works - in most cases, the director wouldn’t want you to see the mess that happens onstage when changing props.
That does it for the background.

# keep track of sprites
    all = pygame.sprite.RenderUpdates()

Next, let us declare the variable all, which will contain a pygame group, in particular, a RenderUpdates group. The variable all will serve as a list which will allow us to keep track of all our sprites. RenderUpdates groups have special properties, which will be discussed further later on, that, in some cases, may allow us to make our game faster.

# keep track of time
    clock = pygame.time.Clock()

Then, let us define a pygame Clock object, which will allow us to manage our program’s frame rate during the game loop later on.

# game loop
    while 1:

It’s time for us to make our game loop. By using while 1, we have made an infinite loop which we can get out of by using the return statement. So we have to make sure that we’ll be able to get out of this loop.

# get input
        for event in pygame.event.get():
            if event.type == QUIT   \
               or (event.type == KEYDOWN and    \
                   event.key == K_ESCAPE):
                return

To get input, we will look at the pygame event queue by calling pygame.event.get(). This will return a list which we can go over using a for loop.
We are mainly interested in events related to getting out of the main loop - meaning, quit events. We want the user to be able to quit by clicking on the X button on the upper right hand side of the window, so we want look for a QUIT type of event.
Also, we want the user to be able to quit by pressing the Escape key. So we have to look for a KEYDOWN event, and if such an event is found, we want to see if the Escape key was pressed.
If any of these events take place, we return, bringing us out of the infinite loop, and ending the program.
It’s time for animation. Going back to RenderUpdates, this type of group makes animation very easy by providing methods which correspond to the three things which we want to accomplish - clear, update, and redraw.

# clear sprites
        all.clear(screen, background)

To clear the screen of sprites, we just have to use the clear method. We have to pass it the screen, so that it will know where it has to clear, and the background, so that it will know what to paint over the sprites to clear the screen.

# update sprites
        all.update()

Next, we want to update all the sprites. Since all the sprites are listed in the variable all, we just have to call the update method for all. This method conveniently updates each sprite in the group all.

# redraw sprites
        dirty = all.draw(screen)
        pygame.display.update(dirty)

Finally, we have to redraw the screen. We do this using two lines of code. First, we call the draw method to redraw the sprites contained in the group all on the screen. Since this is a RenderUpdates group, calling draw returns a list of regions which changed on screen since the last update. To save on time, it would be helpful if we just redrew these regions instead of redrawing the entire screen.
So we store this list in the variable dirty, since this variable contains “dirty rectangles” or the regions which have to be redrawn.
Finally, just like when we made the background, we have to call update to make the changes visible to the user, but this time we pass to it the dirty rectangles so that it will update only the regions which have changed, and leave the parts of the screen which were not changed untouched.

# maintain frame rate
        clock.tick(30)

Then, we use the tick method of our Clock object so that one loop iteration takes a 30th of a second, which makes our program run at 30 frames per second.
And we’re done! It may be difficult to appreciate the work that we have put into this program, because we haven’t put anything on the screen yet. However, by making provisions for sprites this early, adding sprites to our barebones program should be much easier for us later on.
If you have any questions, comments, or suggestions, or anything at all, please leave a comment on the site. Thank you and I hope to see you again for the next screencast.

License

This work is published under a Creative Commons Attribution 2.5 License.