view pytouhou/game/background.py @ 108:2a03940deea3

Move everything graphical to pytouhou.opengl!
author Thibaut Girka <thib@sitedethib.com>
date Tue, 06 Sep 2011 00:26:13 +0200
parents ca571697ec83
children 340fcda8e64a
line wrap: on
line source

# -*- encoding: utf-8 -*-
##
## Copyright (C) 2011 Thibaut Girka <thib@sitedethib.com>
##
## This program is free software; you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published
## by the Free Software Foundation; version 3 only.
##
## This program is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
## GNU General Public License for more details.
##


from pytouhou.utils.interpolator import Interpolator
from pytouhou.vm.anmrunner import ANMRunner
from pytouhou.game.sprite import Sprite


class Background(object):
    def __init__(self, stage, anm_wrapper):
        self.stage = stage
        self.anm_wrapper = anm_wrapper

        self.models = []
        self.object_instances = []
        self.anm_runners = []

        self.position_interpolator = Interpolator((0, 0, 0))
        self.fog_interpolator = Interpolator((0, 0, 0, 0, 0))
        self.position2_interpolator = Interpolator((0, 0, 0))

        self.build_models()
        self.build_object_instances()


    def build_object_instances(self):
        self.object_instances = []
        for model_id, ox, oy, oz in self.stage.object_instances:
            self.object_instances.append((ox, oy, oz, model_id, self.models[model_id]))
        # Z-sorting
        def keyfunc(obj):
            bounding_box = self.stage.models[obj[3]].bounding_box
            return obj[2] + min(bounding_box[2], bounding_box[5])
        self.object_instances.sort(key=keyfunc, reverse=True)


    def build_models(self):
        self.models = []
        for obj in self.stage.models:
            quads = []
            for script_index, ox, oy, oz, width_override, height_override in obj.quads:
                #TODO: per-texture rendering
                sprite = Sprite()
                anm_runner = ANMRunner(self.anm_wrapper, script_index, sprite)
                anm_runner.run_frame()
                sprite.update(width_override, height_override)
                quads.append((ox, oy, oz, width_override, height_override, sprite))
                self.anm_runners.append(anm_runner)
            self.models.append(quads)


    def update(self, frame):
        for frame_num, message_type, args in self.stage.script:
            if frame_num == frame:
                if message_type == 0:
                    self.position_interpolator.set_interpolation_start(frame_num, args)
                elif message_type == 1:
                    self.fog_interpolator.set_interpolation_end_values(args)
                elif message_type == 2:
                    self.position2_interpolator.set_interpolation_end_values(args)
                elif message_type == 3:
                    duration, = args
                    self.position2_interpolator.set_interpolation_end_frame(frame_num + duration)
                elif message_type == 4:
                    duration, = args
                    self.fog_interpolator.set_interpolation_end_frame(frame_num + duration)
            if frame_num > frame and message_type == 0:
                self.position_interpolator.set_interpolation_end(frame_num, args)
                break

        for anm_runner in tuple(self.anm_runners):
            if not anm_runner.run_frame():
                self.anm_runners.remove(anm_runner)

        for model in self.models:
            for ox, oy, oz, width_override, height_override, sprite in model:
                sprite.update(width_override, height_override)

        self.position2_interpolator.update(frame)
        self.fog_interpolator.update(frame)
        self.position_interpolator.update(frame)