Tuesday, March 11, 2008

Pyglet + Fixed Time Step Updates

Pyglet 1.1 comes with a shiny new event loop. I've always liked to control my own mainloop, so that I can implement things like fixed time step updates, and simulation/frame skipping.

After some advice from Alex, I came up with the following class, which plugs neatly into the pyglet mainloop/clock schedule architecture.

import pyglet

class FixedStepLoop(object):
"""
A fixed time step loop for pyglet.
"""
def __init__(self, update_function, step, max_step):
self.update_function = update_function
self.step = step
self.max_step = max_step
self.simulation_time = 0.0 - self.step
self.real_time = 0.0
self.frame_time = 0.0
pyglet.clock.schedule(self._tick)

def _tick(self, T):
self.real_time += T
self.frame_time += T

if T > self.max_step:
self.simulation_time = self.real_time - self.step

while self.simulation_time <= self.real_time:
self.update_function(self.step)
self.simulation_time += self.step
self.frame_time = 0.0

self.step_fraction = self.frame_time / self.step

If you instantiate this class with an update function as the first parameter, followed by the time step size and the maximum step size (after which simulation skipping will occur), the update function will be called with a fixed time step parameter.

As a side effect, you can all get the step fraction (percentage of time passed between update calls) if you want to implement some interpolation between your game state.

window = pyglet.window.Window()

def on_update(t):
print t

fixed_step_loop = FixedStepLoop(on_update, 1.0/10, 0.2)

@window.event
def on_draw():
print fixed_step_loop.step_fraction
window.clear()

pyglet.app.run()

Popular Posts