decoupled tiles from tile images
[koperkapel.git] / koperkapel / loaders / levelloader.py
1 """Loader a level, using the pygame-zero ResourceLoader infrastructure"""
2
3 import json
4
5 from pgzero.loaders import images, ResourceLoader
6 import os
7 import random
8
9 class Tile:
10     IMG = None
11
12     @classmethod
13     def image(cls):
14         if cls.IMG is None:
15             raise NotImplementedError()
16
17         return images.load(cls.IMG)
18
19 class RandomizedTile(Tile):
20     IMGDIR = None
21
22     @classmethod
23     def image(cls):
24         if cls.IMGDIR is None:
25             raise NotImplementedError()
26
27         imgdir = os.path.join(os.path.dirname(__file__), '..', 'images', cls.IMGDIR)
28         img = os.path.splitext(random.choice(os.listdir(imgdir)))[0]
29
30         return images.load(os.path.join(cls.IMGDIR, img))
31
32 class Floor(RandomizedTile):
33     IMGDIR = "floor"
34
35 class Wall(RandomizedTile):
36     IMGDIR = "wall"
37
38 TILES = {
39     "cwall": Wall, # rename this everywhere
40     "floor": Floor,
41 }
42
43 class LevelLoader(ResourceLoader):
44     """ Level loader. """
45
46     EXTNS = ['json']
47     TYPE = 'level'
48
49     def _load(self, level_path):
50         f = open(level_path, 'r')
51         level_data = json.load(f)
52         f.close()
53         self._height = len(level_data['tiles'])
54         self._width = len(level_data['tiles'][0])
55         self._tiles = level_data['tiles']
56         # Consistency check, so we can assume things are correct
57         # in the level renderer
58         for row, row_data in enumerate(self._tiles):
59             if len(row_data) != self._width:
60                 raise RuntimeError("Incorrect len for row %d" % row)
61         self._load_tile_images()
62         return level_data
63
64     def _load_tile_images(self):
65         """Load all the tile images"""
66         for row_data in self._tiles:
67             for tile in row_data:
68                 tile['image'] = TILES[tile['base']].image()
69
70
71 levels = LevelLoader('levels')