# HG changeset patch # User Simon Cross # Date 1302117266 -7200 # Node ID 9d08f99b5ddf92e6cdf038fa16c397d0c9caeded # Parent 30a5f7cf670a9ea8610671e6fa3aedd85fc40df4 Add npcs to gamestate. Update gamestate. Pass world around a bit. Some other stuff. diff -r 30a5f7cf670a -r 9d08f99b5ddf data/game.json --- 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 diff -r 30a5f7cf670a -r 9d08f99b5ddf skaapsteker/engine.py --- 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: diff -r 30a5f7cf670a -r 9d08f99b5ddf skaapsteker/gamestate.py --- 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 diff -r 30a5f7cf670a -r 9d08f99b5ddf skaapsteker/levelscene.py --- 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): diff -r 30a5f7cf670a -r 9d08f99b5ddf skaapsteker/sprites/base.py --- 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) diff -r 30a5f7cf670a -r 9d08f99b5ddf skaapsteker/sprites/items.py --- 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' diff -r 30a5f7cf670a -r 9d08f99b5ddf skaapsteker/sprites/npcs.py --- /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'