changeset 151:5cf927cbd9c5

Merge GameState into Game. TODO: Merge PlayerState into Player
author Thibaut Girka <thib@sitedethib.com>
date Tue, 04 Oct 2011 23:32:02 +0200
parents 4f46717390aa
children 86807b8a63bd
files pytouhou/game/bullet.py pytouhou/game/enemy.py pytouhou/game/game.py pytouhou/game/item.py pytouhou/opengl/gamerenderer.pyx pytouhou/opengl/gamerunner.py pytouhou/vm/eclrunner.py
diffstat 7 files changed, 69 insertions(+), 83 deletions(-) [+]
line wrap: on
line diff
--- a/pytouhou/game/bullet.py
+++ b/pytouhou/game/bullet.py
@@ -21,8 +21,8 @@ from pytouhou.game.sprite import Sprite
 
 class Bullet(object):
     def __init__(self, pos, bullet_type, sprite_idx_offset,
-                       angle, speed, attributes, flags, player, game_state):
-        self._game_state = game_state
+                       angle, speed, attributes, flags, player, game):
+        self._game = game
         self._sprite = None
         self._anmrunner = None
         self._removed = False
--- a/pytouhou/game/enemy.py
+++ b/pytouhou/game/enemy.py
@@ -22,8 +22,8 @@ from math import cos, sin, atan2, pi
 
 
 class Enemy(object):
-    def __init__(self, pos, life, _type, anm_wrapper, game_state, pop_enemy):
-        self._game_state = game_state
+    def __init__(self, pos, life, _type, anm_wrapper, game, pop_enemy):
+        self._game = game
         self._anm_wrapper = anm_wrapper
         self._sprite = None
         self._anmrunner = None
@@ -86,7 +86,7 @@ class Enemy(object):
         (type_, type_idx, sprite_idx_offset, bullets_per_shot, number_of_shots,
          speed, speed2, launch_angle, angle, flags) = self.bullet_attributes
 
-        bullet_type = self._game_state.bullet_types[type_idx]
+        bullet_type = self._game.bullet_types[type_idx]
 
         ox, oy = self.bullet_launch_offset
         launch_pos = self.x + ox, self.y + oy
@@ -107,8 +107,8 @@ class Enemy(object):
         if type_ != 75:
             launch_angle -= angle * (bullets_per_shot - 1) / 2.
 
-        bullets = self._game_state.bullets
-        nb_bullets_max = self._game_state.nb_bullets_max
+        bullets = self._game.bullets
+        nb_bullets_max = self._game.nb_bullets_max
 
         for shot_nb in range(number_of_shots):
             shot_speed = speed if shot_nb == 0 else speed + (speed2 - speed) * float(shot_nb) / float(number_of_shots)
@@ -118,18 +118,18 @@ class Enemy(object):
                     break
 
                 if type_ == 75: # 102h.exe@0x4138cf
-                    bullet_angle = self._game_state.prng.rand_double() * (launch_angle - angle) + angle
+                    bullet_angle = self._game.prng.rand_double() * (launch_angle - angle) + angle
                 if type_ in (74, 75): # 102h.exe@0x4138cf
-                    shot_speed = self._game_state.prng.rand_double() * (speed - speed2) + speed2
+                    shot_speed = self._game.prng.rand_double() * (speed - speed2) + speed2
                 bullets.append(Bullet(launch_pos, bullet_type, sprite_idx_offset,
                                       bullet_angle, shot_speed,
                                       self.extended_bullet_attributes,
-                                      flags, player, self._game_state))
+                                      flags, player, self._game))
                 bullet_angle += angle
 
 
     def select_player(self, players=None):
-        return (players or self._game_state.players)[0] #TODO
+        return (players or self._game.players)[0] #TODO
 
 
     def get_player_angle(self, player=None, pos=None):
@@ -147,12 +147,12 @@ class Enemy(object):
     def set_pos(self, x, y, z):
         self.x, self.y = x, y
         self.interpolator = Interpolator((x, y))
