changeset 189:9d08f99b5ddf

Add npcs to gamestate. Update gamestate. Pass world around a bit. Some other stuff.
author Simon Cross <hodgestar@gmail.com>
date Wed, 06 Apr 2011 21:14:26 +0200
parents 30a5f7cf670a
children e4b466368b89
files data/game.json skaapsteker/engine.py skaapsteker/gamestate.py skaapsteker/levelscene.py skaapsteker/sprites/base.py skaapsteker/sprites/items.py skaapsteker/sprites/npcs.py
diffstat 7 files changed, 110 insertions(+), 60 deletions(-) [+]
line wrap: on
line diff
--- a/data/game.json	Wed Apr 06 21:02:38 2011 +0200
+++ b/data/game.json	Wed Apr 06 21:14:26 2011 +0200
@@ -1,10 +1,24 @@
 {
+    "fox": {
+        "item": null
+    },
     "missions": {
-        "monk_tea": {
-            "items": {}
-        }
+        "monk_tea": {}
+    },
+    "items": {
+        "tealeaf": { "type": "TeaLeaf", "level": "level1", "pos": [8, 3] },
+        "teacup": { "type": "TeaCup", "level": "level1", "pos": [10, 3] },
+        "teapot": { "type": "TeaPot", "level": "level1", "pos": [12, 3] }
     },
-    "items": [
-        {"type": "Dummy", "level": "level1", "pos": [8, 3]}
-    ]
+    "npcs": {
+        "monk": { "type": "Monk", "level": "level1", "pos": [9, 2], "dsm": "npcs/monk.json" },
+        "guard": { "type": "Guard", "level": "level2", "pos": [10, 3], "dsm": "npcs/guard.json" }
+    },
+    "levels": {
+        "level1" : "level1",
+        "level2" : "level2",
+        "level3" : "level3",
+        "level4" : "level4",
+        "level5" : "level5"
+    }
 }
\ No newline at end of file
--- a/skaapsteker/engine.py	Wed Apr 06 21:02:38 2011 +0200
+++ b/skaapsteker/engine.py	Wed Apr 06 21:14:26 2011 +0200
@@ -14,7 +14,7 @@
         self._current_scene = None
         self._fpss = [self._framerate] * 100
         self._cur_frame = 0
-        self.game_state = GameState()
+        self.game_state = GameState("game.json")
 
     def change_scene(self, next_scene):
         if self._current_scene is not None:
--- a/skaapsteker/gamestate.py	Wed Apr 06 21:02:38 2011 +0200
+++ b/skaapsteker/gamestate.py	Wed Apr 06 21:14:26 2011 +0200
@@ -4,52 +4,57 @@
 from skaapsteker.sprites.base import find_sprite
 
 
-class struct(dict):
+class StateProxy(object):
+
+    def __init__(self, data):
+        self.__dict__['_data'] = data # should be a dict
+
     def __getattr__(self, key):
         try:
-            return self[key]
+            print self, key
+            value = self._data[key]
         except KeyError:
             raise AttributeError
-
+        if isinstance(value, dict):
+            return StateProxy(value)
+        else:
+            return value
 
     def __setattr__(self, key, value):
-        self[key] = value
+        self._data[key] = value
+
+    def __iter__(self):
+        return self._data.keys()
+
+    def __contains__(self, key):
+        return key in self._data
+
+    def copy(self):
+        return self._data.copy()
 
 
 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 __init__(self, game_file, saved=False):
+        if saved:
+            raw_data = open(game_file, "rb").read()
+        else:
+            raw_data = data.load(game_file).read()
+        self.data = json.loads(raw_data)
+        self.world = StateProxy(self.data)
 
-    def build_mission_data(self):
-        self.missions = struct()
-        for name, mission in self.data['missions'].items():
-            self.missions[name] = struct(mission)
-
+    def save(self, save_game_file):
+        json.dumps(self.data, open(save_game_file, "wb"))
 
