Line Rider for PyMT + Physics Simulation

Require PyMT 0.5 + PyMunk

"""
This program has been created in the course of a one hour hacking workshop
at FITG 2010 (Lille) without prior knowledge of pymunk.
The idea was to replicate something like http://www.linerider.com/
After one hour (including explanations) we came up with the following
60-line program that does just what we wanted.

Obviously the code is neither optimized (esp. when drawing many lines) and
doesn't make use of our most recent developments. It's kept pretty simple,
actually and could sure be refactored.
I am just putting it up here so that people can find it again.

Enjoy!
http://the-space-station.com/~dennda/gallery/mt/pymt_linerider.png
"""



try:
    import pymunk
except ImportError:
    import sys
    error = "You need pymunk installed. Please refer to http://code.google.com/p/pymunk/"
    sys.exit(error)

from pymt import *


class World(MTWidget):
    """
    The world keeps track of all the lines that are drawn by the user.
    It also initiates the pymunk physics context and adds a ball that
    falls down because it is subject to gravity.
    """

    def __init__(self, **kwargs):
        super(World, self).__init__(**kwargs)
        pymunk.init_pymunk()
        self.space = pymunk.Space()
        self.space.gravity = (20, -400.0)

        mass = 1
        self.radius = 14
        inertia = pymunk.moment_for_circle(mass, 0, self.radius, (0,0))
        self.body = pymunk.Body(mass, inertia)
        self.body.position = getWindow().center
        self.shape = pymunk.Circle(self.body, self.radius, (0,0))
        self.space.add(self.body, self.shape)

        self.lines = []

    def clear(self, *args):
        self.lines = []
        self.space = pymunk.Space()
        self.space.gravity = (0, -900.0)
        self.space.add(self.body, self.shape)

    def on_update(self):
        self.space.step(1/50.)
        if self.body.position[1] < 0:
            self.body.position = getWindow().center
            self.body.velocity = (0, 0)

    def draw(self):
        set_color(0, 0, 0)
        drawCircle(self.body.position, self.radius)
        for line in self.lines:
            drawLine(line)

    def add_line(self, pos1, pos2):
        self.lines.append((pos1, pos2))
        linebody = pymunk.Body(pymunk.inf, pymunk.inf)
        shape = pymunk.Segment(linebody, pos1, pos2, 0.0)
        shape.friction = -10.0
        self.space.add_static(shape)

    def on_touch_down(self, touch):
        touch.userdata['startposition'] = touch.pos

    def on_touch_move(self, touch):
        startpos = touch.userdata.get('startposition')
        if startpos is not None:
            self.add_line(startpos, touch.pos)
        touch.userdata['startposition'] = touch.pos


window = getWindow()
w = World()
btn = MTButton(label='Clear')
btn.connect('on_release', w.clear)

window.add_widget(w)
window.add_widget(btn)

runTouchApp(w)

Download at http://paste.pocoo.org/show/225159/