Sunday, March 07, 2010

Pyglet: A Python Gaming Library.

In a previous article I noted the difficulty in finding a complete, well-documented and active audio library for Python. That was two and a half years ago, but the situation does not seem to have improved. Many of the libraries are moribund or have no developer community. Hardcore coders can piece together what to do from doc strings embedded in the libraries themselves, but the rest of us are left waiting.

One of the anonymous comments on that article mentioned Pyglet. In this series of articles I will provide an overview of that library with a special look at its audio facilities. I will highlight any limitations I have come across in the short time I have been working with it. My viewpoint is that of the casual programmer who wants to pick up a tool and get work done. I do not code every day or for its own sake, but to get real tasks accomplished efficiently in the real world. That is one of the reasons I love Python; even after a year away all the syntax comes readily back to mind. My goal is to find tools that are equally efficient.

You can tell a lot about a tool from its website. The Pyglet site provides detailed API documentation and a handy walk-through guide. Sample applications come with the install. This makes it a lot easier to get started than with many other small tools. (As far as I can tell, Pyglet is the work of a single developer.) However, the FAQ is minimal and many "before sales" questions are not answered, especially those concerning scope and limitations. I find this common enough for developer tools, though it is frustrating. Why would I choose Pyglet over other tools? When would I not want to use it? These are the questions a website should answer simply.

I will say from the beginning that Pyglet has only minimal audio facilities. There is nothing in the way of signal processing, audio effects or algorithmic composition. But as a quick way to play back existing audio in a nice interface, it might be just the ticket.

But now, on to the library!

Pyglet is a game development library for Python that supports Windows, Mac OS X and LINUX. In this day and age I treat those as a minimum target. As a test I will be developing a simple app on Windows 7 64-bit for testing on LINUX and distribution on a Mac mini. This is not an arbitrary test; these are the real-world requirements of the programme, dictated by the availability of computers at my disposal.

Pyglet includes a windowing interface library along with keyboard and mouse detection. Text output can be formatted using a subset of HTML (which does not support CSS, however) or Pyglet-specific markup (about which I could find little). You can even work with fonts and glyphs at a primitive level if you need to design your own.

Images can be read from files or file-like objects, so you can easily store your programme resources in an archive, for instance. In fact the module "image.atlas" provides special support for image bins. A full image or some part thereof can be displayed and transformed within a particular view-port or projection. Images have full sprite control (position, scale and rotation). The demo applications include a convincing clone of the classic Asteroids game.

Pyglet is notable for supporting a complete OpenGL and GLU functionality set, including basic graphics primitives. I am certainly in no position to verify this claim but it seems that anyone familiar with OpenGL can get right to work.

A clock module provides not only scheduled events at specific time slices, but can calculate or limit the frame rate of your application.

Some time has been spent solving common application development problems. For example the "resource" module handles locating data files relative to the application root. Everyone coding in Python ends up writing something similar, but it's good to see the application framework support it.

Without further ado, here is the canonical Hello World programme, taken from the examples provided.

import pyglet

window = pyglet.window.Window()
label = pyglet.text.Label('Hello, world',
    font_name='Times New Roman',
    font_size=36,
    x=window.width//2, y=window.height//2,
    anchor_x='center', anchor_y='center')

@window.event
def on_draw():
  window.clear()
  label.draw()

pyglet.app.run()

We first define a window instance and a label instance. The "@window.event" decorator provides an easy way to modify the class methods, in this case the "on_draw" event. The "app" module hides the application event loop in a single line of code.

And that is all! I don't think I have ever seen a simpler windowing application framework.

This should whet your appetite for what seems to be an uncommonly useful little library. In the second article I will look at some of the configuration "gotchas" I referred to above.

RELATED POSTS

2 comments:

robin said...

Thanks Rafal. The more examples the better!

Joaquin Abian said...

'I don't think I have ever seen a simpler windowing application framework.'

Im not sure I got it. Is not this also simple:

# File: hello1.py

from Tkinter import *
root = Tk()
w = Label(root, text="Hello, world!")
w.pack()
root.mainloop()


the wxPython version is similarly simple.

Post a Comment