Mercurial > rinkhals
changeset 202:3074784c93f4
Animation support
author | Neil Muller <drnlmuller@gmail.com> |
---|---|
date | Fri, 04 Sep 2009 20:23:30 +0000 |
parents | fe1e9c18d4d7 |
children | 653da96db572 |
files | gamelib/animations.py gamelib/engine.py gamelib/equipment.py gamelib/gameboard.py |
diffstat | 4 files changed, 101 insertions(+), 1 deletions(-) [+] |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gamelib/animations.py Fri Sep 04 20:23:30 2009 +0000 @@ -0,0 +1,52 @@ +"""Animation Loops""" + +from pgu.vid import Sprite + +import imagecache +from misc import Position + +class Animation(Sprite): + """Animation loop. + + These are derived from sprites, since they behave similiary in most + respects, but, to ensure draw ordering, we don't add them to + the sprites list. + + Ideally, animations should be quite short.""" + + def __init__(self, sequence, tile_pos): + # Create the first frame + self.iter = iter(sequence) + Sprite.__init__(self, self.iter.next(), (-1000, -1000)) + if hasattr(tile_pos, 'to_tuple'): + self.pos = tile_pos + else: + self.pos = Position(tile_pos[0], tile_pos[1]) + self.removed = False + + def fix_pos(self, tv): + ppos = tv.tile_to_view(self.pos.to_tuple()) + self.rect.x = ppos[0] + self.rect.y = ppos[1] + + def animate(self): + """Step to the next frame. + + Set removed flag when we hit the end of the sequence""" + try: + self.setimage(self.iter.next()) + except StopIteration: + self.removed = True + +class MuzzleFlash(Animation): + + SEQUENCE_LEFT = [imagecache.load_image('sprites/muzzle_flash.png')] + SEQUENCE_RIGHT = [imagecache.load_image('sprites/muzzle_flash.png', + ("right_facing",))] + + def __init__(self, chicken): + if chicken.facing == 'right': + Animation.__init__(self, self.SEQUENCE_RIGHT, chicken.pos) + else: + Animation.__init__(self, self.SEQUENCE_LEFT, chicken.pos) +
--- a/gamelib/engine.py Fri Sep 04 20:16:51 2009 +0000 +++ b/gamelib/engine.py Fri Sep 04 20:23:30 2009 +0000 @@ -110,6 +110,7 @@ sound.play_sound("daybreak.ogg") # disable timer pygame.time.set_timer(MOVE_FOX_ID, 0) + pygame.time.set_timer(ANIM_ID, 50) self.game.gameboard.advance_day() self.game.gameboard.clear_foxes() sound.background_music("daytime.ogg") @@ -121,6 +122,8 @@ elif e.type is KEYDOWN and e.key == K_ESCAPE: self.game.gameboard.reset_cursor() return GameOver(self.game) + elif e.type is ANIM_ID: + self.game.gameboard.run_animations() elif e.type is KEYDOWN and e.key == K_n: return pygame.event.post(START_NIGHT) elif events_equal(e, GO_MAIN_MENU): @@ -151,6 +154,7 @@ # Add a timer to the event queue self.cycle_count = 0 pygame.time.set_timer(MOVE_FOX_ID, 200) + pygame.time.set_timer(ANIM_ID, 50) self.game.gameboard.spawn_foxes() sound.background_music("nighttime.ogg") @@ -166,6 +170,8 @@ elif e.type is KEYDOWN and e.key == K_ESCAPE: self.game.gameboard.reset_cursor() return GameOver(self.game) + elif e.type is ANIM_ID: + self.game.gameboard.run_animations() elif e.type is MOVE_FOX_ID: self.cycle_count += 1 if self.cycle_count > constants.NIGHT_LENGTH: @@ -194,6 +200,7 @@ sound.stop_background_music() self.game.create_game_over() pygame.time.set_timer(MOVE_FOX_ID, 0) + pygame.time.set_timer(ANIM_ID, 0) def event(self, e): if e.type is KEYDOWN: @@ -224,5 +231,6 @@ GO_MAIN_MENU = pygame.event.Event(USEREVENT, name="GO_MAIN_MENU") GO_HELP_SCREEN = pygame.event.Event(USEREVENT, name="GO_HELP_SCREEN") MOVE_FOX_ID = USEREVENT + 1 +ANIM_ID = USEREVENT + 6 MOVE_FOXES = pygame.event.Event(MOVE_FOX_ID, name="MOVE_FOXES") QUIT = pygame.event.Event(QUIT)
--- a/gamelib/equipment.py Fri Sep 04 20:16:51 2009 +0000 +++ b/gamelib/equipment.py Fri Sep 04 20:23:30 2009 +0000 @@ -3,6 +3,7 @@ import random import sound import imagecache +import animations class Equipment(object): IS_EQUIPMENT = True @@ -50,6 +51,8 @@ """Is the potentially unlucky target actually unlucky?""" if hasattr(self, 'HIT_SOUND'): sound.play_sound(self.HIT_SOUND) + if hasattr(self, 'ANIMATION'): + gameboard.animations.append(self.ANIMATION(wielder)) roll = random.randint(1, 100) base_hit = self._get_parameter('BASE_HIT', wielder) range_penalty = self._get_parameter('RANGE_PENALTY', wielder) @@ -74,6 +77,8 @@ CHICKEN_IMAGE_FILE = 'sprites/equip_rifle.png' + ANIMATION = animations.MuzzleFlash + class Knife(Weapon): TYPE = "KNIFE" NAME = "knife"
--- a/gamelib/gameboard.py Fri Sep 04 20:16:51 2009 +0000 +++ b/gamelib/gameboard.py Fri Sep 04 20:23:30 2009 +0000 @@ -149,9 +149,39 @@ def paint(self, surface): self.vid.paint(surface) + # Blit animation frames on top of the drawing + x, y = self.vid.view.x, self.vid.view.y + for anim in self.gameboard.animations: + anim.fix_pos(self.vid) + anim.irect.x = anim.rect.x - anim.shape.x + anim.irect.y = anim.rect.y - anim.shape.y + surface.blit(anim.image, (anim.irect.x - x, anim.irect.y - y)) + # We don't store anim._irect, since we only update anims if the + # image changes, which kills irect def update(self, surface): - return self.vid.update(surface) + us = [] + x, y = self.vid.view.x, self.vid.view.y + for anim in self.gameboard.animations[:]: + """Handle completed animations""" + if anim.removed: + us.append(pygame.Rect(anim.irect.x - x, anim.irect.y - y, + anim.irect.width, anim.irect.height)) + self.gameboard.animations.remove(anim) + # Flag the underlying tiles/sprites to be redrawn + self.vid.alayer[anim.pos.y][anim.pos.x]=1 + us.extend(self.vid.update(surface)) + for anim in self.gameboard.animations: + if anim.updated: + anim.fix_pos(self.vid) + # setimage has happened + anim.irect.x = anim.rect.x - anim.shape.x + anim.irect.y = anim.rect.y - anim.shape.y + surface.blit(anim.image, (anim.irect.x - x, anim.irect.y - y)) + anim.updated = 0 + us.append(pygame.Rect(anim.irect.x - x, anim.irect.y - y, + anim.irect.width, anim.irect.height)) + return us def move_view(self, x, y): self.vid.view.move_ip((x, y)) @@ -186,6 +216,7 @@ self.chickens = set() self.foxes = set() self.buildings = [] + self.animations = [] self.cash = 0 self.eggs = 0 self.days = 0 @@ -593,6 +624,10 @@ self.tv.sprites.remove(fox) self.foxes = set() # Remove all the foxes + def run_animations(self): + for anim in self.animations: + anim.animate() + def move_foxes(self): """Move the foxes.