Forum Archive

Animated sprite sheet

Sebastian

Found this in one of the games I made a while back...

Thought I would share it ;) Maybe someone can improve it a little bit and make it more useful :P

import scene, StringIO, urllib, os, Image

class AnimatedSprite (object):
    def __init__(self, path, frame, w=1, h=1, steps=3, **kwargs):
        self.w = w
        self.h = h
        self.frame = frame
        if path.startswith(('http://', 'https://')):
            file = StringIO.StringIO(urllib.urlopen(path).read())
            img = Image.open(file).convert('RGBA')
#           self.white_to_transparent(img)
            self.tiles = [self.get_frame(img, x, y) for y in xrange(h) for x in xrange(w)]
        elif os.path.isfile(path):
            img = Image.open(path)
            self.tiles = [self.get_frame(img, x, y) for y in xrange(h) for x in xrange(w)]
        elif os.path.isdir(path):
            self.tiles = [scene.load_image_file(path+img) for img in os.listdir(path)]
        self.step = 0
        self.frame_count = 0
        self.steps = steps
        self.rotation = 0
        self.tint = scene.Color(1,1,1,1)
        self.looped = False
        self.is_done = False
        self.original_size = frame.w, frame.h
        self.configure(**kwargs)

    def configure(self, **kwargs):
        for k, v in kwargs.items():
            setattr(self, k, v)

    def white_to_transparent(self, img):
        pixdata = img.load()
        for y in xrange(img.size[1]):
            for x in xrange(img.size[0]):
                if pixdata[x, y] == (255, 255, 255, 255):
                    pixdata[x, y] = (255, 255, 255, 0)

    def get_frame(self, img, x, y):
        w, h = img.size
        w = w/self.w
        h = h/self.h
        frame = img.crop((x*w, y*h, (x+1)*w, (y+1)*h))
        self.original_size = frame.size
        return scene.load_pil_image(frame)

    def set_original_size(self):
        self.frame.w, self.frame.h = self.original_size

    def draw(self):
        self.frame_count += 1
        if not self.is_done:
            scene.push_matrix()
            scene.translate(*self.frame.origin())
            scene.rotate(self.rotation)
            scene.tint(*self.tint)
            scene.image(self.tiles[self.step], 0, 0, *self.frame.size())
            scene.pop_matrix()
        if self.frame_count % self.steps == 0 and not self.is_done:
            self.step += 1
        if not self.looped:
            if self.step == len(self.tiles)-1:
                self.step = 0
                self.is_done = True
        else:
            if self.step == len(self.tiles)-1:
                self.step = 0


class MyScene (scene.Scene):
    def setup(self):
        url = 'https://dl.dropboxusercontent.com/u/25234596/Exp_type_C.png'

        self.img = AnimatedSprite(url, scene.Rect(self.size.w/2, self.size.h/2, 200, 200), w=48)
        self.img.configure(steps=2, looped=True)
        self.img.set_original_size()

    def draw(self):
        scene.background(1,1,1)
        self.img.draw()

    def touch_began(self, touch):
        self.img.frame.center(touch.location)
        self.img.configure(is_done=False, step=0)

scene.run(MyScene())
ccc

Beautiful! This is exactly the sort of effect that we needed for https://github.com/tjferry14/Cloud-Jump-2/issues/9