-    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'))
-
-
+    def create_sprites(self, level):
+        sprites = []
+        for stype, key, needs_world in [
+            ('items', 'items', False),
+            ('npcs', 'npcs', True)]:
+            for sprite_dict in self.data[key].values():
+                sprite_dict = sprite_dict.copy()
+                if needs_world:
+                    sprite_dict['world'] = self.world
+                if sprite_dict.pop('level') == level:
+                    sprites.append(find_sprite(sprite_dict, stype))
+        return sprites
--- a/skaapsteker/levelscene.py	Wed Apr 06 21:02:38 2011 +0200
+++ b/skaapsteker/levelscene.py	Wed Apr 06 21:14:26 2011 +0200
@@ -13,27 +13,23 @@
 
 class LevelScene(engine.Scene):
 
-    def __init__(self, game_state, leveldef, player=None):
+    def __init__(self, game_state, leveldef):
         super(LevelScene, self).__init__(game_state)
-        if not player:
-            self._player = sprites.player.Player()
-        else:
-            self._player = player
+
+        self._player = sprites.player.Player()
         self._level = level.Level(leveldef, self._player)
+
         self._level_surface = self._level.get_surface()
         self._clip_rect = None
         self._world = physics.World()
         self._paused = False
 
-        # hackity, hack, hack
-        for sprite in self._level.enemies:
-            self._world.add(sprite)
-        for sprite in self._level.tiles:
+        for sprite in self._level.sprites:
             self._world.add(sprite)
-        for sprite in self.game_state.levels.get(self._level.name, []):
+        for sprite in self.game_state.create_sprites(self._level.name):
             self._world.add(sprite)
+        self._world.add(self._player)
 
-        self._world.add(self._player)
         self._build_action_map()
 
     def _build_action_map(self):
--- a/skaapsteker/sprites/base.py	Wed Apr 06 21:02:38 2011 +0200
+++ b/skaapsteker/sprites/base.py	Wed Apr 06 21:14:26 2011 +0200
@@ -5,6 +5,7 @@
 from skaapsteker.physics import Sprite
 from skaapsteker.constants import Layers
 from skaapsteker import data
+from skaapsteker import dialogue
 
 
 TILE_SIZE = (64, 64)
@@ -12,6 +13,7 @@
 # Collision Layers (values are ids not numbers)
 PC_LAYER = 0
 MONSTER_LAYER = 1
+NPC_LAYER = 2
 
 
 class Monster(Sprite):
@@ -40,7 +42,26 @@
 
 
 class NPC(Sprite):
-    pass
+
+    image_file = None
+    collision_layer = NPC_LAYER
+    collides_with = set([PC_LAYER])
+
+    debug_color = (240, 240, 240)
+
+    block = True
+
+    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(midbottom=(pos[0]*TILE_SIZE[0]+TILE_SIZE[0]/2, (pos[1]+1)*TILE_SIZE[1]))
+        self.collide_rect = self.rect.move(0, 0)
+        self._layer = Layers.PLAYER
+        self.setup(**opts)
+
+    def setup(self, dsm, world):
+        self.dsm = dialogue.DSM(dsm, world)
 
 
 class Projectile(Sprite):
@@ -74,7 +95,7 @@
 class Geography(Sprite):
     mobile = False
     gravitates = False
-    collides_with = set([PC_LAYER, MONSTER_LAYER])
+    collides_with = set([PC_LAYER, MONSTER_LAYER, NPC_LAYER])
     is_ground = True
     bounce_factor = (0.0, 0.0)
 
--- a/skaapsteker/sprites/items.py	Wed Apr 06 21:02:38 2011 +0200
+++ b/skaapsteker/sprites/items.py	Wed Apr 06 21:14:26 2011 +0200
@@ -1,8 +1,13 @@
 from base import Item
 
 
-class Dummy(Item):
+class TeaCup(Item):
+    image_file = 'teacup_empty.png'
+
+
+class TeaLeaf(Item):
     image_file = 'tealeaf.png'
 
-    def setup(self, missions):
-        self.missions = missions
+
+class TeaPot(Item):
+    image_file = 'teapot.png'
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/skaapsteker/sprites/npcs.py	Wed Apr 06 21:14:26 2011 +0200
@@ -0,0 +1,9 @@
+from .base import NPC
+
+
+class Monk(NPC):
+    image_file = 'monk/monk.png'
+
+
+class Guard(NPC):
+    image_file = 'guard/guard_standing.png'