-        self.interpolator.set_interpolation_start(self._game_state.frame, (x, y))
+        self.interpolator.set_interpolation_start(self._game.frame, (x, y))
 
 
     def move_to(self, duration, x, y, z, formula):
         if not self.interpolator:
-            frame = self._game_state.frame
+            frame = self._game.frame
             self.interpolator = Interpolator((self.x, self.y), formula)
             self.interpolator.set_interpolation_start(frame, (self.x, self.y))
             self.interpolator.set_interpolation_end(frame + duration - 1, (x, y))
@@ -163,7 +163,7 @@ class Enemy(object):
 
     def stop_in(self, duration, formula):
         if not self.speed_interpolator:
-            frame = self._game_state.frame
+            frame = self._game.frame
             self.speed_interpolator = Interpolator((self.speed,), formula)
             self.speed_interpolator.set_interpolation_start(frame, (self.speed,))
             self.speed_interpolator.set_interpolation_end(frame + duration - 1, (0.,))
@@ -194,7 +194,7 @@ class Enemy(object):
     def update(self):
         x, y = self.x, self.y
         if self.interpolator:
-            self.interpolator.update(self._game_state.frame)
+            self.interpolator.update(self._game.frame)
             x, y = self.interpolator.values
 
         self.speed += self.acceleration #TODO: units? Execution order?
@@ -202,7 +202,7 @@ class Enemy(object):
 
 
         if self.speed_interpolator:
-            self.speed_interpolator.update(self._game_state.frame)
+            self.speed_interpolator.update(self._game.frame)
             self.speed, = self.speed_interpolator.values
 
 
--- a/pytouhou/game/game.py
+++ b/pytouhou/game/game.py
@@ -22,29 +22,34 @@ from pytouhou.game.enemy import Enemy
 from pytouhou.game.item import Item
 
 
-class GameState(object):
-    __slots__ = ('resource_loader', 'bullets', 'items', 'players', 'rank', 'difficulty', 'frame',
-                 'stage', 'boss', 'prng', 'bullet_types', 'item_types', 'characters', 'nb_bullets_max')
-    def __init__(self, resource_loader, players, stage, rank, difficulty,
-                 bullet_types, item_types, characters, nb_bullets_max):
+
+class Game(object):
+    def __init__(self, resource_loader, player_states, stage, rank, difficulty,
+                 bullet_types, item_types, characters, nb_bullets_max=None):
         self.resource_loader = resource_loader
 
+        self.nb_bullets_max = nb_bullets_max
         self.bullet_types = bullet_types
         self.item_types = item_types
         self.characters = characters
 
+        self.players = [Player(player_state, characters[player_state.character]) for player_state in player_states]
+        self.enemies = []
         self.bullets = []
         self.items = []
-        self.nb_bullets_max = nb_bullets_max
 
         self.stage = stage
-        self.players = players
         self.rank = rank
         self.difficulty = difficulty
         self.boss = None
         self.prng = Random()
         self.frame = 0
 
+        self.enm_anm_wrapper = resource_loader.get_anm_wrapper2(('stg%denm.anm' % stage,
+                                                                 'stg%denm2.anm' % stage))
+        ecl = resource_loader.get_ecl('ecldata%d.ecl' % stage)
+        self.ecl_runner = ECLMainRunner(ecl, self.new_enemy, self)
+
 
     def change_bullets_into_star_items(self):
         player = self.players[0] #TODO
@@ -53,27 +58,8 @@ class GameState(object):
         self.bullets = []
 
 
