Mercurial > skaapsteker
changeset 622:da331c80ec08
Clean up sprite inheritance hierarchy a bit.
author | Jeremy Thurgood <firxen@gmail.com> |
---|---|
date | Sat, 07 May 2011 13:42:27 +0200 |
parents | 851c8726696c |
children | 65881746dc20 |
files | skaapsteker/levelscene.py skaapsteker/physics.py skaapsteker/sprites/base.py skaapsteker/sprites/items.py skaapsteker/sprites/player.py |
diffstat | 5 files changed, 80 insertions(+), 96 deletions(-) [+] |
line wrap: on
line diff
--- a/skaapsteker/levelscene.py Fri May 06 17:54:24 2011 +0200 +++ b/skaapsteker/levelscene.py Sat May 07 13:42:27 2011 +0200 @@ -77,7 +77,7 @@ self._player = player.Player(self.game_state.world, self._soundsystem) self._player.set_facing(doorway.facing) self._player.set_image() - self._player.set_pos(doorway._starting_tile_pos) + self._player.set_pos(doorway.get_tile_pos()) # Double tap stuff self._last_keydown_time = None
--- a/skaapsteker/physics.py Fri May 06 17:54:24 2011 +0200 +++ b/skaapsteker/physics.py Sat May 07 13:42:27 2011 +0200 @@ -52,7 +52,7 @@ self._mask_cache = {} # image id -> collision bit mask def init_pos(self): - self._float_pos = self.rect.topleft + self._float_pos = self.rect.center def get_debug_color(self): return self.debug_color @@ -67,10 +67,10 @@ def deltap(self, dt): - old_pos = self.rect.topleft + old_pos = self.rect.center self._float_pos = cadd(self._float_pos, cmul(self.velocity, dt)) - self.rect.topleft = cint(self._float_pos) - delta_pos = csub(self.rect.topleft, old_pos) + self.rect.center = cint(self._float_pos) + delta_pos = csub(self.rect.center, old_pos) self.collide_rect.move_ip(delta_pos) self.floor_rect.move_ip(delta_pos)
--- a/skaapsteker/sprites/base.py Fri May 06 17:54:24 2011 +0200 +++ b/skaapsteker/sprites/base.py Sat May 07 13:42:27 2011 +0200 @@ -34,42 +34,43 @@ class GameSprite(Sprite): image_dir = 'sprites/' image_file = None + sprite_layer = None def __init__(self, pos, **opts): Sprite.__init__(self) - self._starting_tile_pos = pos + if self.sprite_layer is not None: + # pygame's Sprite class clobbers self._layer in __init__(), so we need to thwart it. + self._layer = self.sprite_layer + self.setup_image_data(pos) self.setup(**opts) - self.setup_image_data(pos) def setup(self): pass + def get_tile_pos(self): + return cdiv(self.rect.center, TILE_SIZE) + def setup_image_data(self, pos): self.image = data.load_image(self.image_dir + self.image_file) self.rect = self.image.get_rect(midbottom=tile_midbottom(pos)) self.collide_rect = self.rect.move(0, 0) -class AnimatedGameSprite(Sprite): - # folder for animation files, e.g. sprites/foo - image_dir = None - +class AnimatedGameSprite(GameSprite): # first item is the starting animation - animation_regexes = [ + animation_regexes = ( # TODO: swap back once we know how to swap ("running", r"^.*_\d+.png$"), ("standing", r"^.*_standing.png$"), ("attacking", r"^.*_attacking.png$"), - ] + ) wants_updates = True - frame_pause = 0.1 # default time between animation frames + facings = None - facings = {} - def __init__(self, pos, **opts): - Sprite.__init__(self) + def setup_image_data(self, pos): self._animations = dict((k, []) for k, r in self.animation_regexes) self._frame = 0 self._last_time = 0 @@ -103,10 +104,7 @@ else: self.collide_rect.midbottom = tile_midbottom(pos) self._update_image() - self.setup(**opts) - def setup(self): - pass def _update_image(self, force=False): if self.facing: @@ -149,6 +147,7 @@ class Monster(AnimatedGameSprite): + sprite_layer = Layers.PLAYER collision_layer = MONSTER_LAYER collides_with = set([PC_LAYER, PROJECTILE_LAYER]) @@ -156,13 +155,12 @@ block = True - attack_frame = None # Mark a spefici frame in the animatio n as when the attack lands + attack_frame = None # Mark a speficic frame in the animation as when the attack lands attack_damage = 1 def __init__(self, pos, **opts): AnimatedGameSprite.__init__(self, pos, **opts) self.floor_rect = Rect(self.collide_rect.topleft, (self.collide_rect.width, 2)) - self._layer = Layers.PLAYER self.health = 10 self._done_attack = False self.setup(**opts) @@ -273,6 +271,7 @@ class NPC(AnimatedGameSprite): + sprite_layer = Layers.PLAYER collision_layer = NPC_LAYER collides_with = set([]) @@ -283,10 +282,6 @@ block = False actionable = True - def __init__(self, pos, **opts): - AnimatedGameSprite.__init__(self, pos, **opts) - self._layer = Layers.PLAYER - def setup(self, name, world, dsm, state, facing=None): self.name = name self.world = world @@ -375,14 +370,11 @@ actionable = True liftable = True + sprite_layer = Layers.PLAYER collision_layer = NPC_LAYER debug_color = (240, 0, 240) - def __init__(self, pos, **opts): - GameSprite.__init__(self, pos, **opts) - self._layer = Layers.PLAYER - def setup(self, name, world): self.name = name @@ -484,16 +476,17 @@ actionable = False liftable = False image_dir = 'sprites/skulls/' + sprite_layer = Layers.BEHIND debug_color = (255, 255, 0) + def __init__(self, pos, player=False, **opts): self._pos = pos if player: self.image_file = 'kitsune.png' else: self.image_file = 'monster.png' - GameSprite.__init__(self, pos, **opts) - self._layer = Layers.BEHIND + super(Skeleton, self).__init__(pos, **opts) def setup_image_data(self, pos): GameSprite.setup_image_data(self, pos)
--- a/skaapsteker/sprites/items.py Fri May 06 17:54:24 2011 +0200 +++ b/skaapsteker/sprites/items.py Sat May 07 13:42:27 2011 +0200 @@ -29,7 +29,7 @@ if not self._me.broken: self._me.broken = True self.broken = True - self.setup_image_data(self._starting_tile_pos) + self.setup_image_data(self.get_tile_pos()) if self.breaking_sound[0] is not None: sound.play_sound(self.breaking_sound[0])
--- a/skaapsteker/sprites/player.py Fri May 06 17:54:24 2011 +0200 +++ b/skaapsteker/sprites/player.py Sat May 07 13:42:27 2011 +0200 @@ -5,33 +5,31 @@ import pygame.transform from pygame.constants import BLEND_RGBA_MULT -from ..physics import Sprite from ..constants import Layers, FoxHud, DOUBLE_TAP_TIME from ..data import get_files, load_image from ..engine import PlayerDied, AddSpriteEvent, OpenNotification from ..utils import cadd -from .base import (find_sprite, Monster, NPC, Item, Doorway, TILE_SIZE, - PC_LAYER, MONSTER_LAYER, PROJECTILE_LAYER, tile_midbottom) +from .base import (find_sprite, AnimatedGameSprite, Monster, NPC, Item, Doorway, + TILE_SIZE, PC_LAYER, MONSTER_LAYER, PROJECTILE_LAYER, + tile_midbottom) from .projectiles import Fireball, Lightning from .items import BreakableItem -class Player(Sprite): +class Player(AnimatedGameSprite): + sprite_layer = Layers.PLAYER collision_layer = PC_LAYER collides_with = set([MONSTER_LAYER, PROJECTILE_LAYER]) wants_updates = True - block = True - def __init__(self, the_world, soundsystem): - Sprite.__init__(self) + super(Player, self).__init__((0, 0)) self.image = None self.rect = None - self._image_dict = {} self._soundsystem = soundsystem self._soundsystem.load_sound('yelp', 'sounds/yelp.ogg') self._animation_frame = 0.0 @@ -53,8 +51,6 @@ self.prep_flight = 0.0 self.invisible = 0 self.using_shield = 0 - self.shape = 'fox' # Needed so load image does the right thing - self._load_images() self.inventory_image = None # We muck with these in load for convience, so ensure they're right self.the_world = the_world @@ -65,7 +61,53 @@ self.set_pos((0, 0)) self._collisions_seen = 0 self._last_collide = [] - self._layer = Layers.PLAYER + + + def setup_image_data(self, pos): + self.shape = 'fox' # Needed so load image does the right thing + self._image_dict = {} + self._shield_image = load_image('sprites/kitsune_shield.png') + for action in ['standing', 'running', 'jumping', 'attacking']: + for tails in [0, 1, 2, 4]: + directory = 'sprites/kitsune_%s/kitsune_%s_%dtail' % (action, action, tails) + for facing in ['left', 'right']: + self.facing = facing + key = self._make_key(tails, action) + self._image_dict[key] = [] + for image_file in get_files(directory): + if image_file.startswith('.'): + # Skip extra junk for now + continue + image = load_image('%s/%s' % (directory, image_file)) + if action == 'running': + sprint_key = self._make_key(tails, 'sprinting') + if sprint_key not in self._image_dict: + self._image_dict[sprint_key] = [] + shockwave = load_image('sprites/kitsune_shockwave.png') + if facing == 'right': + shockwave = pygame.transform.flip(shockwave, True, False) + if facing == 'right': + image = pygame.transform.flip(image, True, False) + self._image_dict[key].append(image) + if action == 'running': + sprint_image = image.copy() + sprint_image.blit(shockwave, (0, 0)) + self._image_dict[sprint_key].append(sprint_image) + for shape, name in [('human', 'disguise_'), ('human_with_fan', 'disguise-fan_')]: + directory = 'sprites/kitsune_disguise' + for facing in ['left', 'right']: + key = '%s_running_%s' % (shape, facing) + standing_key = '%s_standing_%s' % (shape, facing) + self._image_dict[key] = [] + for image_file in get_files(directory): + if name not in image_file: + continue + image = load_image('%s/%s' % (directory, image_file)) + if facing == 'right': + image = pygame.transform.flip(image, True, False) + self._image_dict[key].append(image) + self._image_dict[standing_key] = [self._image_dict[key][0]] + def set_image(self): key = self._make_key(len(self._me.tails)) @@ -259,8 +301,7 @@ def set_pos(self, pos): self.rect.midbottom = cadd(tile_midbottom(pos), self.rect_offset) - # self.collide_rect.midbottom = pos[0] * TILE_SIZE[0], (pos[1] + 1) * TILE_SIZE[1] # Is this wrong? - self.collide_rect.midbottom = self.rect.midbottom + self.collide_rect.midbottom = tile_midbottom(pos) def action_left(self): self.set_facing('left') @@ -464,60 +505,10 @@ tails = 2 return '%s %s %d' % (action, self.facing, tails) - def _load_images(self): - self._shield_image = load_image('sprites/kitsune_shield.png') - for action in ['standing', 'running', 'jumping', 'attacking']: - for tails in [0, 1, 2, 4]: - directory = 'sprites/kitsune_%s/kitsune_%s_%dtail' % (action, action, tails) - for facing in ['left', 'right']: - self.facing = facing - key = self._make_key(tails, action) - self._image_dict[key] = [] - for image_file in get_files(directory): - if image_file.startswith('.'): - # Skip extra junk for now - continue - image = load_image('%s/%s' % (directory, image_file)) - if action == 'running': - sprint_key = self._make_key(tails, 'sprinting') - if sprint_key not in self._image_dict: - self._image_dict[sprint_key] = [] - shockwave = load_image('sprites/kitsune_shockwave.png') - if facing == 'right': - shockwave = pygame.transform.flip(shockwave, True, False) - if facing == 'right': - image = pygame.transform.flip(image, True, False) - self._image_dict[key].append(image) - if action == 'running': - sprint_image = image.copy() - sprint_image.blit(shockwave, (0, 0)) - self._image_dict[sprint_key].append(sprint_image) - for shape, name in [('human', 'disguise_'), ('human_with_fan', 'disguise-fan_')]: - directory = 'sprites/kitsune_disguise' - for facing in ['left', 'right']: - key = '%s_running_%s' % (shape, facing) - standing_key = '%s_standing_%s' % (shape, facing) - self._image_dict[key] = [] - for image_file in get_files(directory): - if name not in image_file: - continue - image = load_image('%s/%s' % (directory, image_file)) - if facing == 'right': - image = pygame.transform.flip(image, True, False) - self._image_dict[key].append(image) - self._image_dict[standing_key] = [self._image_dict[key][0]] - - def discard_item(self): self._me.item = None - def get_tile_pos(self): - return [a/b for a, b in zip(self.rect.center, TILE_SIZE)] - - def get_tile_for_pos(self, pos): - return [a/b for a, b in zip(pos, TILE_SIZE)] - def get_sprite(self, set_level): my_item = self._me.item if my_item is None: