Python DevCenter
oreilly.comSafari Books Online.Conferences.


Py Games
Pages: 1, 2

But Why Py?

You might be wondering, "Is Python fast enough for game development?" Involved in a Pygame project since it's inception, I have been more than surprised at how fast Pygame can be. Sure, it's not C, but it's no slouch, either. Thanks largely to Pete Shinners and the dedicated and active development community that has sprung up around Pygame, it's only going to improve. There is a burgeoning library of contributed modules you can include in your own projects, a warm and friendly developers mailing list that's only too happy to help people with their problems, and of course the IRC channel (#Pygame on, where most of the "Pygame Projects" developers can be found. There's no problem that seems to go unanswered.

Game developers taking their first forays into "real" development come armed with a large collection of ideas, and a small bag of "clues" about how to realize them. It's demoralizing to get caught up in the intricacies of the chosen development language early in the project, or to realize that there is a large "tooling" time required to get a project off the ground. What these guys want is results! And quickly! The graphic artist wants to see if his character designs will work with his backgrounds, the sound guy wants to know if his music "feels" right, and the coder wants to know exactly how many screen updates (frames per second) he'll get shifting the proposed number of objects (sprites) around a certain-sized screen.

The beauty of Python and Pygame is they free developers from some of the more mundane chores that come with "lower level" languages such as C. You know the arguments: not having to worry about memory, no compile cycle, etc. etc. But it really does make a difference, when you consider the scope of computer games. The basics of Python syntax can be picked up in a couple of days, and the core Pygame functions in a couple more. It's not unfeasible for a novice game programmer to have a small test application up and running in less than a week! Don't believe me? Let's have a quick look.

We will create a simple framework for loading a sprite (a moveable image), set up a display, and blit (or copy -- this term is derived from "bit block transfer") the sprite onto our screen:

# Quick PyGame Example...
# Initialise SDL, display an image...

# For handling filenames...
import os

# The pygame module itself...
import pygame

# The image handling...
import pygame.image

# Important constant definitions for Pygame,
# in this example: used to setup the "Double
# Buffered" Display...
from pygame.locals import *

# Get the image from: ./images/sprite1.gif
sprite_file = os.path.join('images', 'sprite1.gif')

# Open up a display, draw our loaded image onto it
# -- check for ESC; if pressed, exit...
def main():
  # Initialise SDL environment

  # Setup a 640x480 screen...
  screen = pygame.display.set_mode((640,480), HWSURFACE|DOUBLEBUF)
  # Make a "surface" which is the same size as our screen...
  background = pygame.Surface(screen.get_size())

  # Make this background surface a white colour
  # (note: R,G,B tuple):

  # Load our sprite:
  sprite = pygame.image.load(sprite_file)
  # Get the initial position of the sprite,
  sprite_position = sprite.get_rect()

  # Set it's position to the middle of our display...
  sprite_position.bottom = (480 / 2)
  sprite_position.left = (640 / 2) - 100

  # Now "blit" the background and our sprite
  # onto the screen...
  screen.blit(background, (0,0))
  screen.blit(sprite, sprite_position)

  # Now display the screen buffer we've been
  # blitting things to...

  # Infinite loop to keep the window open until
  # ESC or "Close Window" widget
  # is pressed...
  while 1:
    # Get all "Events" that have occurred.
    # Check for keyboard input...
    keyinput = pygame.key.get_pressed()
    # If ESC or "QUIT" events occurred, exit...
    if keyinput[K_ESCAPE] or pygame.event.peek(QUIT):

# So we can run straight from the CLI...
if __name__ == '__main__':

A simple application that didn't involve the words "Hello World"! Save yourself some typing by downloading the examples. When executed, the example code looks something like this:

Screen shot.

We first set up a display 640 pixels wide by 480 pixels high. We've also opted for hardware acceleration (if available) and a "double buffered" display. (Double Buffering allows you to draw on a virtual display that is hidden from view until you switch or "flip" to it.)

Next we create a surface (think of it as a piece of clear plastic that you can draw on), that is the same dimension as our display, and we fill this with a white color -- this surface will act as our background.

We now load our sprite. Using the get_rect() method, we retrieve its current parameters. This allows us to set our sprite's position via the bottom and left attributes (and a few other useful things!). We can set these attributes to an integer value -- or use the existing values as the basis for dynamic modifiers.

With the sprite's position set (in the center of the display, in this example), we blit the background and the sprite to our screen buffer. Using pygame.display.flip(), we make our hidden buffer visible.

The example above is fairly simple, but it's trivial to extend this to move the sprite around our display. We already have an infinite loop that checks if the Escape key is being pressed; if we extend this to check for the cursor keys, we can modify the position of the sprite accordingly and display it in its new position, like so:

  while 1:
    # Get all "Events" that have occurred.
    # Check for keyboard input...
    keyinput = pygame.key.get_pressed()
    # If ESC or "QUIT" events ocurred, exit...
    if keyinput[K_ESCAPE] or pygame.event.peek(QUIT):

    # Ok, ESC not pressed, check for cursor keys...
    if keyinput[K_RIGHT]:
      sprite_position.left = sprite_position.left + 4

    if keyinput[K_LEFT]:
      sprite_position.left = sprite_position.left - 4
    if keyinput[K_UP]:
      sprite_position.bottom = sprite_position.bottom - 4    

    if keyinput[K_DOWN]:
      sprite_position.bottom = sprite_position.bottom + 4    

    # In case changes were made to the position,
    # redraw everything in it's new position...
    screen.blit(background, (0,0))
    screen.blit(sprite, sprite_position)


Voila! A moving sprite!

The example shown is very simple, but as you can see, Pygame handles complicated tasks with grace.

Things don't stop there! Python itself has many ways to impress. Need some networking for your game? No problem:

>>> import socket

Want to use an XML configuration file for the user parameters in the game? Great:

>>> import xml

Bob and Joe have the full power of Python and its standard modules at their disposal, power that removes the need for traditional proprietary formats or other custom developments normally associated with computer games.

In addition, Python provides a great platform for distributed games, as seen in early Ultima Online 2 developments. Python can also provide the means for players to customize ("mod") the game, something that's been popular since Doom hit the shelves. Customizing a game was recently taken to the extreme with "Severance, Blade of Darkness", which features an embedded Python interpreter within the game itself!

Related Reading

Programming Python, 2nd EditionProgramming Python, 2nd Edition
By Mark Lutz
Table of Contents
Sample Chapter
Full Description
Read Online -- Safari

Python and Pygame let developers concentrate on their ideas. You can quickly turn a discussion via email into working code, code that could end up in a final release with little or no change. Updates or modifications (with a bit of thought and the normal software engineering practices) are often trivial to do. It's an easy language for the novice to learn from other people's code, while being powerful enough to implement some extremely far-reaching ideas. Not to mention the fact that the combination of Python, Pygame, and SDL gives you real cross-platform development powers -- virtually the Holy Grail of the modern games industry.

What more could you ask for?

Infinite Lives

There are numerous examples of simple games that have taken a week to develop, as well as large projects that are still in development after a couple of years of work. Pygame has grown with them all, and continues to add new functions that will simplify the developer's life and provide new and interesting features. Python game development is easy and flexible.

With so few commercial developers free to take risks and bring revolutionary titles to market, maybe now is a perfect time to consider doing it yourself. It has never been easier to to sneak under their radar.

Gareth Noyce is an XML Architect by day and an independent Graphic Artist for Free Software projects by night.

Return to the Python DevCenter.

Sponsored by: