Changeset 622:da331c80ec08


Ignore:
Timestamp:
05/07/11 11:42:27 (12 years ago)
Author:
Jeremy Thurgood <firxen@…>
Branch:
default
Phase:
public
Message:

Clean up sprite inheritance hierarchy a bit.

Location:
skaapsteker
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • skaapsteker/levelscene.py

    r621 r622  
    7878        self._player.set_facing(doorway.facing)
    7979        self._player.set_image()
    80         self._player.set_pos(doorway._starting_tile_pos)
     80        self._player.set_pos(doorway.get_tile_pos())
    8181
    8282        # Double tap stuff
  • skaapsteker/physics.py

    r619 r622  
    5353
    5454    def init_pos(self):
    55         self._float_pos = self.rect.topleft
     55        self._float_pos = self.rect.center
    5656
    5757    def get_debug_color(self):
     
    6868
    6969    def deltap(self, dt):
    70         old_pos = self.rect.topleft
     70        old_pos = self.rect.center
    7171        self._float_pos = cadd(self._float_pos, cmul(self.velocity, dt))
    72         self.rect.topleft = cint(self._float_pos)
    73         delta_pos = csub(self.rect.topleft, old_pos)
     72        self.rect.center = cint(self._float_pos)
     73        delta_pos = csub(self.rect.center, old_pos)
    7474        self.collide_rect.move_ip(delta_pos)
    7575        self.floor_rect.move_ip(delta_pos)
  • skaapsteker/sprites/base.py

    r621 r622  
    3535    image_dir = 'sprites/'
    3636    image_file = None
     37    sprite_layer = None
    3738
    3839    def __init__(self, pos, **opts):
    3940        Sprite.__init__(self)
    40         self._starting_tile_pos = pos
     41        if self.sprite_layer is not None:
     42            # pygame's Sprite class clobbers self._layer in __init__(), so we need to thwart it.
     43            self._layer = self.sprite_layer
     44        self.setup_image_data(pos)
    4145        self.setup(**opts)
    42         self.setup_image_data(pos)
    4346
    4447    def setup(self):
    4548        pass
     49
     50    def get_tile_pos(self):
     51        return cdiv(self.rect.center, TILE_SIZE)
    4652
    4753    def setup_image_data(self, pos):
     
    5157
    5258
    53 class AnimatedGameSprite(Sprite):
    54     # folder for animation files, e.g. sprites/foo
    55     image_dir = None
    56 
     59class AnimatedGameSprite(GameSprite):
    5760    # first item is the starting animation
    58     animation_regexes = [
     61    animation_regexes = (
    5962        # TODO: swap back once we know how to swap
    6063        ("running", r"^.*_\d+.png$"),
    6164        ("standing", r"^.*_standing.png$"),
    6265        ("attacking", r"^.*_attacking.png$"),
    63     ]
     66    )
    6467
    6568    wants_updates = True
    66 
    6769    frame_pause = 0.1  # default time between animation frames
    68 
    69     facings = {}
    70 
    71     def __init__(self, pos, **opts):
    72         Sprite.__init__(self)
     70    facings = None
     71
     72
     73    def setup_image_data(self, pos):
    7374        self._animations = dict((k, []) for k, r in self.animation_regexes)
    7475        self._frame = 0
     
    104105            self.collide_rect.midbottom = tile_midbottom(pos)
    105106        self._update_image()
    106         self.setup(**opts)
    107 
    108     def setup(self):
    109         pass
     107
    110108
    111109    def _update_image(self, force=False):
     
    150148class Monster(AnimatedGameSprite):
    151149
     150    sprite_layer = Layers.PLAYER
    152151    collision_layer = MONSTER_LAYER
    153152    collides_with = set([PC_LAYER, PROJECTILE_LAYER])
     
    157156    block = True
    158157
    159     attack_frame = None  # Mark a spefici frame in the animatio n as when the attack lands
     158    attack_frame = None  # Mark a speficic frame in the animation as when the attack lands
    160159    attack_damage = 1
    161160
     
    163162        AnimatedGameSprite.__init__(self, pos, **opts)
    164163        self.floor_rect = Rect(self.collide_rect.topleft, (self.collide_rect.width, 2))
    165         self._layer = Layers.PLAYER
    166164        self.health = 10
    167165        self._done_attack = False
     
    274272class NPC(AnimatedGameSprite):
    275273
     274    sprite_layer = Layers.PLAYER
    276275    collision_layer = NPC_LAYER
    277276    collides_with = set([])
     
    283282    block = False
    284283    actionable = True
    285 
    286     def __init__(self, pos, **opts):
    287         AnimatedGameSprite.__init__(self, pos, **opts)
    288         self._layer = Layers.PLAYER
    289284
    290285    def setup(self, name, world, dsm, state, facing=None):
     
    376371    liftable = True
    377372
     373    sprite_layer = Layers.PLAYER
    378374    collision_layer = NPC_LAYER
    379375
    380376    debug_color = (240, 0, 240)
    381 
    382     def __init__(self, pos, **opts):
    383         GameSprite.__init__(self, pos, **opts)
    384         self._layer = Layers.PLAYER
    385377
    386378
     
    485477    liftable = False
    486478    image_dir = 'sprites/skulls/'
     479    sprite_layer = Layers.BEHIND
    487480    debug_color = (255, 255, 0)
     481
    488482
    489483    def __init__(self, pos, player=False, **opts):
     
    493487        else:
    494488            self.image_file = 'monster.png'
    495         GameSprite.__init__(self, pos, **opts)
    496         self._layer = Layers.BEHIND
     489        super(Skeleton, self).__init__(pos, **opts)
    497490
    498491    def setup_image_data(self, pos):
  • skaapsteker/sprites/items.py

    r573 r622  
    3030            self._me.broken = True
    3131            self.broken = True
    32             self.setup_image_data(self._starting_tile_pos)
     32            self.setup_image_data(self.get_tile_pos())
    3333            if self.breaking_sound[0] is not None:
    3434                sound.play_sound(self.breaking_sound[0])
  • skaapsteker/sprites/player.py

    r621 r622  
    66from pygame.constants import BLEND_RGBA_MULT
    77
    8 from ..physics import Sprite
    98from ..constants import Layers, FoxHud, DOUBLE_TAP_TIME
    109from ..data import get_files, load_image
     
    1211from ..utils import cadd
    1312
    14 from .base import (find_sprite, Monster, NPC, Item, Doorway, TILE_SIZE,
    15                    PC_LAYER, MONSTER_LAYER, PROJECTILE_LAYER, tile_midbottom)
     13from .base import (find_sprite, AnimatedGameSprite, Monster, NPC, Item, Doorway,
     14                   TILE_SIZE, PC_LAYER, MONSTER_LAYER, PROJECTILE_LAYER,
     15                   tile_midbottom)
    1616from .projectiles import Fireball, Lightning
    1717from .items import BreakableItem
     
    1919
    2020
    21 class Player(Sprite):
    22 
     21class Player(AnimatedGameSprite):
     22
     23    sprite_layer = Layers.PLAYER
    2324    collision_layer = PC_LAYER
    2425    collides_with = set([MONSTER_LAYER, PROJECTILE_LAYER])
    2526    wants_updates = True
    26 
    2727    block = True
    2828
    29 
    3029    def __init__(self, the_world, soundsystem):
    31         Sprite.__init__(self)
     30        super(Player, self).__init__((0, 0))
    3231        self.image = None
    3332        self.rect = None
    34         self._image_dict = {}
    3533        self._soundsystem = soundsystem
    3634        self._soundsystem.load_sound('yelp', 'sounds/yelp.ogg')
     
    5452        self.invisible = 0
    5553        self.using_shield = 0
    56         self.shape = 'fox'  # Needed so load image does the right thing
    57         self._load_images()
    5854        self.inventory_image = None
    5955        # We muck with these in load for convience, so ensure they're right
     
    6662        self._collisions_seen = 0
    6763        self._last_collide = []
    68         self._layer = Layers.PLAYER
     64
     65
     66    def setup_image_data(self, pos):
     67        self.shape = 'fox'  # Needed so load image does the right thing
     68        self._image_dict = {}
     69        self._shield_image = load_image('sprites/kitsune_shield.png')
     70        for action in ['standing', 'running', 'jumping', 'attacking']:
     71            for tails in [0, 1, 2, 4]:
     72                directory = 'sprites/kitsune_%s/kitsune_%s_%dtail' % (action, action, tails)
     73                for facing in ['left', 'right']:
     74                    self.facing = facing
     75                    key = self._make_key(tails, action)
     76                    self._image_dict[key] = []
     77                    for image_file in get_files(directory):
     78                        if image_file.startswith('.'):
     79                            # Skip extra junk for now
     80                            continue
     81                        image = load_image('%s/%s' % (directory, image_file))
     82                        if action == 'running':
     83                            sprint_key = self._make_key(tails, 'sprinting')
     84                            if sprint_key not in self._image_dict:
     85                                self._image_dict[sprint_key] = []
     86                            shockwave = load_image('sprites/kitsune_shockwave.png')
     87                            if facing == 'right':
     88                                shockwave = pygame.transform.flip(shockwave, True, False)
     89                        if facing == 'right':
     90                            image = pygame.transform.flip(image, True, False)
     91                        self._image_dict[key].append(image)
     92                        if action == 'running':
     93                            sprint_image = image.copy()
     94                            sprint_image.blit(shockwave, (0, 0))
     95                            self._image_dict[sprint_key].append(sprint_image)
     96        for shape, name in [('human', 'disguise_'), ('human_with_fan', 'disguise-fan_')]:
     97            directory = 'sprites/kitsune_disguise'
     98            for facing in ['left', 'right']:
     99                key = '%s_running_%s' % (shape, facing)
     100                standing_key = '%s_standing_%s' % (shape, facing)
     101                self._image_dict[key] = []
     102                for image_file in get_files(directory):
     103                    if name not in image_file:
     104                        continue
     105                    image = load_image('%s/%s' % (directory, image_file))
     106                    if facing == 'right':
     107                        image = pygame.transform.flip(image, True, False)
     108                    self._image_dict[key].append(image)
     109                self._image_dict[standing_key] = [self._image_dict[key][0]]
     110
    69111
    70112    def set_image(self):
     
    260302    def set_pos(self, pos):
    261303        self.rect.midbottom = cadd(tile_midbottom(pos), self.rect_offset)
    262         # self.collide_rect.midbottom = pos[0] * TILE_SIZE[0], (pos[1] + 1) * TILE_SIZE[1] # Is this wrong?
    263         self.collide_rect.midbottom = self.rect.midbottom
     304        self.collide_rect.midbottom = tile_midbottom(pos)
    264305
    265306    def action_left(self):
     
    465506        return '%s %s %d' % (action, self.facing, tails)
    466507
    467     def _load_images(self):
    468         self._shield_image = load_image('sprites/kitsune_shield.png')
    469         for action in ['standing', 'running', 'jumping', 'attacking']:
    470             for tails in [0, 1, 2, 4]:
    471                 directory = 'sprites/kitsune_%s/kitsune_%s_%dtail' % (action, action, tails)
    472                 for facing in ['left', 'right']:
    473                     self.facing = facing
    474                     key = self._make_key(tails, action)
    475                     self._image_dict[key] = []
    476                     for image_file in get_files(directory):
    477                         if image_file.startswith('.'):
    478                             # Skip extra junk for now
    479                             continue
    480                         image = load_image('%s/%s' % (directory, image_file))
    481                         if action == 'running':
    482                             sprint_key = self._make_key(tails, 'sprinting')
    483                             if sprint_key not in self._image_dict:
    484                                 self._image_dict[sprint_key] = []
    485                             shockwave = load_image('sprites/kitsune_shockwave.png')
    486                             if facing == 'right':
    487                                 shockwave = pygame.transform.flip(shockwave, True, False)
    488                         if facing == 'right':
    489                             image = pygame.transform.flip(image, True, False)
    490                         self._image_dict[key].append(image)
    491                         if action == 'running':
    492                             sprint_image = image.copy()
    493                             sprint_image.blit(shockwave, (0, 0))
    494                             self._image_dict[sprint_key].append(sprint_image)
    495         for shape, name in [('human', 'disguise_'), ('human_with_fan', 'disguise-fan_')]:
    496             directory = 'sprites/kitsune_disguise'
    497             for facing in ['left', 'right']:
    498                 key = '%s_running_%s' % (shape, facing)
    499                 standing_key = '%s_standing_%s' % (shape, facing)
    500                 self._image_dict[key] = []
    501                 for image_file in get_files(directory):
    502                     if name not in image_file:
    503                         continue
    504                     image = load_image('%s/%s' % (directory, image_file))
    505                     if facing == 'right':
    506                         image = pygame.transform.flip(image, True, False)
    507                     self._image_dict[key].append(image)
    508                 self._image_dict[standing_key] = [self._image_dict[key][0]]
    509 
    510 
    511508    def discard_item(self):
    512509        self._me.item = None
    513510
    514 
    515     def get_tile_pos(self):
    516         return [a/b for a, b in zip(self.rect.center, TILE_SIZE)]
    517 
    518     def get_tile_for_pos(self, pos):
    519         return [a/b for a, b in zip(pos, TILE_SIZE)]
    520511
    521512    def get_sprite(self, set_level):
Note: See TracChangeset for help on using the changeset viewer.