changeset 202:d348892ef012

Handle enemy collisions and damages in a way closer to the original game.
author Thibaut Girka <thib@sitedethib.com>
date Mon, 31 Oct 2011 19:01:09 +0100
parents 220c122f428c
children df8b2ab54639
files pytouhou/game/enemy.py pytouhou/game/game.py
diffstat 2 files changed, 60 insertions(+), 58 deletions(-) [+]
line wrap: on
line diff
--- a/pytouhou/game/enemy.py
+++ b/pytouhou/game/enemy.py
@@ -165,16 +165,6 @@ class Enemy(object):
         self._anmrunner.run_frame()
 
 
-    def on_attack(self, bullet):
-        if self.damageable:
-            self.life -= bullet._bullet_type.damage
-            self.drop_particles(1, 1)
-
-
-    def on_collide(self):
-        self.life -= 80 # found experimentally
-
-
     def die_anim(self):
         self._game.new_death((self.x, self.y), self.death_anim)
 
@@ -236,6 +226,62 @@ class Enemy(object):
         return True
 
 
+    def check_collisions(self):
+        # Check for collisions
+        ex, ey = self.x, self.y
+        ehalf_size_x, ehalf_size_y = self.hitbox_half_size
+        ex1, ex2 = ex - ehalf_size_x, ex + ehalf_size_x
+        ey1, ey2 = ey - ehalf_size_y, ey + ehalf_size_y
+
+        damages = 0
+
+        # Check for enemy-bullet collisions
+        for bullet in self._game.players_bullets:
+            half_size = bullet.hitbox_half_size
+            bx, by = bullet.x, bullet.y
+            bx1, bx2 = bx - half_size, bx + half_size
+            by1, by2 = by - half_size, by + half_size
+
+            if not (bx2 < ex1 or bx1 > ex2
+                    or by2 < ey1 or by1 > ey2):
+                bullet.collide()
+                damages += bullet._bullet_type.damage
+                self.drop_particles(1, 1)
+
+        # Check for enemy-player collisions
+        if self.touchable:
+            for player in self._game.players:
+                if not player.state.touchable:
+                    continue
+
+                px, py = player.x, player.y
+                phalf_size = player.hitbox_half_size
+                px1, px2 = px - phalf_size, px + phalf_size
+                py1, py2 = py - phalf_size, py + phalf_size
+
+                #TODO: box-box or point-in-box?
+                if not (ex2 < px1 or ex1 > px2 or ey2 < py1 or ey1 > py2):
+                    if not self.boss:
+                        damages += 10
+                    if player.state.invulnerable_time == 0: #TODO
+                        player.collide()
+
+        # Adjust damages
+        damages = min(70, damages)
+        score = (damages // 5) * 10 #TODO: give to which player?
+
+        if self._game.spellcard:
+            #TODO: there is a division by 3, somewhere... where is it?
+            if damages <= 7:
+                damages = 1 if damages else 0
+            else:
+                damages //= 7
+
+        # Apply damages
+        if self.damageable:
+            self.life -= damages
+
+
     def update(self):
         x, y = self.x, self.y
         if self.interpolator:
@@ -299,5 +345,9 @@ class Enemy(object):
             if self.bullet_launch_timer == self.bullet_launch_interval:
                 self.fire()
 
+        # Check collisions
+        if self.touchable:
+            self.check_collisions()
+
         self.frame += 1
 
--- a/pytouhou/game/game.py
+++ b/pytouhou/game/game.py
@@ -145,26 +145,6 @@ class Game(object):
         for enemy in self.enemies:
             enemy.update()
 
-        # Check for collisions
-        for enemy in self.enemies:
-            ex, ey = enemy.x, enemy.y
-            ehalf_size_x, ehalf_size_y = enemy.hitbox_half_size
-            ex1, ex2 = ex - ehalf_size_x, ex + ehalf_size_x
-            ey1, ey2 = ey - ehalf_size_y, ey + ehalf_size_y
-
-            for bullet in self.players_bullets:
-                half_size = bullet.hitbox_half_size
-                bx, by = bullet.x, bullet.y
-                bx1, bx2 = bx - half_size, bx + half_size
-                by1, by2 = by - half_size, by + half_size
-
-                if not (bx2 < ex1 or bx1 > ex2
-                        or by2 < ey1 or by1 > ey2):
-                    bullet.collide()
-                    enemy.on_attack(bullet)
-                    #TODO: place that at the right place.
-                    #player.state.score += 90 # found experimentally
-
 
     def update_players(self, keystate):
         for player in self.players:
@@ -181,34 +161,6 @@ class Game(object):
         for bullet in self.players_bullets:
             bullet.update()
 
-        # Check for collisions
-        for player in self.players:
-            if not player.state.touchable:
-                continue
-
-            px, py = player.x, player.y
-            phalf_size = player.hitbox_half_size
-            px1, px2 = px - phalf_size, px + phalf_size
-            py1, py2 = py - phalf_size, py + phalf_size
-
-            ghalf_size = player.graze_hitbox_half_size
-            gx1, gx2 = px - ghalf_size, px + ghalf_size
-            gy1, gy2 = py - ghalf_size, py + ghalf_size
-
-            #TODO: Should that be done here or in update_enemies?
-            for enemy in self.enemies:
-                half_size_x, half_size_y = enemy.hitbox_half_size
-                bx, by = enemy.x, enemy.y
-                bx1, bx2 = bx - half_size_x, bx + half_size_x
-                by1, by2 = by - half_size_y, by + half_size_y
-
-                #TODO: box-box or point-in-box?
-                if enemy.touchable and not (bx2 < px1 or bx1 > px2
-                                            or by2 < py1 or by1 > py2):
-                    enemy.on_collide()
-                    if player.state.invulnerable_time == 0:
-                        player.collide()
-
 
     def update_effects(self):
         for effect in self.effects: