Mercurial > touhou
diff pytouhou/game/player.py @ 172:ea2ad94c33a0
Implement player death.
author | Emmanuel Gil Peyrot <linkmauve@linkmauve.fr> |
---|---|
date | Fri, 21 Oct 2011 09:29:16 -0700 |
parents | 7769ce7be03c |
children | 35d850502d1f |
line wrap: on
line diff
--- a/pytouhou/game/player.py +++ b/pytouhou/game/player.py @@ -14,6 +14,7 @@ from pytouhou.game.sprite import Sprite +from pytouhou.game.enemy import Effect from pytouhou.vm.anmrunner import ANMRunner @@ -35,11 +36,15 @@ class PlayerState(object): self.x = 192.0 self.y = 384.0 + self.invulnerable_time = 60 + self.touchable = True + class Player(object): - def __init__(self, state, character): + def __init__(self, state, character, game): self._sprite = None self._anmrunner = None + self._game = game self.hitbox_half_size = character.hitbox_size / 2. @@ -50,6 +55,8 @@ class Player(object): self.set_anim(0) + self.death_time = 0 + @property def x(self): @@ -68,11 +75,10 @@ class Player(object): def collide(self): - self.state.lives -= 1 - self.state.x = 192.0 - self.state.y = 384.0 - #TODO: animation - #TODO: set invulnerability. + if not self.state.invulnerable_time and not self.death_time and self.state.touchable: # Border Between Life and Death + self.death_time = self._game.frame + eff00 = self._game.resource_loader.get_anm_wrapper(('eff00.anm',)) + self._game.effects.append(Effect((self.state.x, self.state.y), 2, eff00)) def collect(self, item): @@ -82,29 +88,83 @@ class Player(object): def update(self, keystate): - try: - dx, dy = {16: (0.0, -1.0), 32: (0.0, 1.0), 64: (-1.0, 0.0), 128: (1.0, 0.0), - 16|64: (-SQ2, -SQ2), 16|128: (SQ2, -SQ2), - 32|64: (-SQ2, SQ2), 32|128: (SQ2, SQ2)}[keystate & (16|32|64|128)] - except KeyError: - speed = 0.0 - dx, dy = 0.0, 0.0 - else: - speed = self.character.focused_speed if keystate & 4 else self.character.speed - dx, dy = dx * speed, dy * speed + if self.death_time == 0 or self._game.frame - self.death_time > 60: + try: + dx, dy = {16: (0.0, -1.0), 32: (0.0, 1.0), 64: (-1.0, 0.0), 128: (1.0, 0.0), + 16|64: (-SQ2, -SQ2), 16|128: (SQ2, -SQ2), + 32|64: (-SQ2, SQ2), 32|128: (SQ2, SQ2)}[keystate & (16|32|64|128)] + except KeyError: + speed = 0.0 + dx, dy = 0.0, 0.0 + else: + speed = self.character.focused_speed if keystate & 4 else self.character.speed + dx, dy = dx * speed, dy * speed + + if dx < 0 and self.direction != -1: + self.set_anim(1) + self.direction = -1 + elif dx > 0 and self.direction != +1: + self.set_anim(3) + self.direction = +1 + elif dx == 0 and self.direction is not None: + self.set_anim({-1: 2, +1: 4}[self.direction]) + self.direction = None + + self.state.x += dx + self.state.y += dy + + if self.state.invulnerable_time > 0: + self.state.invulnerable_time -= 1 + + m = self.state.invulnerable_time % 8 + if m == 0: + self._sprite.color = (255, 255, 255) + self._sprite._changed = True + elif m == 2: + self._sprite.color = (64, 64, 64) + self._sprite._changed = True - if dx < 0 and self.direction != -1: - self.set_anim(1) - self.direction = -1 - elif dx > 0 and self.direction != +1: - self.set_anim(3) - self.direction = +1 - elif dx == 0 and self.direction is not None: - self.set_anim({-1: 2, +1: 4}[self.direction]) - self.direction = None + if self.death_time: + time = self._game.frame - self.death_time + if time == 6: # too late, you are dead :( + self._game.drop_bonus(self.state.x, self.state.y, 2, end_pos=None) #TODO: find the formula + for i in range(5): + self._game.drop_bonus(self.state.x, self.state.y, 0, end_pos=None) #TODO: find the formula + self.state.lives -= 1 + + elif time == 7: + self.state.touchable = False + self._sprite.mirrored = False + self._sprite.fade(24, 128, lambda x: x) + self._sprite.blendfunc = 1 + self._sprite.scale_in(24, 0., 2., lambda x: x) + + elif time == 31: + self.state.x = 192.0 + self.state.y = 384.0 + self.direction = None - self.state.x += dx - self.state.y += dy + self._sprite = Sprite() + self._anmrunner = ANMRunner(self.anm_wrapper, 0, self._sprite) + self._sprite.alpha = 128 + self._sprite.rescale = 0., 2. + self._sprite.fade(30, 255, lambda x: x) + self._sprite.blendfunc = 1 + self._sprite.scale_in(30, 1., 1., lambda x: x) + self._anmrunner.run_frame() + + elif time == 60: # respawned + self.state.touchable = True + self.state.invulnerable_time = 240 + self._sprite.blendfunc = 0 + + if time > 30: + for bullet in self._game.bullets: + bullet.cancel() + + if time > 90: # start the bullet hell again + self.death_time = 0 + self._anmrunner.run_frame()