changeset 21:bf225780973f

Small refactoring, and Rumia \o/
author Thibaut Girka <thib@sitedethib.com>
date Thu, 11 Aug 2011 12:39:12 +0200
parents 6ebf9539c077
children fa87db09fc3a
files eclviewer.py pytouhou/game/background.py pytouhou/game/enemymanager.py pytouhou/game/sprite.py stageviewer.py
diffstat 5 files changed, 58 insertions(+), 30 deletions(-) [+]
line wrap: on
line diff
--- 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)
 
--- 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))
--- 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('<I', args)
-                    if script_index in self.anms[0].scripts:
-                        self.sprite = Sprite(self.anms[0], script_index)
-                        self.anm = self.anms[0]
-                    else:
-                        self.sprite = Sprite(self.anms[1], script_index)
-                        self.anm = self.anms[1]
+                    self.anm, self.sprite = self.anm_wrapper.get_sprite(script_index)
+                elif instr_type == 98: #TODO
+                    self.movement_dependant_sprites = unpack('<HHHHI', args)
                 elif instr_type == 43: # set_pos
                     self.x, self.y, z = unpack('<fff', args)
                     self.interpolator = Interpolator((self.x, self.y)) #TODO: better interpolation
@@ -59,28 +57,41 @@ class Enemy(object):
                 elif instr_type == 57:
                     duration, x, y, z = unpack('<Ifff', args)
                     self.interpolator.set_interpolation_end(self.frame + duration, (x, y))
-        if self.sprite:
-            self.sprite.update()
 
+        x, y = self.x, self.y
         if self.interpolator:
             self.interpolator.update(self.frame)
             x, y = self.interpolator.values
-            dx, dy = x - self.x, y - self.y
-            #TODO: animations
-            if abs(dx) > 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):
--- 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
--- 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)