changeset 152:86807b8a63bd

Add collisions with enemies and items.
author Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
date Sun, 09 Oct 2011 15:32:43 -0700
parents 5cf927cbd9c5
children 37df8c618c2e
files pytouhou/game/bullet.py pytouhou/game/enemy.py pytouhou/game/game.py pytouhou/game/item.py pytouhou/game/player.py pytouhou/vm/eclrunner.py
diffstat 6 files changed, 52 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- a/pytouhou/game/bullet.py
+++ b/pytouhou/game/bullet.py
@@ -107,6 +107,12 @@ class Bullet(object):
                                                    (self.speed,), 16)
 
 
+    def collide(self, player):
+        #TODO: animation
+        self._removed = True
+        player.die()
+
+
     def update(self):
         dx, dy = self.launch_delta
         self.x += dx
--- a/pytouhou/game/enemy.py
+++ b/pytouhou/game/enemy.py
@@ -67,6 +67,7 @@ class Enemy(object):
         self.acceleration = 0.
 
         self.hitbox = (0, 0)
+        self.hitbox_half_size = (0, 0)
         self.screen_box = None
 
         self.pop_enemy = pop_enemy
@@ -144,6 +145,14 @@ class Enemy(object):
         self._anmrunner.run_frame()
 
 
+    def collide(self, player):
+        if self.touchable:
+            #TODO: animation
+            #TODO: doesn’t always kill herself (a boss for example), search how
+            self._removed = True
+            player.die()
+
+
     def set_pos(self, x, y, z):
         self.x, self.y = x, y
         self.interpolator = Interpolator((x, y))
--- a/pytouhou/game/game.py
+++ b/pytouhou/game/game.py
@@ -70,6 +70,8 @@ class Game(object):
 
         # 2. Filter out destroyed enemies
         self.enemies = [enemy for enemy in self.enemies if not enemy._removed]
+        self.bullets = [bullet for bullet in self.bullets if not bullet._removed]
+        self.items = [item for item in self.items if not item._removed]
 
         # 3. Let's play!
         #TODO: check update orders
@@ -100,6 +102,7 @@ class Game(object):
             phalf_size = player.hitbox_half_size
             px1, px2 = px - phalf_size, px + phalf_size
             py1, py2 = py - phalf_size, py + phalf_size
+
             for bullet in self.bullets:
                 half_size = bullet.hitbox_half_size
                 bx, by = bullet.x, bullet.y
@@ -108,10 +111,27 @@ class Game(object):
 
                 if not (bx2 < px1 or bx1 > px2
                         or by2 < py1 or by1 > py2):
-                    print('collided!') #TODO
+                    bullet.collide(player)
+
+            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: enemy-player collision
-        #TODO: item-player collision
+                if not (bx2 < px1 or bx1 > px2
+                        or by2 < py1 or by1 > py2):
+                    enemy.collide(player)
+
+            for item in self.items:
+                half_size = item.hitbox_half_size
+                bx, by = item.x, item.y
+                bx1, bx2 = bx - half_size, bx + half_size
+                by1, by2 = by - half_size, by + half_size
+
+                if not (bx2 < px1 or bx1 > px2
+                        or by2 < py1 or by1 > py2):
+                    item.collect(player)
 
         # 5. Cleaning
         self.cleanup()
--- a/pytouhou/game/item.py
+++ b/pytouhou/game/item.py
@@ -38,6 +38,11 @@ class Item(object):
         self._sprite.angle = angle
 
 
+    def collect(self, player):
+        player.state.score += self._item_type.score
+        self._removed = True
+
+
     def update(self):
         dx, dy = self.delta
 
--- a/pytouhou/game/player.py
+++ b/pytouhou/game/player.py
@@ -69,6 +69,14 @@ class Player(object):
         self._anmrunner.run_frame()
 
 
+    def die(self):
+        self.state.lives -= 1
+        self.state.x = 192.0
+        self.state.y = 384.0
+        #TODO: animation
+        #TODO: set invulnerability.
+
+
     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),
--- a/pytouhou/vm/eclrunner.py
+++ b/pytouhou/vm/eclrunner.py
@@ -699,6 +699,7 @@ class ECLRunner(object):
     @instruction(103)
     def set_hitbox(self, width, height, depth):
         self._enemy.hitbox = (width, height)
+        self._enemy.hitbox_half_size = (width / 2., height / 2.)
 
 
     @instruction(104)