UPDATE 30/03/1: Just realized that unfortunately pyglet doesn't play well with the latest 64bit architecture of oSX. A real shame, as this obviously breaks Pyglet's famed run-anywhere feature. There are reasons to think that the next version will fix this problem (check out this thread for more info).. but for the moment, I guess that the only alternative is falling back to PyOpenGl. UPDATE 14/12/09: pyProcessing is a project building on pyglet that that creates an environment for graphics applications that closely resembles that of the Processing system. Quite neat uh?
Pyglet provides an object-oriented programming interface for developing games and other visually-rich applications for Windows, Mac OS X and Linux. I've been playing with it for an hour or so, and was surprised of how quickly it can let you create a python-based multimedia application.
Some of the features of pyglet are:
No external dependencies or installation requirements. For most application and game requirements, pyglet needs nothing else besides Python, simplifying distribution and installation. Take advantage of multiple windows and multi-monitor desktops. pyglet allows you to use as many windows as you need, and is fully aware of multi-monitor setups for use with fullscreen games. Load images, sound, music and video in almost any format. pyglet can optionally use AVbin to play back audio formats such as MP3, OGG/Vorbis and WMA, and video formats such as DivX, MPEG-2, H.264, WMV and Xvid.
Two possibly useful tips when getting started:
- Go get AVBIN without hesitations, as you'll need it. MP3 and other compressed audio formats require AVbin to be installed (this is the default for the Windows and Mac OS X installers). Uncompressed WAV files can be played without AVbin.
- [tested on OSx leopard only] If you try running the hello-world example from the console, after hitting window = pyglet.window.Window() you'll see a new window appearing on your screen. That looks like good news obviously, but soon you'll find out that the Finder doesn't like that, and apparently the Python launcher results being as 'not responding' on the Force Quit Application menu. Well nothing to worry there: it's because you haven't issued the pyglet.app.run() command yet (which is where the main event loop gets handled).
The screenshot above is taken from one of the example apps you can download. Balls keeps bouncing around in a window, playing a sound when they hit the border. Check out the code:
import os import random import sys
from pyglet.gl import * import pyglet from pyglet.window import key
BALL_IMAGE \= 'ball.png' BALL_SOUND \= 'ball.wav'
if len(sys.argv) > 1: BALL_SOUND \= sys.argv
sound \= pyglet.resource.media(BALL_SOUND, streaming\=False)
class Ball(pyglet.sprite.Sprite): ball_image \= pyglet.resource.image(BALL_IMAGE) width \= ball_image.width height \= ball_image.height
def \_\_init\_\_(self): x \= random.random() \* (window.width \- self.width) y \= random.random() \* (window.height \- self.height) super(Ball, self).\_\_init\_\_(self.ball\_image, x, y, batch\=balls\_batch) self.dx \= (random.random() \- 0.5) \* 1000 self.dy \= (random.random() \- 0.5) \* 1000 def update(self, dt): if self.x \= window.width: self.dx \*\= \-1 sound.play() if self.y \= window.height: self.dy \*\= \-1 sound.play() self.x +\= self.dx \* dt self.y +\= self.dy \* dt self.x \= min(max(self.x, 0), window.width \- self.width) self.y \= min(max(self.y, 0), window.height \- self.height)
window \= pyglet.window.Window(640, 480)
@window.event def on_key_press(symbol, modifiers): if symbol \=\= key.SPACE: balls.append(Ball()) elif symbol \=\= key.BACKSPACE: if balls: del balls[-1] elif symbol \=\= key.ESCAPE: window.has_exit \= True
@window.event def on_draw(): window.clear() balls_batch.draw() label.draw()
def update(dt): for ball in balls: ball.update(dt) pyglet.clock.schedule_interval(update, 1/30.)
balls_batch \= pyglet.graphics.Batch() balls \=  label \= pyglet.text.Label('Press space to add a ball, backspace to remove', font_size\=14, x\=window.width // 2, y\=10, anchor_x\='center')
if __name__ \=\= '__main__': pyglet.app.run()
Cite this blog post:
blog Python's phenotype
blog Library 2.0