# HG changeset patch # User Emmanuel Gil Peyrot # Date 1318199563 25200 # Node ID 86807b8a63bdf88baeaa2f515b460cb72f4e6761 # Parent 5cf927cbd9c58fff9cdc0649322735df94379455 Add collisions with enemies and items. diff --git a/pytouhou/game/bullet.py b/pytouhou/game/bullet.py --- 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 diff --git a/pytouhou/game/enemy.py b/pytouhou/game/enemy.py --- 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)) diff --git a/pytouhou/game/game.py b/pytouhou/game/game.py --- 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() diff --git a/pytouhou/game/item.py b/pytouhou/game/item.py --- 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 diff --git a/pytouhou/game/player.py b/pytouhou/game/player.py --- 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), diff --git a/pytouhou/vm/eclrunner.py b/pytouhou/vm/eclrunner.py --- 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)