changeset 127:e1dd3b785269

Initial game state stuff.
author Jeremy Thurgood <firxen@gmail.com>
date Tue, 05 Apr 2011 00:03:33 +0200
parents 9cae256b91d7
children 36267deaccd8
files data/game.json data/levels/level1.json skaapsteker/__main__.py skaapsteker/engine.py skaapsteker/gamestate.py skaapsteker/level.py skaapsteker/levelscene.py skaapsteker/menuscene.py skaapsteker/sprites/base.py skaapsteker/sprites/enemies.py skaapsteker/sprites/items.py
diffstat 11 files changed, 114 insertions(+), 29 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/data/game.json	Tue Apr 05 00:03:33 2011 +0200
@@ -0,0 +1,10 @@
+{
+    "missions": {
+        "monk_tea": {
+            "items": {}
+        }
+    },
+    "items": [
+        {"type": "Dummy", "level": "level1", "pos": [8, 3]}
+    ]
+}
\ No newline at end of file
--- a/data/levels/level1.json	Mon Apr 04 23:38:03 2011 +0200
+++ b/data/levels/level1.json	Tue Apr 05 00:03:33 2011 +0200
@@ -23,8 +23,5 @@
         {"type": "Dummy", "pos": [4, 2], "direction": "left" },
         {"type": "Dummy", "pos": [5, 5], "direction": "right" }
     ],
-    "sprites": [
-        {"type": "enemies.Dummy", "pos": [2, 2], "direction": "left" }
-    ],
-    "player": {"pos": [3, 3], "direction": "left"}
+    "player": {"pos": [3, 3], "direction": "right"}
 }
--- a/skaapsteker/__main__.py	Mon Apr 04 23:38:03 2011 +0200
+++ b/skaapsteker/__main__.py	Tue Apr 05 00:03:33 2011 +0200
@@ -57,9 +57,9 @@
 
     engine = Engine()
     if level is not None:
-        engine.change_scene(LevelScene(level))
+        engine.change_scene(LevelScene(engine.game_state, level))
     else:
-        engine.change_scene(MenuScene())
+        engine.change_scene(MenuScene(engine.game_state))
     try:
         engine.run()
     except KeyboardInterrupt:
--- a/skaapsteker/engine.py	Mon Apr 04 23:38:03 2011 +0200
+++ b/skaapsteker/engine.py	Tue Apr 05 00:03:33 2011 +0200
@@ -5,6 +5,8 @@
 import pygame.event
 from pygame.locals import QUIT, USEREVENT
 
+from skaapsteker.gamestate import GameState
+
 class Engine(object):
 
     def __init__(self):
@@ -12,6 +14,7 @@
         self._current_scene = None
         self._fpss = [self._framerate] * 100
         self._cur_frame = 0
+        self.game_state = GameState()
 
     def change_scene(self, next_scene):
         if self._current_scene is not None:
@@ -44,8 +47,9 @@
 
 class Scene(object):
 
-    def __init__(self):
+    def __init__(self, game_state):
         self.widgets = []
+        self._game_state = game_state
 
     def post(self, ev):
         """Post an event to pygame's event loop."""
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/skaapsteker/gamestate.py	Tue Apr 05 00:03:33 2011 +0200
@@ -0,0 +1,55 @@
+import json
+
+from skaapsteker import data
+from skaapsteker.sprites.base import find_sprite
+
+
+class struct(dict):
+    def __getattr__(self, key):
+        try:
+            return self[key]
+        except KeyError:
+            raise AttributeError
+
+
+    def __setattr__(self, key, value):
+        self[key] = value
+
+
+class GameState(object):
+    def __init__(self, game_file=None):
+        if game_file is None:
+            game_file = 'game.json'
+        self.data = json.loads(data.load(game_file).read())
+        self.build_mission_data()
+        self.build_item_data()
+        self.build_level_data()
+        print self.missions
+        print self.items
+        print self.levels
+
+
+    def build_mission_data(self):
+        self.missions = struct()
+        for name, mission in self.data['missions'].items():
+            self.missions[name] = struct(mission)
+
+
+    def build_item_data(self):
+        self.items = struct()
+        for item in self.data['items']:
+            istruct = struct(item)
+            istruct.missions = struct()
+            self.items[item['type']] = istruct
+        for mission_name, mission in self.missions.items():
+            for name, item in mission['items'].items():
+                self.items[name].missions[mission_name] = item
+
+
+    def build_level_data(self):
+        self.levels = struct()
+        for item in self.items.values():
+            item_level = item.pop('level')
+            self.levels.setdefault(item_level, []).append(find_sprite(item, 'items'))
+
+
--- a/skaapsteker/level.py	Mon Apr 04 23:38:03 2011 +0200
+++ b/skaapsteker/level.py	Tue Apr 05 00:03:33 2011 +0200
@@ -56,6 +56,7 @@
 
 class Level(object):
     def __init__(self, leveldef, player):
+        self.name = leveldef
         self.level_data = json.loads(data.load('levels/' + leveldef + '.json').read())
         self.sprites = LayeredUpdates()
         self.build_backgrounds()
@@ -87,10 +88,11 @@
     def setup_enemies(self):
         self.enemies = LayeredUpdates()
         for enemy_def in self.level_data['enemies']:
-            enemy = enemies.get_enemy(enemy_def)
+            enemy = find_sprite(enemy_def, 'enemies')
             self.enemies.add(enemy)
             self.sprites.add(enemy)
 
+
     def setup_player(self, player):
         player_data = self.level_data['player']
         player.set_facing(player_data.pop('direction', 'left'))
@@ -98,12 +100,6 @@
         player.set_pos(player_data.pop('pos', (5, 5)))
         self.sprites.add(player)
 
-    # def setup_sprites(self):
-    #     self.sprites = []
-    #     for sprite_desc in self.level_data['sprites']:
-    #         self.sprites.append(find_sprite(sprite_desc))
-    #     print self.sprites
-
 
     def get_surface(self):
         return Surface(self.pixel_size)
--- a/skaapsteker/levelscene.py	Mon Apr 04 23:38:03 2011 +0200
+++ b/skaapsteker/levelscene.py	Tue Apr 05 00:03:33 2011 +0200
@@ -13,7 +13,8 @@
 
 class LevelScene(engine.Scene):
 
-    def __init__(self, leveldef, player=None):
+    def __init__(self, game_state, leveldef, player=None):
+        super(LevelScene, self).__init__(game_state)
         if not player:
             self._player = sprites.player.Player()
         else:
@@ -29,6 +30,8 @@
             self._world.add(sprite)
         for sprite in self._level.tiles:
             self._world.add(sprite)
+        for sprite in self._game_state.levels[self._level.name]:
+            self._world.add(sprite)
 
         self._world.add(self._player)
         self._build_action_map()
--- a/skaapsteker/menuscene.py	Mon Apr 04 23:38:03 2011 +0200
+++ b/skaapsteker/menuscene.py	Tue Apr 05 00:03:33 2011 +0200
@@ -6,8 +6,8 @@
 from .widgets.text import Text, TextChoice
 
 class MenuScene(Scene):
-    def __init__(self, cur_game=None):
-        super(MenuScene, self).__init__()
+    def __init__(self, game_state, cur_game=None):
+        super(MenuScene, self).__init__(game_state)
         self.widgets.append(Text("MENU:", (50, 50), color='white', size=48))
         self.cur_game = cur_game
         menu_options = [
@@ -27,7 +27,7 @@
     def selected(self, option, data):
         "Callback from menu TextChoice"
         if data.startswith('level'):
-            ChangeScene.post(LevelScene(data))
+            ChangeScene.post(LevelScene(self._game_state, data))
         elif data == 'quit':
             pygame.event.post(pygame.event.Event(QUIT))
         elif data == 'resume':
--- a/skaapsteker/sprites/base.py	Mon Apr 04 23:38:03 2011 +0200
+++ b/skaapsteker/sprites/base.py	Tue Apr 05 00:03:33 2011 +0200
@@ -48,6 +48,24 @@
     mobile = False
     gravitates = False
 
+    image_file = None
+    collision_layer = MONSTER_LAYER
+    collides_with = set([PC_LAYER])
+
+    debug_color = (240, 0, 240)
+
+    def __init__(self, pos, **opts):
+        Sprite.__init__(self)
+        self.image = data.load_image('sprites/' + self.image_file)
+        self.starting_tile_pos = pos
+        self.rect = self.image.get_rect(topleft=(pos[0]*TILE_SIZE[0], pos[1]*TILE_SIZE[1]))
+        self._layer = Layers.PLAYER
+        self.setup(**opts)
+
+
+    def setup(self):
+        pass
+
 
 class Geography(Sprite):
     mobile = False
@@ -70,11 +88,12 @@
         return (0, 240, 0)
 
 
-def find_sprite(descr):
+def find_sprite(descr, mod_name=None):
     """Create a sprite object from a dictionary describing it."""
     descr = descr.copy()
-    stype = descr.pop("type")
-    mod_name, cls_name = stype.rsplit(".", 1)
+    cls_name = descr.pop("type")
+    if mod_name is None:
+        mod_name, cls_name = cls_name.rsplit(".", 1)
     mod_name = ".".join(["skaapsteker.sprites", mod_name])
     mod =  __import__(mod_name, fromlist=[cls_name])
     cls = getattr(mod, cls_name)
--- a/skaapsteker/sprites/enemies.py	Mon Apr 04 23:38:03 2011 +0200
+++ b/skaapsteker/sprites/enemies.py	Tue Apr 05 00:03:33 2011 +0200
@@ -1,17 +1,10 @@
 from base import Monster
 
-def get_enemy(enemydef):
-    enemydef = enemydef.copy()
-    monster_class = enemydef.pop('type')
-    pos = enemydef.pop('pos')
-    return globals()[monster_class](pos, **enemydef)
-
 
 class Dummy(Monster):
     image_file = 'dummy.png'
 
     def setup(self, direction):
-        print "Dummy monster at %r, facing %s on layer %s" % (self.starting_tile_pos, direction, self._layer)
+        self.facing = direction
 
 
-
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/skaapsteker/sprites/items.py	Tue Apr 05 00:03:33 2011 +0200
@@ -0,0 +1,8 @@
+from base import Item
+
+
+class Dummy(Item):
+    image_file = 'monk/monk.png'
+
+    def setup(self, missions):
+        self.missions = missions