# HG changeset patch # User Thibaut Girka # Date 1313059152 -7200 # Node ID bf225780973faf2f25685234b4bd26259fc80917 # Parent 6ebf9539c0774e46cbe92b7d76018e1d2acca2f7 Small refactoring, and Rumia \o/ diff --git a/eclviewer.py b/eclviewer.py --- a/eclviewer.py +++ b/eclviewer.py @@ -14,6 +14,7 @@ from pytouhou.formats.pbg3 import PBG3 from pytouhou.formats.std import Stage from pytouhou.formats.ecl import ECL from pytouhou.formats.anm0 import Animations +from pytouhou.game.sprite import AnmWrapper from pytouhou.game.background import Background from pytouhou.game.enemymanager import EnemyManager from pytouhou.opengl.texture import TextureManager @@ -59,10 +60,10 @@ def main(path, stage_num): pass else: anims.append(enemies2_anim) - enemy_manager = EnemyManager(stage, anims, ecl) + enemy_manager = EnemyManager(stage, AnmWrapper(anims), ecl) background_anim = Animations.read(BytesIO(archive.extract('stg%dbg.anm' % stage_num))) - background = Background(stage, background_anim) + background = Background(stage, AnmWrapper((background_anim,))) print(enemy_manager.stage.name) diff --git a/pytouhou/game/background.py b/pytouhou/game/background.py --- a/pytouhou/game/background.py +++ b/pytouhou/game/background.py @@ -8,9 +8,9 @@ from pytouhou.game.sprite import Sprite class Background(object): - def __init__(self, stage, anim): + def __init__(self, stage, anm_wrapper): self.stage = stage - self.anim = anim + self.anm_wrapper = anm_wrapper self.objects = [] self.object_instances = [] self.objects_by_texture = {} @@ -49,7 +49,8 @@ class Background(object): for i, obj in enumerate(self.stage.objects): faces = [] for script_index, ox, oy, oz, width_override, height_override in obj.quads: - sprite = Sprite(self.anim, script_index) + #TODO: per-texture rendering + anm, sprite = self.anm_wrapper.get_sprite(script_index) sprite.update(width_override, height_override) uvs, vertices = sprite._uvs, tuple((x + ox, y + oy, z + oz) for x, y, z in sprite._vertices) faces.append((vertices, uvs)) @@ -64,7 +65,9 @@ class Background(object): uvs_format = 'f' * (2 * nb_vertices) vertices = struct.pack(vertices_format, *chain(*vertices)) uvs = struct.pack(uvs_format, *chain(*uvs)) - self.objects_by_texture = {(self.anim.first_name, self.anim.secondary_name): (nb_vertices, vertices, uvs)} + assert len(self.anm_wrapper.anm_files) == 1 #TODO + anm = self.anm_wrapper.anm_files[0] + self.objects_by_texture = {(anm.first_name, anm.secondary_name): (nb_vertices, vertices, uvs)} self.position_interpolator = Interpolator((0, 0, 0)) self.fog_interpolator = Interpolator((0, 0, 0, 0, 0)) diff --git a/pytouhou/game/enemymanager.py b/pytouhou/game/enemymanager.py --- a/pytouhou/game/enemymanager.py +++ b/pytouhou/game/enemymanager.py @@ -8,8 +8,8 @@ from math import cos, sin, atan2 class Enemy(object): - def __init__(self, pos, life, _type, script, anms): - self.anms = tuple(anms) + def __init__(self, pos, life, _type, script, anm_wrapper): + self.anm_wrapper = anm_wrapper self.anm = None self.script = list(script) self.x, self.y = pos @@ -18,6 +18,7 @@ class Enemy(object): self.frame = 0 self.sprite = None + self.movement_dependant_sprites = None self.interpolator = None #TODO self.angle = 0. self.speed = 0. @@ -34,12 +35,9 @@ class Enemy(object): return False elif instr_type == 97: # set_enemy_sprite script_index, = unpack(' abs(dy): - pass #TODO - else: - pass #TODO - self.x, self.y = x, y + self.speed += self.acceleration #TODO: units? Execution order? 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: - self.x -= dx + x -= dx else: - self.x += dx - self.y += dy + x += dx + y += dy + + if self.movement_dependant_sprites: + #TODO: is that really how it works? + dx, dy = self.x - x, self.y - y + if (dx, dy) == (0, 0): + self.anm, self.sprite = self.anm_wrapper.get_sprite(self.movement_dependant_sprites[0]) + elif abs(dx) > abs(dy): + if dx < 0: + self.anm, self.sprite = self.anm_wrapper.get_sprite(self.movement_dependant_sprites[2]) + else: + self.anm, self.sprite = self.anm_wrapper.get_sprite(self.movement_dependant_sprites[3]) + else: + if dy < 0: + self.anm, self.sprite = self.anm_wrapper.get_sprite(self.movement_dependant_sprites[1]) + else: + self.anm, self.sprite = self.anm_wrapper.get_sprite(self.movement_dependant_sprites[2]) + + self.x, self.y = x, y + if self.sprite: + self.sprite.update() self.frame += 1 return True @@ -88,9 +99,9 @@ class Enemy(object): class EnemyManager(object): - def __init__(self, stage, anims, ecl): + def __init__(self, stage, anm_wrapper, ecl): self.stage = stage - self.anims = tuple(anims) + self.anm_wrapper = anm_wrapper self.main = [] self.subs = {} self.objects_by_texture = {} @@ -120,7 +131,7 @@ class EnemyManager(object): for sub, instr_type, args in self.main.pop(0)[1]: if instr_type in (0, 2, 4, 6): # Normal/mirrored enemy x, y, z, life, unknown1, unknown2, unknown3 = args - self.enemies.append(Enemy((x, y), life, instr_type, self.subs[sub], self.anims)) + self.enemies.append(Enemy((x, y), life, instr_type, self.subs[sub], self.anm_wrapper)) # Update enemies for enemy in tuple(self.enemies): diff --git a/pytouhou/game/sprite.py b/pytouhou/game/sprite.py --- a/pytouhou/game/sprite.py +++ b/pytouhou/game/sprite.py @@ -2,6 +2,18 @@ from struct import unpack from pytouhou.utils.matrix import Matrix + +class AnmWrapper(object): + def __init__(self, anm_files): + self.anm_files = list(anm_files) + + def get_sprite(self, script_index): + for anm in self.anm_files: + if script_index in anm.scripts: + return anm, Sprite(anm, script_index) + + + class Sprite(object): def __init__(self, anm, script_index): self.anm = anm diff --git a/stageviewer.py b/stageviewer.py --- a/stageviewer.py +++ b/stageviewer.py @@ -13,6 +13,7 @@ import pygame from pytouhou.formats.pbg3 import PBG3 from pytouhou.formats.std import Stage from pytouhou.formats.anm0 import Animations +from pytouhou.game.sprite import AnmWrapper from pytouhou.game.background import Background from pytouhou.opengl.texture import TextureManager @@ -49,7 +50,7 @@ def main(path, stage_num): stage = Stage.read(BytesIO(archive.extract('stage%d.std' % stage_num)), stage_num) background_anim = Animations.read(BytesIO(archive.extract('stg%dbg.anm' % stage_num))) - background = Background(stage, background_anim) + background = Background(stage, AnmWrapper((background_anim,))) print(background.stage.name)