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()