Mercurial > skaapsteker
comparison skaapsteker/sprites/base.py @ 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 |
comparison
equal
deleted
inserted
replaced
621:851c8726696c | 622:da331c80ec08 |
---|---|
32 | 32 |
33 | 33 |
34 class GameSprite(Sprite): | 34 class GameSprite(Sprite): |
35 image_dir = 'sprites/' | 35 image_dir = 'sprites/' |
36 image_file = None | 36 image_file = None |
37 sprite_layer = None | |
37 | 38 |
38 def __init__(self, pos, **opts): | 39 def __init__(self, pos, **opts): |
39 Sprite.__init__(self) | 40 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) | |
41 self.setup(**opts) | 45 self.setup(**opts) |
42 self.setup_image_data(pos) | |
43 | 46 |
44 def setup(self): | 47 def setup(self): |
45 pass | 48 pass |
49 | |
50 def get_tile_pos(self): | |
51 return cdiv(self.rect.center, TILE_SIZE) | |
46 | 52 |
47 def setup_image_data(self, pos): | 53 def setup_image_data(self, pos): |
48 self.image = data.load_image(self.image_dir + self.image_file) | 54 self.image = data.load_image(self.image_dir + self.image_file) |
49 self.rect = self.image.get_rect(midbottom=tile_midbottom(pos)) | 55 self.rect = self.image.get_rect(midbottom=tile_midbottom(pos)) |
50 self.collide_rect = self.rect.move(0, 0) | 56 self.collide_rect = self.rect.move(0, 0) |
51 | 57 |
52 | 58 |
53 class AnimatedGameSprite(Sprite): | 59 class AnimatedGameSprite(GameSprite): |
54 # folder for animation files, e.g. sprites/foo | |
55 image_dir = None | |
56 | |
57 # first item is the starting animation | 60 # first item is the starting animation |
58 animation_regexes = [ | 61 animation_regexes = ( |
59 # TODO: swap back once we know how to swap | 62 # TODO: swap back once we know how to swap |
60 ("running", r"^.*_\d+.png$"), | 63 ("running", r"^.*_\d+.png$"), |
61 ("standing", r"^.*_standing.png$"), | 64 ("standing", r"^.*_standing.png$"), |
62 ("attacking", r"^.*_attacking.png$"), | 65 ("attacking", r"^.*_attacking.png$"), |
63 ] | 66 ) |
64 | 67 |
65 wants_updates = True | 68 wants_updates = True |
66 | |
67 frame_pause = 0.1 # default time between animation frames | 69 frame_pause = 0.1 # default time between animation frames |
68 | 70 facings = None |
69 facings = {} | 71 |
70 | 72 |
71 def __init__(self, pos, **opts): | 73 def setup_image_data(self, pos): |
72 Sprite.__init__(self) | |
73 self._animations = dict((k, []) for k, r in self.animation_regexes) | 74 self._animations = dict((k, []) for k, r in self.animation_regexes) |
74 self._frame = 0 | 75 self._frame = 0 |
75 self._last_time = 0 | 76 self._last_time = 0 |
76 self._animation = self.animation_regexes[0][0] | 77 self._animation = self.animation_regexes[0][0] |
77 if self.facings and self._animation in self.facings: | 78 if self.facings and self._animation in self.facings: |
101 if isinstance(pos, pygame.Rect): | 102 if isinstance(pos, pygame.Rect): |
102 self.collide_rect.midbottom = pos.midbottom | 103 self.collide_rect.midbottom = pos.midbottom |
103 else: | 104 else: |
104 self.collide_rect.midbottom = tile_midbottom(pos) | 105 self.collide_rect.midbottom = tile_midbottom(pos) |
105 self._update_image() | 106 self._update_image() |
106 self.setup(**opts) | 107 |
107 | |
108 def setup(self): | |
109 pass | |
110 | 108 |
111 def _update_image(self, force=False): | 109 def _update_image(self, force=False): |
112 if self.facing: | 110 if self.facing: |
113 images = self._animations[self._animation][self.facing] | 111 images = self._animations[self._animation][self.facing] |
114 else: | 112 else: |
147 self._last_time = time.time() | 145 self._last_time = time.time() |
148 | 146 |
149 | 147 |
150 class Monster(AnimatedGameSprite): | 148 class Monster(AnimatedGameSprite): |
151 | 149 |
150 sprite_layer = Layers.PLAYER | |
152 collision_layer = MONSTER_LAYER | 151 collision_layer = MONSTER_LAYER |
153 collides_with = set([PC_LAYER, PROJECTILE_LAYER]) | 152 collides_with = set([PC_LAYER, PROJECTILE_LAYER]) |
154 | 153 |
155 debug_color = (240, 120, 120) | 154 debug_color = (240, 120, 120) |
156 | 155 |
157 block = True | 156 block = True |
158 | 157 |
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 |
160 attack_damage = 1 | 159 attack_damage = 1 |
161 | 160 |
162 def __init__(self, pos, **opts): | 161 def __init__(self, pos, **opts): |
163 AnimatedGameSprite.__init__(self, pos, **opts) | 162 AnimatedGameSprite.__init__(self, pos, **opts) |
164 self.floor_rect = Rect(self.collide_rect.topleft, (self.collide_rect.width, 2)) | 163 self.floor_rect = Rect(self.collide_rect.topleft, (self.collide_rect.width, 2)) |
165 self._layer = Layers.PLAYER | |
166 self.health = 10 | 164 self.health = 10 |
167 self._done_attack = False | 165 self._done_attack = False |
168 self.setup(**opts) | 166 self.setup(**opts) |
169 | 167 |
170 def setup(self, fishmonger_count=False): | 168 def setup(self, fishmonger_count=False): |
271 if self.collide_rect.centerx > floor.collide_rect.centerx: | 269 if self.collide_rect.centerx > floor.collide_rect.centerx: |
272 self.change_facing() | 270 self.change_facing() |
273 | 271 |
274 class NPC(AnimatedGameSprite): | 272 class NPC(AnimatedGameSprite): |
275 | 273 |
274 sprite_layer = Layers.PLAYER | |
276 collision_layer = NPC_LAYER | 275 collision_layer = NPC_LAYER |
277 collides_with = set([]) | 276 collides_with = set([]) |
278 | 277 |
279 debug_color = (240, 240, 240) | 278 debug_color = (240, 240, 240) |
280 bounce_factor = (0, 0) # NPC's don't bounce by default | 279 bounce_factor = (0, 0) # NPC's don't bounce by default |
281 gravitates = False | 280 gravitates = False |
282 | 281 |
283 block = False | 282 block = False |
284 actionable = True | 283 actionable = True |
285 | |
286 def __init__(self, pos, **opts): | |
287 AnimatedGameSprite.__init__(self, pos, **opts) | |
288 self._layer = Layers.PLAYER | |
289 | 284 |
290 def setup(self, name, world, dsm, state, facing=None): | 285 def setup(self, name, world, dsm, state, facing=None): |
291 self.name = name | 286 self.name = name |
292 self.world = world | 287 self.world = world |
293 self.dsm = dialogue.DSM(name, world, dsm, state) | 288 self.dsm = dialogue.DSM(name, world, dsm, state) |
373 mobile = False | 368 mobile = False |
374 gravitates = False | 369 gravitates = False |
375 actionable = True | 370 actionable = True |
376 liftable = True | 371 liftable = True |
377 | 372 |
373 sprite_layer = Layers.PLAYER | |
378 collision_layer = NPC_LAYER | 374 collision_layer = NPC_LAYER |
379 | 375 |
380 debug_color = (240, 0, 240) | 376 debug_color = (240, 0, 240) |
381 | |
382 def __init__(self, pos, **opts): | |
383 GameSprite.__init__(self, pos, **opts) | |
384 self._layer = Layers.PLAYER | |
385 | 377 |
386 | 378 |
387 def setup(self, name, world): | 379 def setup(self, name, world): |
388 self.name = name | 380 self.name = name |
389 self.world = world | 381 self.world = world |
482 mobile = False | 474 mobile = False |
483 gravitates = False | 475 gravitates = False |
484 actionable = False | 476 actionable = False |
485 liftable = False | 477 liftable = False |
486 image_dir = 'sprites/skulls/' | 478 image_dir = 'sprites/skulls/' |
479 sprite_layer = Layers.BEHIND | |
487 debug_color = (255, 255, 0) | 480 debug_color = (255, 255, 0) |
481 | |
488 | 482 |
489 def __init__(self, pos, player=False, **opts): | 483 def __init__(self, pos, player=False, **opts): |
490 self._pos = pos | 484 self._pos = pos |
491 if player: | 485 if player: |
492 self.image_file = 'kitsune.png' | 486 self.image_file = 'kitsune.png' |
493 else: | 487 else: |
494 self.image_file = 'monster.png' | 488 self.image_file = 'monster.png' |
495 GameSprite.__init__(self, pos, **opts) | 489 super(Skeleton, self).__init__(pos, **opts) |
496 self._layer = Layers.BEHIND | |
497 | 490 |
498 def setup_image_data(self, pos): | 491 def setup_image_data(self, pos): |
499 GameSprite.setup_image_data(self, pos) | 492 GameSprite.setup_image_data(self, pos) |
500 # Pixel based rect, not tile: | 493 # Pixel based rect, not tile: |
501 self.rect = self.image.get_rect(midbottom=self._pos) | 494 self.rect = self.image.get_rect(midbottom=self._pos) |