Enhanced animation code for pyglet

Here is the sourcecode to my earlier post on expanding pyglet’s animation support. This is a subclass of the pyglet.sprite.Sprite class, and adds support for pausing, seeking and looping.

This is pretty much a drop-in replacement for pyglet’s Sprite class, but it doesn’t do all the fancy timing stuff yet. In particular, if you are using a very low frame rate, the display may not be 100% accurate. If anyone feels like porting the full timing code of the _animate method over from pyglet.sprite.Sprite, I would be happy to post it.

Code is released on a ‘do whatever you like with it’ basis, have fun…

import pyglet

class AnimatedSprite(pyglet.sprite.Sprite):
”’ Sprite subclass providing advanced
playback controls for animated sprites ”’

def __init__(self,
img, x=0, y=0,
blend_src=pyglet.gl.GL_SRC_ALPHA,
blend_dest=pyglet.gl.GL_ONE_MINUS_SRC_ALPHA,
batch=None,
group=None,
usage=’dynamic’):
pyglet.sprite.Sprite.__init__(self, img, x, y, blend_src, blend_dest, batch, group, usage)

self._paused = False
self._range = (0, 1)

def _animate(self, dt):
self._frame_index += 1
if self._frame_index >= self.range[1]:
self._frame_index = self.range[0]
self.dispatch_event(‘on_animation_end’)

frame = self._animation.frames[self._frame_index]
self._set_texture(frame.image.get_texture())

if frame.duration != None:
pyglet.clock.schedule_once(self._animate, frame.duration)
else:
self.dispatch_event(‘on_animation_end’)

def set_frame(self, i):
”’ Seek to the specified frame ”’
self._frame_index = max(self.range[0], min(self.range[1], i))
frame = self._animation.frames[self._frame_index]

pyglet.clock.unschedule(self._animate)
self._animate(0.0)

def set_loop(self, begin, end):
”’ Loop between the begin and end frames ”’

self.range = (begin, end)

if self._frame_index < begin: self._frame_index = begin-1 pyglet.clock.unschedule(self._animate) self._animate(0.0) def pause(self): ''' pause animation playback ''' if not self._paused: frame = self._animation.frames[self._frame_index] self._animate(frame.duration) pyglet.clock.unschedule(self._animate) self._paused = True def play(self): ''' resume animation playback ''' if self._paused: frame = self._animation.frames[self._frame_index] self._animate(frame.duration) self._paused = False [/sourcecode]

Advertisements

4 comments

  1. Would it be possible to create an animation class without scheduling? It appears all the scheduling that goes on is what’s slowing down my game. So instead of setting a period (which is in milliseconds?) between animation frames, it would be frames per tick so it’d be relative to my game FPS. Does this make sense or am I completely off?

    • The way pyglet deals with animations, it will only update the animation frame each time pyglet renders. As long as your frame-rate is reasonable, it will only be updating the animation as often as is necessary to render, so I don’t see where this could be improved…


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s