# HG changeset patch # User Thibaut Girka # Date 1320084069 -3600 # Node ID d348892ef0125ffa512110fc15352beccc74e088 # Parent 220c122f428ce065c86fb88760d217bfb3df0efd Handle enemy collisions and damages in a way closer to the original game. diff --git a/pytouhou/game/enemy.py b/pytouhou/game/enemy.py --- 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 diff --git a/pytouhou/game/game.py b/pytouhou/game/game.py --- 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: