Mercurial > touhou
comparison pytouhou/game/enemy.py @ 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 | e1bc8c4cbb1a |
children | 709f42eaa55e |
comparison
equal
deleted
inserted
replaced
201:220c122f428c | 202:d348892ef012 |
---|---|
163 self._sprite = Sprite() | 163 self._sprite = Sprite() |
164 self._anmrunner = ANMRunner(self._anm_wrapper, index, self._sprite) | 164 self._anmrunner = ANMRunner(self._anm_wrapper, index, self._sprite) |
165 self._anmrunner.run_frame() | 165 self._anmrunner.run_frame() |
166 | 166 |
167 | 167 |
168 def on_attack(self, bullet): | |
169 if self.damageable: | |
170 self.life -= bullet._bullet_type.damage | |
171 self.drop_particles(1, 1) | |
172 | |
173 | |
174 def on_collide(self): | |
175 self.life -= 80 # found experimentally | |
176 | |
177 | |
178 def die_anim(self): | 168 def die_anim(self): |
179 self._game.new_death((self.x, self.y), self.death_anim) | 169 self._game.new_death((self.x, self.y), self.death_anim) |
180 | 170 |
181 | 171 |
182 def drop_particles(self, number, color): | 172 def drop_particles(self, number, color): |
232 or max_x < -x | 222 or max_x < -x |
233 or max_y < y - screen_height | 223 or max_y < y - screen_height |
234 or max_y < -y): | 224 or max_y < -y): |
235 return False | 225 return False |
236 return True | 226 return True |
227 | |
228 | |
229 def check_collisions(self): | |
230 # Check for collisions | |
231 ex, ey = self.x, self.y | |
232 ehalf_size_x, ehalf_size_y = self.hitbox_half_size | |
233 ex1, ex2 = ex - ehalf_size_x, ex + ehalf_size_x | |
234 ey1, ey2 = ey - ehalf_size_y, ey + ehalf_size_y | |
235 | |
236 damages = 0 | |
237 | |
238 # Check for enemy-bullet collisions | |
239 for bullet in self._game.players_bullets: | |
240 half_size = bullet.hitbox_half_size | |
241 bx, by = bullet.x, bullet.y | |
242 bx1, bx2 = bx - half_size, bx + half_size | |
243 by1, by2 = by - half_size, by + half_size | |
244 | |
245 if not (bx2 < ex1 or bx1 > ex2 | |
246 or by2 < ey1 or by1 > ey2): | |
247 bullet.collide() | |
248 damages += bullet._bullet_type.damage | |
249 self.drop_particles(1, 1) | |
250 | |
251 # Check for enemy-player collisions | |
252 if self.touchable: | |
253 for player in self._game.players: | |
254 if not player.state.touchable: | |
255 continue | |
256 | |
257 px, py = player.x, player.y | |
258 phalf_size = player.hitbox_half_size | |
259 px1, px2 = px - phalf_size, px + phalf_size | |
260 py1, py2 = py - phalf_size, py + phalf_size | |
261 | |
262 #TODO: box-box or point-in-box? | |
263 if not (ex2 < px1 or ex1 > px2 or ey2 < py1 or ey1 > py2): | |
264 if not self.boss: | |
265 damages += 10 | |
266 if player.state.invulnerable_time == 0: #TODO | |
267 player.collide() | |
268 | |
269 # Adjust damages | |
270 damages = min(70, damages) | |
271 score = (damages // 5) * 10 #TODO: give to which player? | |
272 | |
273 if self._game.spellcard: | |
274 #TODO: there is a division by 3, somewhere... where is it? | |
275 if damages <= 7: | |
276 damages = 1 if damages else 0 | |
277 else: | |
278 damages //= 7 | |
279 | |
280 # Apply damages | |
281 if self.damageable: | |
282 self.life -= damages | |
237 | 283 |
238 | 284 |
239 def update(self): | 285 def update(self): |
240 x, y = self.x, self.y | 286 x, y = self.x, self.y |
241 if self.interpolator: | 287 if self.interpolator: |
297 if self.bullet_launch_interval != 0: | 343 if self.bullet_launch_interval != 0: |
298 self.bullet_launch_timer += 1 | 344 self.bullet_launch_timer += 1 |
299 if self.bullet_launch_timer == self.bullet_launch_interval: | 345 if self.bullet_launch_timer == self.bullet_launch_interval: |
300 self.fire() | 346 self.fire() |
301 | 347 |
348 # Check collisions | |
349 if self.touchable: | |
350 self.check_collisions() | |
351 | |
302 self.frame += 1 | 352 self.frame += 1 |
303 | 353 |