Browse code
added terrain
edwlan authored on 26/07/2013 18:32:05
Showing 2 changed files
Showing 2 changed files
... | ... |
@@ -11,7 +11,9 @@ from src import map |
11 | 11 |
class Application(object): |
12 | 12 |
def __init__(self): |
13 | 13 |
self.screen = console.Screen(200,125) |
14 |
- self.map = map.Map(200,125) |
|
14 |
+ self.terrain_registry = map.TerrainRegistry() |
|
15 |
+ self.terrain_registry.load_from_file('data/terrain.yml') |
|
16 |
+ self.map = map.Map(200,125, self.terrain_registry) |
|
15 | 17 |
self.player = player.Player(4,5, self.map) |
16 | 18 |
self.events = events.EventHandler() |
17 | 19 |
player.ArrowHandler(self.player, self.events) |
... | ... |
@@ -1,22 +1,45 @@ |
1 | 1 |
import numpy as np |
2 | 2 |
import libtcodpy as tc |
3 |
+import yaml |
|
3 | 4 |
|
4 | 5 |
def squeeze(val, low, high): |
5 | 6 |
return min(max(val, low), high) |
6 | 7 |
|
8 |
+class TerrainGen(object): |
|
9 |
+ def __init__(self, map): |
|
10 |
+ self.width, self.height = map.dim |
|
11 |
+ self.terrain_registry = map.terrain_registry |
|
12 |
+ |
|
13 |
+ def generate(self): |
|
14 |
+ w,h = self.width, self.height |
|
15 |
+ map = np.random.choice(self.terrain_registry.get_terrain_types(), (w,h)) |
|
16 |
+ print self.terrain_registry.get_terrain_types() |
|
17 |
+ print map[map>4] |
|
18 |
+ chars = np.zeros((w,h)).astype('int') |
|
19 |
+ fgcolors = np.zeros((w,h,3)) |
|
20 |
+ bgcolors = np.zeros((w,h,3)) |
|
21 |
+ |
|
22 |
+ for x, row in enumerate(map): |
|
23 |
+ for y, cell in enumerate(row): |
|
24 |
+ char, bgcolor, fgcolor = self.terrain_registry.get_display(cell) |
|
25 |
+ chars[x,y] = char |
|
26 |
+ fgcolors[x,y] = fgcolor |
|
27 |
+ bgcolors[x,y] = bgcolor |
|
28 |
+ return map, chars, fgcolors, bgcolors |
|
29 |
+ |
|
30 |
+ |
|
7 | 31 |
class Map(object): |
8 |
- def __init__(self, w, h): |
|
32 |
+ def __init__(self, w, h, terrain_registry): |
|
33 |
+ self.pov = None |
|
9 | 34 |
self.width = w |
10 | 35 |
self.height = h |
11 |
- self.map = np.random.random_integers(ord('a'), ord('z'), (w,h) ) |
|
12 |
- self.map[3,5] = ord('*') |
|
13 |
- self.map[::10, ::10] = ord('#') |
|
14 |
- self.fgcolors = np.random.random_integers(100,255, (w,h,3) ) |
|
15 |
- self.fgcolors[::10,::10] = (0,0,0) |
|
16 |
- self.bgcolors = np.random.random_integers(0,100, (w,h,3) ) |
|
17 |
- self.bgcolors[::10,::10] = (255,255,255) |
|
36 |
+ self.terrain_registry = terrain_registry |
|
18 | 37 |
self.overlays = {} # (x,y): { set( object, ... ) } |
19 | 38 |
|
39 |
+ self.ids, self.map, self.fgcolors, self.bgcolors = TerrainGen(self).generate() |
|
40 |
+ |
|
41 |
+ self.fov = FovCache(self, self.terrain_registry) |
|
42 |
+ |
|
20 | 43 |
def add(self, object): |
21 | 44 |
self.overlays.setdefault(object.pos,[]).append(object) |
22 | 45 |
|
... | ... |
@@ -59,3 +82,102 @@ class Map(object): |
59 | 82 |
tc.console_set_char_foreground(con.con, screen_x,screen_y, tc.black) |
60 | 83 |
tc.console_set_char_background(con.con, screen_x,screen_y, tc.white) |
61 | 84 |
tc.console_fill_char(con.con, chars.transpose()) |
85 |
+ |
|
86 |
+ def coord_iter(self): |
|
87 |
+ return ( (x,y) for x in range(self.width) for y in range(self.height) ) |
|
88 |
+ |
|
89 |
+ @property |
|
90 |
+ def dim(self): |
|
91 |
+ return self.width, self.height |
|
92 |
+ |
|
93 |
+ |
|
94 |
+class FovCache(object): |
|
95 |
+ # TODO: get allow updates to base_map |
|
96 |
+ def __init__(self, map, terrain_registry): |
|
97 |
+ self.base_map = tc.map_new(*map.dim) |
|
98 |
+ |
|
99 |
+ for x,y in map.coord_iter(): |
|
100 |
+ if (x,y) in map.overlays: |
|
101 |
+ object = map.overlays[x,y] |
|
102 |
+ pssble,trnsprnt = object.passable, object.transparent |
|
103 |
+ else: |
|
104 |
+ pssble,trnsprnt = terrain_registry.get_props(map.ids[x,y]) |
|
105 |
+ tc.map_set_properties(self.base_map, x,y, trnsprnt,pssble) |
|
106 |
+ |
|
107 |
+ self.fovmaps = {} |
|
108 |
+ |
|
109 |
+ def get_fovmap(self, terrain_registry, origin, radius): |
|
110 |
+ key = origin,radius |
|
111 |
+ |
|
112 |
+ if key in self.fovmaps: fovmap = self.fovmaps[key] |
|
113 |
+ else: |
|
114 |
+ fovmap = tc.map_new(self.width, self.height) |
|
115 |
+ tc.map_copy(self.base_map, fovmap) |
|
116 |
+ self.fovmaps[key] = fovmap |
|
117 |
+ |
|
118 |
+ x,y = origin |
|
119 |
+ tc.map_compute_fov(fovmap, x,y, radius) |
|
120 |
+ |
|
121 |
+ return fovmap |
|
122 |
+ |
|
123 |
+ def is_transparent(self, coord): |
|
124 |
+ return tc.map_is_transparent(self.base_map, *coord) |
|
125 |
+ def is_passable(self, coord): |
|
126 |
+ return tc.map_is_walkable(self.base_map, *coord) |
|
127 |
+ |
|
128 |
+ |
|
129 |
+class TerrainInfo(object): |
|
130 |
+ passable = False |
|
131 |
+ transparent = False |
|
132 |
+ char = ord(' ') |
|
133 |
+ fg = (255,255,255) |
|
134 |
+ bg = (0,0,0) |
|
135 |
+ |
|
136 |
+ @classmethod |
|
137 |
+ def make_terrain(cls, name, char, passable, transparent,fg,bg): |
|
138 |
+ if hasattr(char, 'upper'): char = ord(char) |
|
139 |
+ passable = bool(passable) |
|
140 |
+ transparent = bool(transparent) |
|
141 |
+ return type(name, (cls,), dict(char=char, passable=passable, transparent=transparent,fg=fg,bg=bg)) |
|
142 |
+ |
|
143 |
+class TerrainRegistry(object): |
|
144 |
+ def __init__(self): |
|
145 |
+ self.id = 0 |
|
146 |
+ self.registry = {} |
|
147 |
+ self.names = {} |
|
148 |
+ |
|
149 |
+ def get_terrain(self, id): |
|
150 |
+ ter = self.registry[id] |
|
151 |
+ return ter |
|
152 |
+ |
|
153 |
+ def get_props(self, id): |
|
154 |
+ ter = self.get_terrain(id) |
|
155 |
+ return ter.passable, ter.transparent |
|
156 |
+ |
|
157 |
+ def get_display(self, char): |
|
158 |
+ ter = self.get_terrain(char) |
|
159 |
+ return ter.char, ter.fg, ter.bg |
|
160 |
+ |
|
161 |
+ def get_terrain_types(self): |
|
162 |
+ return list(self.registry) |
|
163 |
+ |
|
164 |
+ |
|
165 |
+ def register(self, ter): |
|
166 |
+ self.id += 1 |
|
167 |
+ self.registry[self.id] = ter |
|
168 |
+ self.names[ter.__name__] = ter |
|
169 |
+ return ter |
|
170 |
+ |
|
171 |
+ def new_terrain(self, name, char, |
|
172 |
+ passable=False, transparent=False, fg=(255,255,255), bg=(0,0,0) |
|
173 |
+ ): |
|
174 |
+ ter = TerrainInfo.make_terrain(name, char, passable, transparent, fg,bg) |
|
175 |
+ return self.register(ter) |
|
176 |
+ |
|
177 |
+ def load_from_file(self, fn, loader=yaml.safe_load): |
|
178 |
+ with open(fn) as f: |
|
179 |
+ values = loader(f) |
|
180 |
+ for name, terrain in values.viewitems(): |
|
181 |
+ self.new_terrain(name, **terrain) |
|
182 |
+ |
|
183 |
+ |