Mercurial > touhou
diff pytouhou/game/bullet.py @ 122:174324a4da51
Add support for launch animations! (Warning: slow :()
author | Thibaut Girka <thib@sitedethib.com> |
---|---|
date | Sat, 10 Sep 2011 01:26:30 +0200 |
parents | 4300a832f033 |
children | d1c82d43bbf3 |
line wrap: on
line diff
--- a/pytouhou/game/bullet.py +++ b/pytouhou/game/bullet.py @@ -20,19 +20,14 @@ from pytouhou.game.sprite import Sprite class Bullet(object): - __slots__ = ('x', 'y', 'angle', 'speed', 'frame', 'grazed', - 'flags', 'attributes', 'anim_idx', 'sprite_idx_offset', 'player', - 'speed_interpolator', - '_game_state', '_sprite', '_anmrunner', - '_removed', '_launched') - - def __init__(self, pos, anim_idx, sprite_idx_offset, + def __init__(self, pos, type_idx, sprite_idx_offset, angle, speed, attributes, flags, player, game_state): self._game_state = game_state self._sprite = None self._anmrunner = None self._removed = False self._launched = False + self._bullet_type = game_state.bullet_types[type_idx] self.speed_interpolator = None self.frame = 0 @@ -40,101 +35,111 @@ class Bullet(object): self.player = player - self.anim_idx = anim_idx self.sprite_idx_offset = sprite_idx_offset - #TODO - #if flags & (2|4|8): - # if flags & 2: #TODO: Huh?! - # index = 14 - # elif flags & 4: - # index = 15 - # else: - # index = 19 - # self._sprite = Sprite() - # self._anmrunner = ANMRunner(self._game_state.resource_loader.get_anm_wrapper(('etama3.anm',)), #TODO - # index, self._sprite, 0) #TODO: offset - # self._anmrunner.run_frame() - self.flags = flags self.attributes = list(attributes) self.x, self.y = pos self.angle = angle self.speed = speed + dx, dy = cos(angle) * speed, sin(angle) * speed + self.delta = dx, dy - if flags & 1: - self.speed_interpolator = Interpolator((speed + 5.,)) - self.speed_interpolator.set_interpolation_start(0, (speed + 5.,)) - self.speed_interpolator.set_interpolation_end(16, (speed,)) - if flags & 448: - self.speed_interpolator = Interpolator((speed,)) - self.speed_interpolator.set_interpolation_start(0, (speed,)) - self.speed_interpolator.set_interpolation_end(attributes[0] - 1, (0,)) # TODO: really -1? Without, the new speed isn’t set. + #TODO + if flags & 14: + bt = self._bullet_type + if flags & 2: + index = bt.launch_anim2_index + launch_mult = bt.launch_anim_penalties[0] + elif flags & 4: + index = bt.launch_anim4_index + launch_mult = bt.launch_anim_penalties[1] + else: + index = bt.launch_anim8_index + launch_mult = bt.launch_anim_penalties[2] + self.launch_delta = dx * launch_mult, dy * launch_mult + self._sprite = Sprite() + self._anmrunner = ANMRunner(bt.anm_wrapper, + index, self._sprite, + bt.launch_anim_offsets[sprite_idx_offset]) + self._anmrunner.run_frame() + else: + self.launch() - - def get_player_angle(self): - return atan2(self.player.y - self.y, self.player.x - self.x) + self._sprite.angle = angle def is_visible(self, screen_width, screen_height): - if self._sprite: - tx, ty, tw, th = self._sprite.texcoords - if self._sprite.corner_relative_placement: - raise Exception #TODO - else: - tx, ty, tw, th = 0., 0., 0., 0. + tx, ty, tw, th = self._sprite.texcoords + if self._sprite.corner_relative_placement: + raise Exception #TODO max_x = tw / 2. max_y = th / 2. - min_x = -max_x - min_y = -max_y - if any((min_x > screen_width - self.x, + if any((max_x < self.x - screen_width, max_x < -self.x, - min_y > screen_height - self.y, + max_y < self.y - screen_height, max_y < -self.y)): return False return True - def set_anim(self, anim_idx=None, sprite_idx_offset=None): - if anim_idx is not None: - self.anim_idx = anim_idx - + def set_anim(self, sprite_idx_offset=None): if sprite_idx_offset is not None: self.sprite_idx_offset = sprite_idx_offset + bt = self._bullet_type self._sprite = Sprite() - anm_wrapper = self._game_state.resource_loader.get_anm_wrapper(('etama3.anm',)) #TODO - self._anmrunner = ANMRunner(anm_wrapper, self.anim_idx, + self._sprite.angle = self.angle + self._anmrunner = ANMRunner(bt.anm_wrapper, bt.anim_index, self._sprite, self.sprite_idx_offset) + self._anmrunner.run_frame() + + + def launch(self): + self._launched = True + self.update = self.update_full + self.set_anim() + if self.flags & 1: + self.speed_interpolator = Interpolator((self.speed + 5.,), 0, + (self.speed,), 16) def update(self): - if not self._sprite or self._sprite._removed: - self._launched = True - self.set_anim() + dx, dy = self.launch_delta + self.x += dx + self.y += dy + + self.frame += 1 + + if not self._anmrunner.run_frame(): + self.launch() + + def update_simple(self): + dx, dy = self.delta + self.x += dx + self.y += dy + + + def update_full(self): sprite = self._sprite if self._anmrunner is not None and not self._anmrunner.run_frame(): self._anmrunner = None - if sprite.automatic_orientation and sprite.angle != self.angle: - sprite.angle = self.angle - sprite._changed = True #TODO: flags x, y = self.x, self.y + dx, dy = self.delta if self.flags & 16: frame, count = self.attributes[0:2] length, angle = self.attributes[4:6] angle = self.angle if angle < -900.0 else angle #TODO: is that right? - dx = cos(self.angle) * self.speed + cos(angle) * length - dy = sin(self.angle) * self.speed + sin(angle) * length - self.speed = (dx ** 2 + dy ** 2) ** 0.5 - self.angle = atan2(dy, dx) + dx, dy = dx + cos(angle) * length, dy + sin(angle) * length + self.delta = dx, dy if self.frame == frame: #TODO: include last frame, or not? if count > 0: self.attributes[1] -= 1 @@ -147,7 +152,12 @@ class Bullet(object): acceleration, angular_speed = self.attributes[4:6] self.speed += acceleration self.angle += angular_speed - if self.frame != 0 and self.frame % frame == 0: + dx, dy = cos(self.angle) * self.speed, sin(self.angle) * self.speed + self.delta = dx, dy + sprite.angle = self.angle + if sprite.automatic_orientation: + sprite._changed = True + if self.frame % frame == 0: if count > 0: self.attributes[1] -= 1 else: @@ -156,31 +166,38 @@ class Bullet(object): #TODO: check frame, count = self.attributes[0:2] angle, speed = self.attributes[4:6] - if self.frame != 0 and self.frame % frame == 0: + if self.frame % frame == 0: count = count - 1 if self.flags & 64: - self.angle = self.angle + angle + self.angle += angle elif self.flags & 128: - self.angle = self.get_player_angle() + angle + self.angle = atan2(self.player.y - y, self.player.x - x) + angle elif self.flags & 256: self.angle = angle - if count: - self.speed_interpolator.set_interpolation_start(self.frame, (speed,)) - self.speed_interpolator.set_interpolation_end(self.frame + frame - 1, (0,)) # TODO: really -1? Without, the new speed isn’t set. + dx, dy = cos(self.angle) * speed, sin(self.angle) * speed + self.delta = dx, dy + sprite.angle = self.angle + if sprite.automatic_orientation: + sprite._changed = True + + if count > 0: + self.speed_interpolator = Interpolator((speed,), self.frame, + (0.,), self.frame + frame - 1) else: self.flags &= ~448 self.speed = speed self.attributes[1] = count #TODO: other flags + elif not self.speed_interpolator and self._anmrunner is None: + self.update = self.update_simple if self.speed_interpolator: self.speed_interpolator.update(self.frame) self.speed, = self.speed_interpolator.values - dx, dy = cos(self.angle) * self.speed, sin(self.angle) * self.speed self.x, self.y = x + dx, y + dy self.frame += 1