21 July 2009 ~ 2 Comments

PyGame and Animated Sprites

An animated sprite is a serie of the same image slightly modified and displayed at a certain framerate per second.

explosed-sprite

Explosion Sprite sampled from Remastered Tyrian Graphics @ Lost Garden

Sample 5 frames Sprite representation:

-----------------------------------------
|   1   |   2   |   3   |   4   |   5   |
| 16x16 | 16x16 | 16x16 | 16x16 | 16x16 |
|       |       |       |       |       |
-----------------------------------------

For a  given framerate set to 30fps :

  1. Frame 1 is blited at now()
  2. Frame 2 blitted 1000/30 seconds after Frame 1
  3. Frame 3 blitted 1000/30 seconds after Frame 2

and so on.

This gives the illusion of motion.

With PyGame you can load a set of images to an Animated Sprite Class or you can load a single image containing all your frames and slice it using PyGame’s Subsurface Method

I made an helper function to load and slice such sprites:

[sourcecode language='python']
def load_sliced_sprites(self, w, h, filename):
    '''
    Specs :
    	Master can be any height.
    	Sprites frames width must be the same width
    	Master width must be len(frames)*frame.width
    Assuming you ressources directory is named "ressources"
    '''
    images = []
    master_image = pygame.image.load(os.path.join('ressources', filename)).convert_alpha()

    master_width, master_height = master_image.get_size()
    for i in xrange(int(master_width/w)):
    	images.append(master_image.subsurface((i*w,0,w,h)))
    return images

[/sourcecode]

Use it like this :

[sourcecode language='python']
''' Asuming your frames have a 16x16 size '''
explosion_images = load_sliced_sprites(16, 16, 'explosions-sprite.png')
[/sourcecode]

explosion_images will then be an iterable list so you can use it with this kind of class courtesy of the excellent piman’s Sprites Tutorial :

[sourcecode language='python']
import pygame

class AnimatedSprite(pygame.sprite.Sprite):
    def __init__(self, images, fps = 10):
        pygame.sprite.Sprite.__init__(self)
        self._images = images

        # Track the time we started, and the time between updates.
        # Then we can figure out when we have to switch the image.
        self._start = pygame.time.get_ticks()
        self._delay = 1000 / fps
        self._last_update = 0
        self._frame = 0

        # Call update to set our first image.
        self.update(pygame.time.get_ticks())

    def update(self, t):
        # Note that this doesn't work if it's been more that self._delay
        # time between calls to update(); we only update the image once
        # then, but it really should be updated twice.

        if t - self._last_update > self._delay:
            self._frame += 1
            if self._frame >= len(self._images): self._frame = 0
            self.image = self._images[self._frame]
            self._last_update = t

[/sourcecode]

Happy Learning!
Spread the word:
  • del.icio.us
  • Reddit
  • StumbleUpon
  • Technorati
  • Twitter
  • DZone
  • Facebook
  • FriendFeed
  • HackerNews

2 Responses to “PyGame and Animated Sprites”