# HG changeset patch # User Thibaut Girka # Date 1341135818 -7200 # Node ID 2350147cf0433cc5714f66416952dbdb90f49942 # Parent 4eca6130f118573ec0eb7823d7b82ec29a263d6f Fix bullet cancellation and removal diff --git a/pytouhou/game/bullet.pyx b/pytouhou/game/bullet.pyx --- a/pytouhou/game/bullet.pyx +++ b/pytouhou/game/bullet.pyx @@ -22,7 +22,7 @@ from pytouhou.game.sprite import Sprite LAUNCHING, LAUNCHED, CANCELLED = range(3) cdef class Bullet(object): - cdef public unsigned int _state, flags, frame, sprite_idx_offset + cdef public unsigned int state, flags, frame, sprite_idx_offset cdef public double dx, dy, angle, speed #TODO cdef public object player_bullet, target cdef public object _game, _bullet_type @@ -35,7 +35,7 @@ cdef class Bullet(object): player_bullet=False, damage=0, hitbox=None): self._game = game self._bullet_type = bullet_type - self._state = LAUNCHING + self.state = LAUNCHING self.sprite = None self.anmrunner = None self.removed = False @@ -122,7 +122,7 @@ cdef class Bullet(object): def launch(Bullet self): - self._state = LAUNCHED + self.state = LAUNCHED self.frame = 0 self.set_anim() self.dx, self.dy = cos(self.angle) * self.speed, sin(self.angle) * self.speed @@ -151,7 +151,7 @@ cdef class Bullet(object): self.dx, self.dy = self.dx / 2., self.dy / 2. # Change update method - self._state = CANCELLED + self.state = CANCELLED # Do not use this one for collisions anymore if self.player_bullet: @@ -163,17 +163,17 @@ cdef class Bullet(object): def update(Bullet self): if self.anmrunner is not None and not self.anmrunner.run_frame(): - if self._state == LAUNCHING: + if self.state == LAUNCHING: #TODO: check if it doesn't skip a frame self.launch() - elif self._state == CANCELLED: + elif self.state == CANCELLED: self.removed = True else: self.anmrunner = None - if self._state == LAUNCHING: + if self.state == LAUNCHING: pass - elif self._state == CANCELLED: + elif self.state == CANCELLED: pass elif self.flags & 1: # Initial speed burst diff --git a/pytouhou/game/enemy.py b/pytouhou/game/enemy.py --- a/pytouhou/game/enemy.py +++ b/pytouhou/game/enemy.py @@ -20,6 +20,7 @@ from pytouhou.game.bullet import Bullet from pytouhou.game.laser import Laser from pytouhou.game.effect import Effect from math import cos, sin, atan2, pi +from pytouhou.game.bullet import LAUNCHED class Enemy(object): @@ -280,6 +281,8 @@ class Enemy(object): # Check for enemy-bullet collisions for bullet in self._game.players_bullets: + if bullet.state != LAUNCHED: + continue half_size = bullet.hitbox_half_size bx, by = bullet.x, bullet.y bx1, bx2 = bx - half_size[0], bx + half_size[0] diff --git a/pytouhou/game/game.py b/pytouhou/game/game.py --- a/pytouhou/game/game.py +++ b/pytouhou/game/game.py @@ -12,11 +12,14 @@ ## GNU General Public License for more details. ## +from itertools import chain + from pytouhou.utils.random import Random from pytouhou.vm.eclrunner import ECLMainRunner from pytouhou.vm.msgrunner import MSGRunner +from pytouhou.game.bullet import LAUNCHED, CANCELLED from pytouhou.game.enemy import Enemy from pytouhou.game.item import Item from pytouhou.game.effect import Effect @@ -142,6 +145,13 @@ class Game(object): item.autocollect(player) + def cancel_bullets(self): + for bullet in self.bullets: + bullet.cancel() + for laser in self.lasers: + laser.cancel() + + def change_bullets_into_star_items(self): player = self.players[0] #TODO item_type = self.item_types[6] @@ -325,6 +335,9 @@ class Game(object): self.new_particle((px, py), 0, .8, 192) #TODO for bullet in self.bullets: + if bullet.state != LAUNCHED: + continue + half_size = bullet.hitbox_half_size bx, by = bullet.x, bullet.y bx1, bx2 = bx - half_size[0], bx + half_size[0] @@ -372,16 +385,19 @@ class Game(object): self.enemies = [enemy for enemy in self.enemies if not enemy.removed] + # Update cancelled bullets + self.cancelled_bullets = [b for b in chain(self.cancelled_bullets, + self.bullets, + self.players_bullets) + if b.state == CANCELLED and not b.removed] # Filter out-of-scren bullets self.bullets = [bullet for bullet in self.bullets - if not bullet.removed] + if not bullet.removed and bullet.state != CANCELLED] self.players_bullets = [bullet for bullet in self.players_bullets - if not bullet.removed] + if not bullet.removed and bullet.state != CANCELLED] for i, laser in enumerate(self.players_lasers): if laser and laser.removed: self.players_lasers[i] = None - self.cancelled_bullets = [bullet for bullet in self.cancelled_bullets - if not bullet.removed] self.effects = [effect for effect in self.effects if not effect.removed] # Filter “timed-out” lasers diff --git a/pytouhou/game/player.py b/pytouhou/game/player.py --- a/pytouhou/game/player.py +++ b/pytouhou/game/player.py @@ -256,10 +256,7 @@ class Player(object): self.sprite.changed = True if time > 30: - for bullet in self._game.bullets: - bullet.cancel() - for laser in self._game.lasers: - laser.cancel() + self._game.cancel_bullets() if time > 90: # start the bullet hell again self.death_time = 0