Mercurial > touhou
diff pytouhou/game/enemymanager.py @ 49:cbe1cb50f2fd
Refactor ECLRunner/EnemyManager so that all VM stuff goes to ECLRunner
author | Thibaut Girka <thib@sitedethib.com> |
---|---|
date | Mon, 22 Aug 2011 19:23:00 +0200 |
parents | 8353c33d53d4 |
children | 811cefefb5c8 |
line wrap: on
line diff
--- a/pytouhou/game/enemymanager.py +++ b/pytouhou/game/enemymanager.py @@ -13,16 +13,18 @@ random = Random(0x39f4) class Enemy(object): - def __init__(self, pos, life, _type, ecl_runner, anm_wrapper): - self.anm_wrapper = anm_wrapper - self.anm = None - self.ecl_runner = ecl_runner + def __init__(self, pos, life, _type, anm_wrapper): + self._anm_wrapper = anm_wrapper + self._anm = None + self._sprite = None + self._removed = False + self._type = _type + + self.frame = 0 + self.x, self.y = pos self.life = life self.max_life = life - self.type = _type - self.frame = 0 - self.sprite = None self.pending_bullets = [] self.bullet_attributes = None self.bullet_launch_offset = (0, 0) @@ -36,7 +38,7 @@ class Enemy(object): self.bullet_launch_interval = 0 self.delay_attack = False - self.death_sprite = None + self.death_anim = None self.movement_dependant_sprites = None self.direction = None self.interpolator = None #TODO @@ -47,57 +49,6 @@ class Enemy(object): self.hitbox = (0, 0) - self.ecl_runner.implementation.update({67: self.set_bullet_attributes, - 97: self.set_sprite, - 98: self.set_multiple_sprites, - 45: self.set_angle_speed, - 43: self.set_pos, - 46: self.set_rotation_speed, - 47: self.set_speed, - 48: self.set_acceleration, - 51: self.target_player, - 57: self.move_to, - 77: self.set_bullet_interval, - 78: self.set_delay_attack, - 79: self.set_no_delay_attack, - 81: self.set_bullet_launch_offset, - 100: self.set_death_sprite, - 103: self.set_hitbox, - 105: self.set_vulnerable, - 108: self.set_death_callback, - 113: self.set_low_life_trigger, - 114: self.set_low_life_callback, - 115: self.set_timeout, - 126: self.set_remaining_lives}) #TODO - - - def set_remaining_lives(self, lives): - self.remaining_lives = lives - - - def set_death_callback(self, sub): - self.death_callback = sub - - - def set_low_life_trigger(self, value): - self.low_life_trigger = value - - - def set_low_life_callback(self, sub): - self.low_life_callback = sub - - - def set_timeout(self, timeout): - self.timeout = timeout - - - def set_vulnerable(self, vulnerable): - self.vulnerable = bool(vulnerable & 1) - - - def set_bullet_launch_offset(self, x, y, z): - self.bullet_launch_offset = (x, y) - def set_bullet_attributes(self, bullet_anim, launch_anim, bullets_per_shot, number_of_shots, speed, unknown, launch_angle, @@ -110,37 +61,8 @@ class Enemy(object): #TODO: actually fire - def set_bullet_interval(self, value): - self.bullet_launch_interval = value - - - def set_delay_attack(self): - self.delay_attack = True - - - def set_no_delay_attack(self): - self.delay_attack = False - - - def set_death_sprite(self, sprite_index): - self.death_sprite = sprite_index % 256 #TODO - - - def set_hitbox(self, width, height, depth): - self.hitbox = (width, height) - - - def set_sprite(self, sprite_index): - self.anm, self.sprite = self.anm_wrapper.get_sprite(sprite_index) - - - def set_multiple_sprites(self, default, end_left, end_right, left, right): - self.movement_dependant_sprites = end_left, end_right, left, right - self.anm, self.sprite = self.anm_wrapper.get_sprite(default) - - - def set_angle_speed(self, angle, speed): - self.angle, self.speed = angle, speed + def set_anim(self, index): + self._anm, self._sprite = self._anm_wrapper.get_sprite(index) def set_pos(self, x, y, z): @@ -149,34 +71,16 @@ class Enemy(object): self.interpolator.set_interpolation_start(self.frame, (x, y)) - def set_rotation_speed(self, speed): - self.rotation_speed = speed - - - def set_speed(self, speed): - self.speed = speed - - - def set_acceleration(self, acceleration): - self.acceleration = acceleration - - - def target_player(self, unknown, speed): - self.speed = speed #TODO: unknown - player_x, player_y = 192., 384.#TODO - self.angle = atan2(player_y - self.y, player_x - self.x) - - def move_to(self, duration, x, y, z): self.interpolator.set_interpolation_end(self.frame + duration, (x, y)) def is_visible(self, screen_width, screen_height): - if not self.sprite: + if not self._sprite: return False - tx, ty, tw, th = self.sprite.texcoords - if self.sprite.corner_relative_placement: + tx, ty, tw, th = self._sprite.texcoords + if self._sprite.corner_relative_placement: raise Exception #TODO else: max_x = tw / 2. @@ -194,20 +98,18 @@ class Enemy(object): def get_objects_by_texture(self): objects_by_texture = {} - key = self.anm.first_name, self.anm.secondary_name + key = self._anm.first_name, self._anm.secondary_name if not key in objects_by_texture: objects_by_texture[key] = (0, [], [], []) - vertices = tuple((x + self.x, y + self.y, z) for x, y, z in self.sprite._vertices) + vertices = tuple((x + self.x, y + self.y, z) for x, y, z in self._sprite._vertices) objects_by_texture[key][1].extend(vertices) - objects_by_texture[key][2].extend(self.sprite._uvs) - objects_by_texture[key][3].extend(self.sprite._colors) + objects_by_texture[key][2].extend(self._sprite._uvs) + objects_by_texture[key][3].extend(self._sprite._colors) #TODO: effects/bullet launch return objects_by_texture def update(self, frame): - self.ecl_runner.update() - x, y = self.x, self.y if self.interpolator: self.interpolator.update(self.frame) @@ -217,7 +119,7 @@ class Enemy(object): self.angle += self.rotation_speed #TODO: units? Execution order? dx, dy = cos(self.angle) * self.speed, sin(self.angle) * self.speed - if self.type & 2: + if self._type & 2: x -= dx else: x += dx @@ -226,24 +128,24 @@ class Enemy(object): if self.movement_dependant_sprites: #TODO: is that really how it works? if x < self.x: - self.anm, self.sprite = self.anm_wrapper.get_sprite(self.movement_dependant_sprites[2]) + self.set_anim(self.movement_dependant_sprites[2]) self.direction = -1 elif x > self.x: - self.anm, self.sprite = self.anm_wrapper.get_sprite(self.movement_dependant_sprites[3]) + self.set_anim(self.movement_dependant_sprites[3]) self.direction = +1 elif self.direction is not None: - self.anm, self.sprite = self.anm_wrapper.get_sprite(self.movement_dependant_sprites[{-1: 0, +1:1}[self.direction]]) + self.set_anim(self.movement_dependant_sprites[{-1: 0, +1:1}[self.direction]]) self.direction = None self.x, self.y = x, y - if self.sprite: - changed = self.sprite.update() + if self._sprite: + changed = self._sprite.update() visible = self.is_visible(384, 448) if changed and visible: - self.sprite.update_vertices_uvs_colors() - elif not self.sprite.playing: + self._sprite.update_vertices_uvs_colors() + elif not self._sprite.playing: visible = False - self.sprite = None + self._sprite = None else: visible = False @@ -254,13 +156,15 @@ class Enemy(object): class EnemyManager(object): - def __init__(self, stage, anm_wrapper, ecl): + def __init__(self, stage, anm_wrapper, ecl, game_state): + self._game_state = game_state self.stage = stage self.anm_wrapper = anm_wrapper self.main = [] self.ecl = ecl self.objects_by_texture = {} self.enemies = [] + self.processes = [] # Populate main for frame, sub, instr_type, args in ecl.main: @@ -270,12 +174,6 @@ class EnemyManager(object): self.main[-1][1].append((sub, instr_type, args)) - def make_enemy_deleter(self, enemy): - def _enemy_deleter(unknown): #TODO: unknown - self.enemies.remove(enemy) - return _enemy_deleter - - def update(self, frame): if self.main and self.main[0][0] == frame: for sub, instr_type, args in self.main.pop(0)[1]: @@ -288,11 +186,16 @@ class EnemyManager(object): y = random.rand_double() * 416 #102h.exe@0x41184b if z < -990: y = random.rand_double() * 800 #102h.exe@0x411881 - ecl_runner = ECLRunner(self.ecl, sub) - enemy = Enemy((x, y), life, instr_type, ecl_runner, self.anm_wrapper) - ecl_runner.implementation[1] = self.make_enemy_deleter(enemy) + enemy = Enemy((x, y), life, instr_type, self.anm_wrapper) + self.enemies.append(enemy) + self.processes.append(ECLRunner(self.ecl, sub, enemy, self._game_state)) + - self.enemies.append(enemy) + # Run processes + self.processes[:] = (process for process in self.processes if process.run_iteration()) + + # Filter of destroyed enemies + self.enemies[:] = (enemy for enemy in self.enemies if not enemy._removed) # Update enemies visible_enemies = [enemy for enemy in self.enemies if enemy.update(frame)]