-
-class Game(object):
-    def __init__(self, resource_loader, player_states, stage, rank, difficulty,
-                 bullet_types, item_types, characters, nb_bullets_max=None):
-        self.game_state = GameState(resource_loader, player_states, stage,
-                                    rank, difficulty,
-                                    bullet_types, item_types, characters, nb_bullets_max)
-
-        self.players = [Player(player_state, characters[player_state.character]) for player_state in player_states]
-        self.enemies = []
-
-        self.bonuses = []
-
-        self.enm_anm_wrapper = resource_loader.get_anm_wrapper2(('stg%denm.anm' % stage,
-                                                                 'stg%denm2.anm' % stage))
-        ecl = resource_loader.get_ecl('ecldata%d.ecl' % stage)
-        self.ecl_runner = ECLMainRunner(ecl, self.new_enemy, self.game_state)
-
-
     def new_enemy(self, pos, life, instr_type, pop_enemy):
-        enemy = Enemy(pos, life, instr_type, self.enm_anm_wrapper, self.game_state, pop_enemy)
+        enemy = Enemy(pos, life, instr_type, self.enm_anm_wrapper, self, pop_enemy)
         self.enemies.append(enemy)
         return enemy
 
@@ -101,10 +87,10 @@ class Game(object):
         for enemy in self.enemies:
             enemy.update()
 
-        for bullet in self.game_state.bullets:
+        for bullet in self.bullets:
             bullet.update()
 
-        for item in self.game_state.items:
+        for item in self.items:
             item.update()
 
         # 4. Check for collisions!
@@ -114,7 +100,7 @@ class Game(object):
             phalf_size = player.hitbox_half_size
             px1, px2 = px - phalf_size, px + phalf_size
             py1, py2 = py - phalf_size, py + phalf_size
-            for bullet in self.game_state.bullets:
+            for bullet in self.bullets:
                 half_size = bullet.hitbox_half_size
                 bx, by = bullet.x, bullet.y
                 bx1, bx2 = bx - half_size, bx + half_size
@@ -130,7 +116,7 @@ class Game(object):
         # 5. Cleaning
         self.cleanup()
 
-        self.game_state.frame += 1
+        self.frame += 1
 
 
     def cleanup(self):
@@ -145,9 +131,9 @@ class Game(object):
 
         # Filter out-of-scren bullets
         # TODO: was_visible thing
-        self.game_state.bullets = [bullet for bullet in self.game_state.bullets if bullet.is_visible(384, 448)]
+        self.bullets = [bullet for bullet in self.bullets if bullet.is_visible(384, 448)]
 
         # Disable boss mode if it is dead/it has timeout
-        if self.game_state.boss and self.game_state.boss._removed:
-            self.game_state.boss = None
+        if self.boss and self.boss._removed:
+            self.boss = None
 
--- a/pytouhou/game/item.py
+++ b/pytouhou/game/item.py
@@ -17,8 +17,8 @@ from math import cos, sin, atan2, pi
 
 
 class Item(object):
-    def __init__(self, pos, item_type, angle, speed, player, game_state):
-        self._game_state = game_state
+    def __init__(self, pos, item_type, angle, speed, player, game):
+        self._game = game
         self._sprite = item_type.sprite
         self._removed = False
         self._item_type = item_type
--- a/pytouhou/opengl/gamerenderer.pyx
+++ b/pytouhou/opengl/gamerenderer.pyx
@@ -151,8 +151,8 @@ cdef class GameRenderer:
             glDisable(GL_FOG)
             self.render_elements(game.enemies)
             self.render_elements(game.players)
-            self.render_elements(game.game_state.bullets)
-            self.render_elements(game.game_state.items)
+            self.render_elements(game.bullets)
+            self.render_elements(game.items)
             #TODO: display item indicators
             glEnable(GL_FOG)
 
