Effect Animation with Pyglet next round

17.10.2009 by azarai in game development | pyglet | python

I did enhance my little effect animation demo and added a little utility that will make life much easier for converting LexusX particle animations to real transparent pngs too.


w : switch background to white
b : switch background to black
Arrow Up : use next effect
Arrow Up : use previous effect
Left Mouse click : spawn new effect at mouse location

Code of the demo app:

import glob, re
import pyglet
from pyglet.image import Animation, AnimationFrame
window = pyglet.window.Window()

white = (1,1,1,0)
black = (0,0,0,0)

rgb_white = (255,255,255,255)
rgb_black = (0,0,0,255)

effects = []
use_effect = 0

def create_effect_animation(image_name):
    img = pyglet.image.load(image_name)
    columns = img.width /192
    rows = img.height /192
    effect_seq = pyglet.image.ImageGrid(img, rows, columns).get_texture_sequence()
    effect_frames = []
    for row in range(rows, 0, -1):
        end = row * columns
        start = end - (columns -1) -1
        for effect_frame in effect_seq[start:end:1]:
            effect_frames.append(AnimationFrame(effect_frame, 0.1))

    effect_frames[(rows * columns) -1].duration = None
    return Animation(effect_frames)

effect_anims = []
for effect_file in glob.glob('effects/_LPE__*.png'):
    m = re.match(r".*_LPE__(.*)_by.*", effect_file)
    key = m.group(1)
    effect_anims.append({'key':key, 'value':create_effect_animation(effect_file) })

label = pyglet.text.Label('Effect: '+ effect_anims[use_effect]['key'],
                          font_name='Times New Roman',
                          x=30, y=30,
                          anchor_x='left', anchor_y='center', color = rgb_black)

class EffectSprite(pyglet.sprite.Sprite):
    def on_animation_end(self):

def on_mouse_press(x, y, button, modifiers):
    if(pyglet.window.mouse.LEFT == button):
        effect = EffectSprite(effect_anims[use_effect]['value'])
        effect.position = (x-effect.width/2, y - effect.height/2)

def on_key_press(symbol, modifiers):
    global use_effect
    if symbol == pyglet.window.key.B:
        label.color = rgb_white
    if symbol == pyglet.window.key.W:
        label.color = rgb_black
    if symbol == pyglet.window.key.UP:
        use_effect +=1
        if use_effect > len(effect_anims) -1:
            use_effect = len(effect_anims) -1
        label.text = 'Effect: ' + effect_anims[use_effect]['key']
    if symbol == pyglet.window.key.DOWN:
        use_effect -= 1
        if use_effect < 0:
            use_effect = 0
        label.text = 'Effect: ' + effect_anims[use_effect]['key']

def on_draw():
    for effect in effects:


The utility (lpe-parser):

from PIL import Image, ImageOps
import glob, os, sys

pattern = sys.argv[1] + "\*.png"

for infile in glob.glob(pattern):
    path, filename = os.path.split(infile)
    im = Image.open(infile)
    parsed_folder = path + "/parsed" 
    if not os.path.exists(parsed_folder):

    im_gray = ImageOps.grayscale(im.copy())
    im_new = im.copy()   
    im_new.save(parsed_folder + "/" + filename, "png")

The lpe-parser looks in the given directory for pngs and makes them transparent. A grayscale version of the original image is used for the alpha channel. The new, now really transparent, image is stored in the subfolder parsed.

Download effect demo with pngs + lpe-parser ~17 MB

Is anyone interested in a ready to use library? If so which usage approach would you prefer? What would you need?

Want content like this in your inbox each workday? No BS, spam or tricks... just useful content:

I understand and agree to the privacy policy