# HG changeset patch # User Emmanuel Gil Peyrot # Date 1319753382 25200 # Node ID dbe6b7b2d3fc4b4a04937247cb0e4da81a3818b1 # Parent ba3297ab3bdeb37e201065803cf4e72b3b4f84de Fix a few things about particles. diff --git a/pytouhou/game/effect.py b/pytouhou/game/effect.py --- a/pytouhou/game/effect.py +++ b/pytouhou/game/effect.py @@ -40,36 +40,53 @@ class Effect(object): class Particle(object): - def __init__(self, start_pos, index, anm_wrapper, size, end_pos): + def __init__(self, start_pos, index, anm_wrapper, size, amp, delay, game): self._sprite = Sprite() self._sprite.anm, self._sprite.texcoords = anm_wrapper.get_sprite(index) + self._game = game self._removed = False self.x, self.y = start_pos self.frame = 0 self._sprite.alpha = 128 self._sprite.blendfunc = 1 + self._sprite.rescale = (size, size) - self.pos_interpolator = Interpolator(start_pos, 0, + self.pos_interpolator = None + self.scale_interpolator = None + self.rotations_interpolator = None + + self.delay = delay + self.amp = amp + + + def set_end_pos(self, amp): + end_pos = (self.x + amp * self._game.prng.rand_double() - amp/2, + self.y + amp * self._game.prng.rand_double() - amp/2) + + self.pos_interpolator = Interpolator((self.x, self.y), 0, end_pos, 24, formula=(lambda x: 2. * x - x ** 2)) - self.scale_interpolator = Interpolator((size, size), 0, + self.scale_interpolator = Interpolator(self._sprite.rescale, 0, (0., 0.), 24) - self.rotations_interpolator = Interpolator((0., 0., 0.), 0, + self.rotations_interpolator = Interpolator(self._sprite.rotations_3d, 0, (0., 0., 2*pi), 24) - self._sprite._changed = True def update(self): - self.pos_interpolator.update(self.frame) - self.x, self.y = self.pos_interpolator.values + if (self.frame == 0 and not self.delay) or (self.frame == 1 and self.delay): + self.set_end_pos(self.amp) + + if self.pos_interpolator: + self.pos_interpolator.update(self.frame) + self.x, self.y = self.pos_interpolator.values - self.scale_interpolator.update(self.frame) - self._sprite.rescale = self.scale_interpolator.values + self.scale_interpolator.update(self.frame) + self._sprite.rescale = self.scale_interpolator.values - self.rotations_interpolator.update(self.frame) - self._sprite.rotations_3d = self.rotations_interpolator.values + self.rotations_interpolator.update(self.frame) + self._sprite.rotations_3d = self.rotations_interpolator.values - self._sprite._changed = True + self._sprite._changed = True if self.frame == 24: self._removed = True diff --git a/pytouhou/game/enemy.py b/pytouhou/game/enemy.py --- a/pytouhou/game/enemy.py +++ b/pytouhou/game/enemy.py @@ -169,7 +169,7 @@ class Enemy(object): def on_attack(self, bullet): if self.damageable: self.life -= bullet._bullet_type.damage - self._game.new_particle((self.x, self.y), 1, 3., 192) #TODO: find the real size and range. + self.drop_particles(1, 1) def on_collide(self): @@ -178,10 +178,16 @@ class Enemy(object): def die_anim(self): self._game.new_death((self.x, self.y), self.death_anim) - #TODO: 8 white particles are used only in stage 3 to 6, - # in other stages they are 2 red and 6 blue. - for i in range(8): - self._game.new_particle((self.x, self.y), 0, 3., 192) #TODO: find the real size and range. + + + def drop_particles(self, number, color): + #TODO: white particles are only used in stage 3 to 6, + # in other stages they are blue. + if color == 0: + if self._game.stage in [1, 2, 7]: + color = 3 + for i in range(number): + self._game.new_particle((self.x, self.y), color, 4., 256, delay=False) #TODO: find the real size. def set_pos(self, x, y, z): diff --git a/pytouhou/game/game.py b/pytouhou/game/game.py --- a/pytouhou/game/game.py +++ b/pytouhou/game/game.py @@ -84,10 +84,8 @@ class Game(object): self.effects.append(Effect(pos, anim, self.etama4)) - def new_particle(self, pos, color, size, amp): - self.effects.append(Particle(pos, 7 + 4 * color + self.prng.rand_uint16() % 4, self.etama4, size, - (pos[0] + amp * self.prng.rand_double() - amp/2, - pos[1] + amp * self.prng.rand_double() - amp/2))) + def new_particle(self, pos, color, size, amp, delay=False): + self.effects.append(Particle(pos, 7 + 4 * color + self.prng.rand_uint16() % 4, self.etama4, size, amp, delay, self)) def new_enemy(self, pos, life, instr_type, bonus_dropped, die_score): @@ -170,7 +168,7 @@ class Game(object): bullet.grazed = True player.state.graze += 1 player.state.score += 500 # found experimentally - self.new_particle((px, py), 0, .8, 192) #TODO: find the real size and range. + self.new_particle((px, py), 0, .8, 192, delay=True) #TODO: find the real size and range. #TODO: display a static particle during one frame at # 12 pixels of the player, in the axis of the “collision”. diff --git a/pytouhou/game/player.py b/pytouhou/game/player.py --- a/pytouhou/game/player.py +++ b/pytouhou/game/player.py @@ -78,6 +78,8 @@ class Player(object): if not self.state.invulnerable_time and not self.death_time and self.state.touchable: # Border Between Life and Death self.death_time = self._game.frame self._game.new_death((self.state.x, self.state.y), 2) + for i in range(16): + self._game.new_particle((self.state.x, self.state.y), 2, 4., 256, delay=True) #TODO: find the real size and range. def collect(self, item): @@ -141,9 +143,6 @@ class Player(object): end_pos=(self._game.prng.rand_double() * 288 + 48, self._game.prng.rand_double() * 192 - 64)) - for i in range(16): - self._game.new_particle((self.state.x, self.state.y), 0, 4., 256) #TODO: find the real size and range. - elif time == 7: self._sprite.mirrored = False self._sprite.fade(24, 128, lambda x: x) diff --git a/pytouhou/vm/eclrunner.py b/pytouhou/vm/eclrunner.py --- a/pytouhou/vm/eclrunner.py +++ b/pytouhou/vm/eclrunner.py @@ -129,9 +129,13 @@ class ECLRunner(object): if death_flags < 4: if enm._bonus_dropped >= 0: + enm.drop_particles(7, 0) self._game.drop_bonus(enm.x, enm.y, enm._bonus_dropped) elif enm._bonus_dropped == -1: + enm.drop_particles(10, 0) self._game.drop_bonus(enm.x, enm.y, self._game.prng.rand_uint16() % 2) #TODO: find the formula in the binary. Can be big power sometimes. + else: + enm.drop_particles(4, 0) if death_flags == 0: enm._removed = True