--- a/pytouhou/opengl/gamerunner.py
+++ b/pytouhou/opengl/gamerunner.py
@@ -86,7 +86,7 @@ class GameRunner(pyglet.window.Window, G
 
     def update(self):
         if self.background:
-            self.background.update(self.game.game_state.frame)
+            self.background.update(self.game.frame)
         if self.game:
             #TODO: allow user settings
             keystate = 0
--- a/pytouhou/vm/eclrunner.py
+++ b/pytouhou/vm/eclrunner.py
@@ -25,13 +25,13 @@ logger = get_logger(__name__)
 
 class ECLMainRunner(object):
     __metaclass__ = MetaRegistry
-    __slots__ = ('_ecl', '_new_enemy_func', '_game_state', 'processes',
+    __slots__ = ('_ecl', '_new_enemy_func', '_game', 'processes',
                  'instruction_pointer')
 
-    def __init__(self, ecl, new_enemy_func, game_state):
+    def __init__(self, ecl, new_enemy_func, game):
         self._ecl = ecl
         self._new_enemy_func = new_enemy_func
-        self._game_state = game_state
+        self._game = game
 
         self.processes = []
 
@@ -45,12 +45,12 @@ class ECLMainRunner(object):
             except IndexError:
                 break
 
-            if frame > self._game_state.frame:
+            if frame > self._game.frame:
                 break
             else:
                 self.instruction_pointer += 1
 
-            if frame == self._game_state.frame:
+            if frame == self._game.frame:
                 try:
                     callback = self._handlers[instr_type]
                 except KeyError:
@@ -65,13 +65,13 @@ class ECLMainRunner(object):
     def _pop_enemy(self, sub, instr_type, x, y, z, life, bonus_dropped, unknown2, unknown3):
         if instr_type & 4:
             if x < -990: #102h.exe@0x411820
-                x = self._game_state.prng.rand_double() * 368
+                x = self._game.prng.rand_double() * 368
             if y < -990: #102h.exe@0x41184b
-                y = self._game_state.prng.rand_double() * 416
+                y = self._game.prng.rand_double() * 416
             if z < -990: #102h.exe@0x411881
-                y = self._game_state.prng.rand_double() * 800
+                y = self._game.prng.rand_double() * 800
         enemy = self._new_enemy_func((x, y), life, instr_type, self._pop_enemy)
-        process = ECLRunner(self._ecl, sub, enemy, self._game_state)
+        process = ECLRunner(self._ecl, sub, enemy, self._game)
         self.processes.append(process)
         process.run_iteration()
 
@@ -81,7 +81,7 @@ class ECLMainRunner(object):
     @instruction(4)
     @instruction(6)
     def pop_enemy(self, sub, instr_type, x, y, z, life, bonus_dropped, unknown2, unknown3):
-        if self._game_state.boss:
+        if self._game.boss:
             return
         self._pop_enemy(sub, instr_type, x, y, z, life, bonus_dropped, unknown2, unknown3)
 
@@ -90,14 +90,14 @@ class ECLMainRunner(object):
 
 class ECLRunner(object):
     __metaclass__ = MetaRegistry
-    __slots__ = ('_ecl', '_enemy', '_game_state', 'variables', 'sub', 'frame',
+    __slots__ = ('_ecl', '_enemy', '_game', 'variables', 'sub', 'frame',
                  'instruction_pointer', 'comparison_reg', 'stack')
 
-    def __init__(self, ecl, sub, enemy, game_state):
+    def __init__(self, ecl, sub, enemy, game):
         # Things not supposed to change
         self._ecl = ecl
         self._enemy = enemy
-        self._game_state = game_state
+        self._game = game
 
         # Things supposed to change (and be put in the stack)
         self.variables = [0,  0,  0,  0,
@@ -159,7 +159,7 @@ class ECLRunner(object):
 
 
             #TODO: skip bad ranks
-            if not rank_mask & (0x100 << self._game_state.rank):
+            if not rank_mask & (0x100 << self._game.rank):
                 continue
 
 
@@ -181,9 +181,9 @@ class ECLRunner(object):
             return self.variables[int(-10001-value)]
         elif -10025 <= value <= -10013:
             if value == -10013:
-                return self._game_state.rank
+                return self._game.rank
             elif value == -10014:
-                return self._game_state.difficulty
+                return self._game.difficulty
             elif value == -10015:
                 return self._enemy.x
             elif value == -10016:
@@ -203,7 +203,7 @@ class ECLRunner(object):
             elif value == -10024:
                 return self._enemy.life
             elif value == -10025:
-                return self._enemy.select_player().character
+                return self._enemy.select_player().state.character #TODO
             raise NotImplementedError(value) #TODO
         else:
             return value
@@ -274,19 +274,19 @@ class ECLRunner(object):
     def set_random_int(self, variable_id, maxval):
         """Set the specified variable to a random int in the [0, maxval) range.
         """
-        self._setval(variable_id, int(self._getval(maxval) * self._game_state.prng.rand_double()))
+        self._setval(variable_id, int(self._getval(maxval) * self._game.prng.rand_double()))
 
 
     @instruction(8)
     def set_random_float(self, variable_id, maxval):
         """Set the specified variable to a random float in [0, maxval) range.
         """
-        self._setval(variable_id, self._getval(maxval) * self._game_state.prng.rand_double())
+        self._setval(variable_id, self._getval(maxval) * self._game.prng.rand_double())
 
 
     @instruction(9)
     def set_random_float2(self, variable_id, amp, minval):
-        self._setval(variable_id, self._getval(minval) + self._getval(amp) * self._game_state.prng.rand_double())
+        self._setval(variable_id, self._getval(minval) + self._getval(amp) * self._game.prng.rand_double())
 
 
     @instruction(10)
@@ -443,7 +443,7 @@ class ECLRunner(object):
 
     @instruction(49)
     def set_random_angle(self, min_angle, max_angle):
-        angle = self._game_state.prng.rand_double() * (max_angle - min_angle) + min_angle
+        angle = self._game.prng.rand_double() * (max_angle - min_angle) + min_angle
         self._enemy.angle = angle
 
 
@@ -454,7 +454,7 @@ class ECLRunner(object):
         else:
             minx, miny, maxx, maxy = (0., 0., 0., 0.)
 
-        angle = self._game_state.prng.rand_double() * (max_angle - min_angle) + min_angle
+        angle = self._game.prng.rand_double() * (max_angle - min_angle) + min_angle
         sa, ca = sin(angle), cos(angle)
 
         distx = min(96.0, (maxx - minx) / 2.)
@@ -635,7 +635,7 @@ class ECLRunner(object):
     @instruction(77)
     def set_bullet_interval_ex(self, value):
         self._enemy.bullet_launch_interval = value
-        self._enemy.bullet_launch_timer = int(self._game_state.prng.rand_double() * value) #TODO: check
+        self._enemy.bullet_launch_timer = int(self._game.prng.rand_double() * value) #TODO: check
 
 
     @instruction(78)
@@ -660,7 +660,7 @@ class ECLRunner(object):
 
     @instruction(83)
     def change_bullets_into_star_items(self):
-        self._game_state.change_bullets_into_star_items()
+        self._game.change_bullets_into_star_items()
 
 
     @instruction(93)
@@ -693,7 +693,7 @@ class ECLRunner(object):
     @instruction(101)
     def set_boss_mode(self, unknown):
         #TODO: unknown
-        self._game_state.boss = self._enemy
+        self._game.boss = self._enemy
 
 
     @instruction(103)
@@ -787,14 +787,14 @@ class ECLRunner(object):
     def call_special_function(self, function, arg):
         if function == 0: # Cirno
             if arg == 0:
-                for bullet in self._game_state.bullets:
+                for bullet in self._game.bullets:
                     bullet.speed = bullet.angle = 0.
                     bullet.delta = (0., 0.)
                     bullet.set_anim(sprite_idx_offset=15) #TODO: check
             else:
-                for bullet in self._game_state.bullets:
+                for bullet in self._game.bullets:
                     bullet.speed = 2.0 #TODO
-                    bullet.angle = self._game_state.prng.rand_double() * pi #TODO
+                    bullet.angle = self._game.prng.rand_double() * pi #TODO
                     bullet.delta = (cos(bullet.angle) * bullet.speed, sin(bullet.angle) * bullet.speed)
         else:
             logger.warn("Unimplemented special function %d!", function)