1 | #!/usr/bin/env python |
||
2 | # |
||
3 | # libtcod python samples |
||
4 | # This code demonstrates various usages of libtcod modules |
||
5 | # It's in the public domain. |
||
6 | # |
||
7 | from __future__ import division |
||
8 | |||
9 | import math |
||
10 | import os |
||
11 | |||
12 | import tcod as libtcod |
||
13 | |||
14 | # Import Psyco if available |
||
15 | try: |
||
16 | import psyco |
||
17 | psyco.full() |
||
18 | except ImportError: |
||
19 | pass |
||
20 | |||
21 | SAMPLE_SCREEN_WIDTH = 46 |
||
22 | SAMPLE_SCREEN_HEIGHT = 20 |
||
23 | SAMPLE_SCREEN_X = 20 |
||
24 | SAMPLE_SCREEN_Y = 10 |
||
25 | font = os.path.join(b'data', b'fonts', b'consolas10x10_gs_tc.png') |
||
26 | libtcod.console_set_custom_font(font, libtcod.FONT_TYPE_GREYSCALE | libtcod.FONT_LAYOUT_TCOD) |
||
27 | libtcod.console_init_root(80, 50, b'libtcod python sample', False) |
||
28 | sample_console = libtcod.console_new(SAMPLE_SCREEN_WIDTH, SAMPLE_SCREEN_HEIGHT) |
||
29 | |||
30 | ############################################# |
||
31 | # parser unit test |
||
32 | ############################################# |
||
33 | # parser declaration |
||
34 | if True: |
||
35 | print ('***** File Parser test *****') |
||
36 | parser=libtcod.parser_new() |
||
37 | struct=libtcod.parser_new_struct(parser, b'myStruct') |
||
38 | libtcod.struct_add_property(struct, b'bool_field', libtcod.TYPE_BOOL, True) |
||
39 | libtcod.struct_add_property(struct, b'char_field', libtcod.TYPE_CHAR, True) |
||
40 | libtcod.struct_add_property(struct, b'int_field', libtcod.TYPE_INT, True) |
||
41 | libtcod.struct_add_property(struct, b'float_field', libtcod.TYPE_FLOAT, True) |
||
42 | libtcod.struct_add_property(struct, b'color_field', libtcod.TYPE_COLOR, True) |
||
43 | libtcod.struct_add_property(struct, b'dice_field', libtcod.TYPE_DICE, True) |
||
44 | libtcod.struct_add_property(struct, b'string_field', libtcod.TYPE_STRING, |
||
45 | True) |
||
46 | libtcod.struct_add_list_property(struct, b'bool_list', libtcod.TYPE_BOOL, |
||
47 | True) |
||
48 | libtcod.struct_add_list_property(struct, b'char_list', libtcod.TYPE_CHAR, |
||
49 | True) |
||
50 | libtcod.struct_add_list_property(struct, b'integer_list', libtcod.TYPE_INT, |
||
51 | True) |
||
52 | libtcod.struct_add_list_property(struct, b'float_list', libtcod.TYPE_FLOAT, |
||
53 | True) |
||
54 | libtcod.struct_add_list_property(struct, b'string_list', libtcod.TYPE_STRING, |
||
55 | True) |
||
56 | libtcod.struct_add_list_property(struct, b'color_list', libtcod.TYPE_COLOR, |
||
57 | True) |
||
58 | ## # dice lists doesn't work yet |
||
59 | ## libtcod.struct_add_list_property(struct, b'dice_list', libtcod.TYPE_DICE, |
||
60 | ## True) |
||
61 | |||
62 | # default listener |
||
63 | print ('***** Default listener *****') |
||
64 | libtcod.parser_run(parser, os.path.join(b'data', b'cfg', b'sample.cfg')) |
||
65 | print ('bool_field : ', \ |
||
66 | libtcod.parser_get_bool_property(parser, b'myStruct.bool_field')) |
||
67 | print ('char_field : ', \ |
||
68 | libtcod.parser_get_char_property(parser, b'myStruct.char_field')) |
||
69 | print ('int_field : ', \ |
||
70 | libtcod.parser_get_int_property(parser, b'myStruct.int_field')) |
||
71 | print ('float_field : ', \ |
||
72 | libtcod.parser_get_float_property(parser, b'myStruct.float_field')) |
||
73 | print ('color_field : ', \ |
||
74 | libtcod.parser_get_color_property(parser, b'myStruct.color_field')) |
||
75 | print ('dice_field : ', \ |
||
76 | libtcod.parser_get_dice_property(parser, b'myStruct.dice_field')) |
||
77 | print ('string_field : ', \ |
||
78 | libtcod.parser_get_string_property(parser, b'myStruct.string_field')) |
||
79 | print ('bool_list : ', \ |
||
80 | libtcod.parser_get_list_property(parser, b'myStruct.bool_list', |
||
81 | libtcod.TYPE_BOOL)) |
||
82 | print ('char_list : ', \ |
||
83 | libtcod.parser_get_list_property(parser, b'myStruct.char_list', |
||
84 | libtcod.TYPE_CHAR)) |
||
85 | print ('integer_list : ', \ |
||
86 | libtcod.parser_get_list_property(parser, b'myStruct.integer_list', |
||
87 | libtcod.TYPE_INT)) |
||
88 | print ('float_list : ', \ |
||
89 | libtcod.parser_get_list_property(parser, b'myStruct.float_list', |
||
90 | libtcod.TYPE_FLOAT)) |
||
91 | print ('string_list : ', \ |
||
92 | libtcod.parser_get_list_property(parser, b'myStruct.string_list', |
||
93 | libtcod.TYPE_STRING)) |
||
94 | print ('color_list : ', \ |
||
95 | libtcod.parser_get_list_property(parser, b'myStruct.color_list', |
||
96 | libtcod.TYPE_COLOR)) |
||
97 | ## print ('dice_list : ', \ |
||
98 | ## libtcod.parser_get_list_property(parser, b'myStruct.dice_list', |
||
99 | ## libtcod.TYPE_DICE)) |
||
100 | |||
101 | # custom listener |
||
102 | print ('***** Custom listener *****') |
||
103 | View Code Duplication | class MyListener: |
|
0 ignored issues
–
show
Duplication
introduced
by
![]() |
|||
104 | def new_struct(self, struct, name): |
||
105 | print ('new structure type', libtcod.struct_get_name(struct), \ |
||
106 | ' named ', name ) |
||
107 | return True |
||
108 | def new_flag(self, name): |
||
109 | print ('new flag named ', name) |
||
110 | return True |
||
111 | def new_property(self,name, typ, value): |
||
112 | type_names = ['NONE', 'BOOL', 'CHAR', 'INT', 'FLOAT', 'STRING', \ |
||
113 | 'COLOR', 'DICE'] |
||
114 | type_name = type_names[typ & 0xff] |
||
115 | if typ & libtcod.TYPE_LIST: |
||
116 | type_name = 'LIST<%s>' % type_name |
||
117 | print ('new property named ', name,' type ',type_name, \ |
||
118 | ' value ', value) |
||
119 | return True |
||
120 | def end_struct(self, struct, name): |
||
121 | print ('end structure type', libtcod.struct_get_name(struct), \ |
||
122 | ' named ', name) |
||
123 | return True |
||
124 | def error(self,msg): |
||
125 | print ('error : ', msg) |
||
126 | return True |
||
127 | libtcod.parser_run(parser, os.path.join(b'data',b'cfg',b'sample.cfg'), MyListener()) |
||
128 | ############################################# |
||
129 | # end of parser unit test |
||
130 | ############################################# |
||
131 | |||
132 | ############################################# |
||
133 | # true color sample |
||
134 | ############################################# |
||
135 | tc_cols = [libtcod.Color(50, 40, 150), |
||
136 | libtcod.Color(240, 85, 5), |
||
137 | libtcod.Color(50, 35, 240), |
||
138 | libtcod.Color(10, 200, 130), |
||
139 | ] |
||
140 | tc_dirr = [1, -1, 1, 1] |
||
141 | tc_dirg = [1, -1, -1, 1] |
||
142 | tc_dirb = [1, 1, 1, -1] |
||
143 | def render_colors(first, key, mouse): |
||
144 | global tc_cols, tc_dirr, tc_dirg, tc_dirb, tc_fast |
||
145 | |||
146 | TOPLEFT = 0 |
||
147 | TOPRIGHT = 1 |
||
148 | BOTTOMLEFT = 2 |
||
149 | BOTTOMRIGHT = 3 |
||
150 | if first: |
||
151 | libtcod.sys_set_fps(0) |
||
152 | libtcod.console_clear(sample_console) |
||
153 | tc_fast = False |
||
154 | for c in range(4): |
||
155 | # move each corner color |
||
156 | component=libtcod.random_get_int(None, 0, 2) |
||
157 | if component == 0: |
||
158 | tc_cols[c].r += 5 * tc_dirr[c] |
||
159 | if tc_cols[c].r == 255: |
||
160 | tc_dirr[c] = -1 |
||
161 | elif tc_cols[c].r == 0: |
||
162 | tc_dirr[c] = 1 |
||
163 | elif component == 1: |
||
164 | tc_cols[c].g += 5 * tc_dirg[c] |
||
165 | if tc_cols[c].g == 255: |
||
166 | tc_dirg[c] = -1 |
||
167 | elif tc_cols[c].g == 0: |
||
168 | tc_dirg[c] = 1 |
||
169 | elif component == 2: |
||
170 | tc_cols[c].b += 5 * tc_dirb[c] |
||
171 | if tc_cols[c].b == 255: |
||
172 | tc_dirb[c] = -1 |
||
173 | elif tc_cols[c].b == 0: |
||
174 | tc_dirb[c] = 1 |
||
175 | |||
176 | if not tc_fast: |
||
177 | # interpolate corner colors |
||
178 | for x in range(SAMPLE_SCREEN_WIDTH): |
||
179 | xcoef = float(x) / (SAMPLE_SCREEN_WIDTH - 1) |
||
180 | top = libtcod.color_lerp(tc_cols[TOPLEFT], tc_cols[TOPRIGHT], xcoef) |
||
181 | bottom = libtcod.color_lerp(tc_cols[BOTTOMLEFT], tc_cols[BOTTOMRIGHT], |
||
182 | xcoef) |
||
183 | for y in range(SAMPLE_SCREEN_HEIGHT): |
||
184 | ycoef = float(y) / (SAMPLE_SCREEN_HEIGHT - 1) |
||
185 | curColor = libtcod.color_lerp(top, bottom, ycoef) |
||
186 | libtcod.console_set_char_background(sample_console, x, y, curColor, |
||
187 | libtcod.BKGND_SET) |
||
188 | textColor = libtcod.console_get_char_background(sample_console, |
||
189 | SAMPLE_SCREEN_WIDTH // 2, 5) |
||
190 | textColor.r = 255 - textColor.r |
||
191 | textColor.g = 255 - textColor.g |
||
192 | textColor.b = 255 - textColor.b |
||
193 | libtcod.console_set_default_foreground(sample_console, textColor) |
||
194 | for x in range(SAMPLE_SCREEN_WIDTH): |
||
195 | for y in range(SAMPLE_SCREEN_HEIGHT): |
||
196 | col = libtcod.console_get_char_background(sample_console, x, y) |
||
197 | col = libtcod.color_lerp(col, libtcod.black, 0.5) |
||
198 | c = libtcod.random_get_int(None, ord('a'), ord('z')) |
||
199 | libtcod.console_set_default_foreground(sample_console, col) |
||
200 | libtcod.console_put_char(sample_console, x, y, c, |
||
201 | libtcod.BKGND_NONE) |
||
202 | else: |
||
203 | # same, but using the ConsoleBuffer class to speed up rendering |
||
204 | buffer = libtcod.ConsoleBuffer(SAMPLE_SCREEN_WIDTH, SAMPLE_SCREEN_HEIGHT) # initialize buffer |
||
205 | c = libtcod.random_get_int(None, ord('a'), ord('z')) |
||
206 | for x in range(SAMPLE_SCREEN_WIDTH): |
||
207 | xcoef = float(x) / (SAMPLE_SCREEN_WIDTH - 1) |
||
208 | top = libtcod.color_lerp(tc_cols[TOPLEFT], tc_cols[TOPRIGHT], xcoef) |
||
209 | bottom = libtcod.color_lerp(tc_cols[BOTTOMLEFT], tc_cols[BOTTOMRIGHT], xcoef) |
||
210 | for y in range(SAMPLE_SCREEN_HEIGHT): |
||
211 | # for maximum speed, we avoid using any libtcod function in |
||
212 | # this inner loop, except for the ConsoleBuffer's functions. |
||
213 | ycoef = float(y) / (SAMPLE_SCREEN_HEIGHT - 1) |
||
214 | r = int(top.r * ycoef + bottom.r * (1 - ycoef)) |
||
215 | g = int(top.g * ycoef + bottom.g * (1 - ycoef)) |
||
216 | b = int(top.b * ycoef + bottom.b * (1 - ycoef)) |
||
217 | c += 1 |
||
218 | if c > ord('z'): c = ord('a') |
||
219 | # set background, foreground and char with a single function |
||
220 | buffer.set(x, y, r, g, b, r // 2, g // 2, b // 2, chr(c)) |
||
221 | buffer.blit(sample_console) # update console with the buffer's contents |
||
222 | libtcod.console_set_default_foreground(sample_console, libtcod.Color(int(r), int(g), int(b))) |
||
223 | |||
224 | libtcod.console_set_default_background(sample_console, libtcod.grey) |
||
225 | libtcod.console_print_rect_ex(sample_console, SAMPLE_SCREEN_WIDTH // 2, |
||
226 | 5, SAMPLE_SCREEN_WIDTH - 2, |
||
227 | SAMPLE_SCREEN_HEIGHT - 1, |
||
228 | libtcod.BKGND_MULTIPLY, libtcod.CENTER, |
||
229 | "The Doryen library uses 24 bits " |
||
230 | "colors, for both background and " |
||
231 | "foreground.") |
||
232 | |||
233 | if key.c == ord('f'): tc_fast = not tc_fast |
||
234 | libtcod.console_set_default_foreground(sample_console, libtcod.white) |
||
235 | libtcod.console_print(sample_console, 1, SAMPLE_SCREEN_HEIGHT - 2, |
||
236 | "F : turn fast rendering %s" % ("off" if tc_fast else "on")) |
||
237 | |||
238 | ############################################# |
||
239 | # offscreen console sample |
||
240 | ############################################# |
||
241 | oc_secondary = None |
||
242 | oc_screenshot = None |
||
243 | oc_counter = 0 |
||
244 | oc_x = 0 |
||
245 | oc_y = 0 |
||
246 | oc_init = False |
||
247 | oc_xdir = 1 |
||
248 | oc_ydir = 1 |
||
249 | def render_offscreen(first, key, mouse): |
||
250 | global oc_secondary, oc_screenshot |
||
251 | global oc_counter, oc_x, oc_y, oc_init, oc_xdir, oc_ydir |
||
252 | |||
253 | if not oc_init: |
||
254 | oc_init = True |
||
255 | oc_secondary = libtcod.console_new(SAMPLE_SCREEN_WIDTH // 2, |
||
256 | SAMPLE_SCREEN_HEIGHT // 2) |
||
257 | oc_screenshot = libtcod.console_new(SAMPLE_SCREEN_WIDTH, |
||
258 | SAMPLE_SCREEN_HEIGHT) |
||
259 | libtcod.console_print_frame(oc_secondary, 0, 0, SAMPLE_SCREEN_WIDTH // 2, |
||
260 | SAMPLE_SCREEN_HEIGHT // 2, False, libtcod.BKGND_NONE, |
||
261 | b'Offscreen console') |
||
262 | libtcod.console_print_rect_ex(oc_secondary, SAMPLE_SCREEN_WIDTH // 4, |
||
263 | 2, SAMPLE_SCREEN_WIDTH // 2 - 2, |
||
264 | SAMPLE_SCREEN_HEIGHT // 2, |
||
265 | libtcod.BKGND_NONE, libtcod.CENTER, |
||
266 | b"You can render to an offscreen " |
||
267 | b"console and blit in on another " |
||
268 | b"one, simulating alpha " |
||
269 | b"transparency.") |
||
270 | if first: |
||
271 | libtcod.sys_set_fps(30) |
||
272 | # get a "screenshot" of the current sample screen |
||
273 | libtcod.console_blit(sample_console, 0, 0, SAMPLE_SCREEN_WIDTH, |
||
274 | SAMPLE_SCREEN_HEIGHT, oc_screenshot, 0, 0) |
||
275 | oc_counter += 1 |
||
276 | if oc_counter % 20 == 0: |
||
277 | oc_x += oc_xdir |
||
278 | oc_y += oc_ydir |
||
279 | if oc_x == SAMPLE_SCREEN_WIDTH / 2 + 5: |
||
280 | oc_xdir = -1 |
||
281 | elif oc_x == -5: |
||
282 | oc_xdir = 1 |
||
283 | if oc_y == SAMPLE_SCREEN_HEIGHT / 2 + 5: |
||
284 | oc_ydir = -1 |
||
285 | elif oc_y == -5: |
||
286 | oc_ydir = 1 |
||
287 | libtcod.console_blit(oc_screenshot, 0, 0, SAMPLE_SCREEN_WIDTH, |
||
288 | SAMPLE_SCREEN_HEIGHT, sample_console, 0, 0) |
||
289 | libtcod.console_blit(oc_secondary, 0, 0, SAMPLE_SCREEN_WIDTH // 2, |
||
290 | SAMPLE_SCREEN_HEIGHT // 2, sample_console, oc_x, oc_y, |
||
291 | 1.0,0.75) |
||
292 | |||
293 | ############################################# |
||
294 | # line drawing sample |
||
295 | ############################################# |
||
296 | line_bk = libtcod.Color() |
||
297 | line_init = False |
||
298 | line_bk_flag = libtcod.BKGND_SET |
||
299 | |||
300 | def render_lines(first, key, mouse): |
||
301 | global line_bk, line_init, line_bk_flag |
||
302 | |||
303 | flag_names=['BKGND_NONE', |
||
304 | 'BKGND_SET', |
||
305 | 'BKGND_MULTIPLY', |
||
306 | 'BKGND_LIGHTEN', |
||
307 | 'BKGND_DARKEN', |
||
308 | 'BKGND_SCREEN', |
||
309 | 'BKGND_COLOR_DODGE', |
||
310 | 'BKGND_COLOR_BURN', |
||
311 | 'BKGND_ADD', |
||
312 | 'BKGND_ADDALPHA', |
||
313 | 'BKGND_BURN', |
||
314 | 'BKGND_OVERLAY', |
||
315 | 'BKGND_ALPHA', |
||
316 | ] |
||
317 | if key.vk in (libtcod.KEY_ENTER, libtcod.KEY_KPENTER): |
||
318 | line_bk_flag += 1 |
||
319 | if (line_bk_flag & 0xff) > libtcod.BKGND_ALPH: |
||
320 | line_bk_flag=libtcod.BKGND_NONE |
||
321 | alpha = 0.0 |
||
322 | if (line_bk_flag & 0xff) == libtcod.BKGND_ALPH: |
||
323 | # for the alpha mode, update alpha every frame |
||
324 | alpha = (1.0 + math.cos(libtcod.sys_elapsed_seconds() * 2)) / 2.0 |
||
325 | line_bk_flag = libtcod.BKGND_ALPHA(alpha) |
||
326 | elif (line_bk_flag & 0xff) == libtcod.BKGND_ADDA: |
||
327 | # for the add alpha mode, update alpha every frame |
||
328 | alpha = (1.0 + math.cos(libtcod.sys_elapsed_seconds() * 2)) / 2.0 |
||
329 | line_bk_flag = libtcod.BKGND_ADDALPHA(alpha) |
||
330 | if not line_init: |
||
331 | line_bk = libtcod.console_new(SAMPLE_SCREEN_WIDTH, SAMPLE_SCREEN_HEIGHT) |
||
332 | # initialize the colored background |
||
333 | for x in range(SAMPLE_SCREEN_WIDTH): |
||
334 | for y in range(SAMPLE_SCREEN_HEIGHT): |
||
335 | col = libtcod.Color(x * 255 // (SAMPLE_SCREEN_WIDTH - 1), |
||
336 | (x + y) * 255 // (SAMPLE_SCREEN_WIDTH - 1 + |
||
337 | SAMPLE_SCREEN_HEIGHT - 1), |
||
338 | y * 255 // (SAMPLE_SCREEN_HEIGHT-1)) |
||
339 | libtcod.console_set_char_background(line_bk, x, y, col, libtcod.BKGND_SET) |
||
340 | line_init = True |
||
341 | if first: |
||
342 | libtcod.sys_set_fps(30) |
||
343 | libtcod.console_set_default_foreground(sample_console, libtcod.white) |
||
344 | libtcod.console_blit(line_bk, 0, 0, SAMPLE_SCREEN_WIDTH, |
||
345 | SAMPLE_SCREEN_HEIGHT, sample_console, 0, 0) |
||
346 | recty = int((SAMPLE_SCREEN_HEIGHT - 2) * ((1.0 + |
||
347 | math.cos(libtcod.sys_elapsed_seconds())) / 2.0)) |
||
348 | for x in range(SAMPLE_SCREEN_WIDTH): |
||
349 | col = libtcod.Color(x * 255 // SAMPLE_SCREEN_WIDTH, |
||
350 | x * 255 // SAMPLE_SCREEN_WIDTH, |
||
351 | x * 255 // SAMPLE_SCREEN_WIDTH) |
||
352 | libtcod.console_set_char_background(sample_console, x, recty, col, line_bk_flag) |
||
353 | libtcod.console_set_char_background(sample_console, x, recty + 1, col, |
||
354 | line_bk_flag) |
||
355 | libtcod.console_set_char_background(sample_console, x, recty + 2, col, |
||
356 | line_bk_flag) |
||
357 | angle = libtcod.sys_elapsed_seconds() * 2.0 |
||
358 | cos_angle=math.cos(angle) |
||
359 | sin_angle=math.sin(angle) |
||
360 | xo = int(SAMPLE_SCREEN_WIDTH // 2 * (1 + cos_angle)) |
||
361 | yo = int(SAMPLE_SCREEN_HEIGHT // 2 + sin_angle * SAMPLE_SCREEN_WIDTH // 2) |
||
362 | xd = int(SAMPLE_SCREEN_WIDTH // 2 * (1 - cos_angle)) |
||
363 | yd = int(SAMPLE_SCREEN_HEIGHT // 2 - sin_angle * SAMPLE_SCREEN_WIDTH // 2) |
||
364 | # draw the line |
||
365 | # in python the easiest way is to use the line iterator |
||
366 | for x,y in libtcod.line_iter(xo, yo, xd, yd): |
||
367 | if 0 <= x < SAMPLE_SCREEN_WIDTH and \ |
||
368 | 0 <= y < SAMPLE_SCREEN_HEIGHT: |
||
369 | libtcod.console_set_char_background(sample_console, x, y, |
||
370 | libtcod.light_blue, line_bk_flag) |
||
371 | libtcod.console_print(sample_console, 2, 2, |
||
372 | '%s (ENTER to change)' % |
||
373 | flag_names[line_bk_flag & 0xff]) |
||
374 | |||
375 | ############################################# |
||
376 | # noise sample |
||
377 | ############################################# |
||
378 | noise_func = 0 |
||
379 | noise_dx = 0.0 |
||
380 | noise_dy = 0.0 |
||
381 | noise_octaves = 4.0 |
||
382 | noise_zoom = 3.0 |
||
383 | noise_hurst = libtcod.NOISE_DEFAULT_HURST |
||
384 | noise_lacunarity = libtcod.NOISE_DEFAULT_LACUNARITY |
||
385 | noise = libtcod.noise_new(2) |
||
386 | noise_img=libtcod.image_new(SAMPLE_SCREEN_WIDTH*2,SAMPLE_SCREEN_HEIGHT*2) |
||
387 | def render_noise(first, key, mouse): |
||
388 | global noise_func, noise_img |
||
389 | global noise_dx, noise_dy |
||
390 | global noise_octaves, noise_zoom, noise_hurst, noise_lacunarity, noise |
||
391 | |||
392 | PERLIN = 0 |
||
393 | SIMPLEX = 1 |
||
394 | WAVELET = 2 |
||
395 | FBM_PERLIN = 3 |
||
396 | TURBULENCE_PERLIN = 4 |
||
397 | FBM_SIMPLEX = 5 |
||
398 | TURBULENCE_SIMPLEX = 6 |
||
399 | FBM_WAVELET = 7 |
||
400 | TURBULENCE_WAVELET = 8 |
||
401 | funcName=[ |
||
402 | '1 : perlin noise ', |
||
403 | '2 : simplex noise ', |
||
404 | '3 : wavelet noise ', |
||
405 | '4 : perlin fbm ', |
||
406 | '5 : perlin turbulence ', |
||
407 | '6 : simplex fbm ', |
||
408 | '7 : simplex turbulence ', |
||
409 | '8 : wavelet fbm ', |
||
410 | '9 : wavelet turbulence ', |
||
411 | ] |
||
412 | if first: |
||
413 | libtcod.sys_set_fps(30) |
||
414 | libtcod.console_clear(sample_console) |
||
415 | noise_dx += 0.01 |
||
416 | noise_dy += 0.01 |
||
417 | for y in range(2*SAMPLE_SCREEN_HEIGHT): |
||
418 | for x in range(2*SAMPLE_SCREEN_WIDTH): |
||
419 | f = [noise_zoom * x / (2*SAMPLE_SCREEN_WIDTH) + noise_dx, |
||
420 | noise_zoom * y / (2*SAMPLE_SCREEN_HEIGHT) + noise_dy] |
||
421 | value = 0.0 |
||
422 | if noise_func == PERLIN: |
||
423 | value = libtcod.noise_get(noise, f, libtcod.NOISE_PERLIN) |
||
424 | elif noise_func == SIMPLEX: |
||
425 | value = libtcod.noise_get(noise, f, libtcod.NOISE_SIMPLEX) |
||
426 | elif noise_func == WAVELET: |
||
427 | value = libtcod.noise_get(noise, f, libtcod.NOISE_WAVELET) |
||
428 | elif noise_func == FBM_PERLIN: |
||
429 | value = libtcod.noise_get_fbm(noise, f, noise_octaves, libtcod.NOISE_PERLIN) |
||
430 | elif noise_func == TURBULENCE_PERLIN: |
||
431 | value = libtcod.noise_get_turbulence(noise, f, noise_octaves, libtcod.NOISE_PERLIN) |
||
432 | elif noise_func == FBM_SIMPLEX: |
||
433 | value = libtcod.noise_get_fbm(noise, f, noise_octaves, libtcod.NOISE_SIMPLEX) |
||
434 | elif noise_func == TURBULENCE_SIMPLEX: |
||
435 | value = libtcod.noise_get_turbulence(noise, f, |
||
436 | noise_octaves, libtcod.NOISE_SIMPLEX) |
||
437 | elif noise_func == FBM_WAVELET: |
||
438 | value = libtcod.noise_get_fbm(noise, f, noise_octaves, libtcod.NOISE_WAVELET) |
||
439 | elif noise_func == TURBULENCE_WAVELET: |
||
440 | value = libtcod.noise_get_turbulence(noise, f, |
||
441 | noise_octaves, libtcod.NOISE_WAVELET) |
||
442 | c = int((value + 1.0) / 2.0 * 255) |
||
443 | if c < 0: |
||
444 | c = 0 |
||
445 | elif c > 255: |
||
446 | c = 255 |
||
447 | col = libtcod.Color(c // 2, c // 2, c) |
||
448 | libtcod.image_put_pixel(noise_img,x,y,col) |
||
449 | libtcod.console_set_default_background(sample_console, libtcod.grey) |
||
450 | rectw = 24 |
||
451 | recth = 13 |
||
452 | if noise_func <= WAVELET: |
||
453 | recth = 10 |
||
454 | libtcod.image_blit_2x(noise_img,sample_console,0,0) |
||
455 | libtcod.console_rect(sample_console, 2, 2, rectw, recth, False, |
||
456 | libtcod.BKGND_MULTIPLY) |
||
457 | for y in range(2,2+recth): |
||
458 | for x in range(2,2+rectw): |
||
459 | col=libtcod.console_get_char_foreground(sample_console,x,y) |
||
460 | col = col * libtcod.grey |
||
461 | libtcod.console_set_char_foreground(sample_console,x,y,col) |
||
462 | |||
463 | for curfunc in range(TURBULENCE_WAVELET + 1): |
||
464 | if curfunc == noise_func: |
||
465 | libtcod.console_set_default_foreground(sample_console, libtcod.white) |
||
466 | libtcod.console_set_default_background(sample_console, |
||
467 | libtcod.light_blue) |
||
468 | libtcod.console_print_ex(sample_console, 2, 2 + curfunc, |
||
469 | libtcod.BKGND_SET, libtcod.LEFT, funcName[curfunc]) |
||
470 | else: |
||
471 | libtcod.console_set_default_foreground(sample_console, libtcod.grey) |
||
472 | libtcod.console_print(sample_console, 2, 2 + curfunc, |
||
473 | funcName[curfunc]) |
||
474 | libtcod.console_set_default_foreground(sample_console, libtcod.white) |
||
475 | libtcod.console_print(sample_console, 2, 11, |
||
476 | 'Y/H : zoom (%2.1f)' % noise_zoom) |
||
477 | if noise_func > WAVELET: |
||
478 | libtcod.console_print(sample_console, 2, 12, |
||
479 | 'E/D : hurst (%2.1f)' % noise_hurst) |
||
480 | libtcod.console_print(sample_console, 2, 13, |
||
481 | 'R/F : lacunarity (%2.1f)' % |
||
482 | noise_lacunarity) |
||
483 | libtcod.console_print(sample_console, 2, 14, |
||
484 | 'T/G : octaves (%2.1f)' % noise_octaves) |
||
485 | if key.vk == libtcod.KEY_NONE: |
||
486 | return |
||
487 | if ord('9') >= key.c >= ord('1'): |
||
488 | noise_func = key.c - ord('1') |
||
489 | elif key.c in (ord('E'), ord('e')): |
||
490 | noise_hurst += 0.1 |
||
491 | libtcod.noise_delete(noise) |
||
492 | noise = libtcod.noise_new(2,noise_hurst,noise_lacunarity) |
||
493 | elif key.c in (ord('D'), ord('d')): |
||
494 | noise_hurst -= 0.1 |
||
495 | libtcod.noise_delete(noise) |
||
496 | noise = libtcod.noise_new(2, noise_hurst, noise_lacunarity) |
||
497 | elif key.c in (ord('R'), ord('r')): |
||
498 | noise_lacunarity += 0.5 |
||
499 | libtcod.noise_delete(noise) |
||
500 | noise = libtcod.noise_new(2, noise_hurst, noise_lacunarity) |
||
501 | elif key.c in (ord('F'), ord('f')): |
||
502 | noise_lacunarity -= 0.5 |
||
503 | libtcod.noise_delete(noise) |
||
504 | noise = libtcod.noise_new(2, noise_hurst, noise_lacunarity) |
||
505 | elif key.c in (ord('T'), ord('t')): |
||
506 | noise_octaves += 0.5 |
||
507 | elif key.c in (ord('G'), ord('g')): |
||
508 | noise_octaves -= 0.5 |
||
509 | elif key.c in (ord('Y'), ord('y')): |
||
510 | noise_zoom += 0.2 |
||
511 | elif key.c in (ord('H'), ord('h')): |
||
512 | noise_zoom -= 0.2 |
||
513 | |||
514 | ############################################# |
||
515 | # field of view sample |
||
516 | ############################################# |
||
517 | fov_px = 20 |
||
518 | fov_py = 10 |
||
519 | fov_recompute = True |
||
520 | fov_torch = False |
||
521 | fov_map = None |
||
522 | fov_dark_wall = libtcod.Color(0, 0, 100) |
||
523 | fov_light_wall = libtcod.Color(130, 110, 50) |
||
524 | fov_dark_ground = libtcod.Color(50, 50, 150) |
||
525 | fov_light_ground = libtcod.Color(200, 180, 50) |
||
526 | fov_noise = None |
||
527 | fov_torchx = 0.0 |
||
528 | fov_init = False |
||
529 | fov_light_walls = True |
||
530 | fov_algo_num = 0 |
||
531 | fov_algo_names = ['BASIC ','DIAMOND ', 'SHADOW ', |
||
532 | 'PERMISSIVE0','PERMISSIVE1','PERMISSIVE2','PERMISSIVE3','PERMISSIVE4', |
||
533 | 'PERMISSIVE5','PERMISSIVE6','PERMISSIVE7','PERMISSIVE8','RESTRICTIVE'] |
||
534 | def render_fov(first, key, mouse): |
||
535 | global fov_px, fov_py, fov_map, fov_dark_wall, fov_light_wall |
||
536 | global fov_dark_ground, fov_light_ground |
||
537 | global fov_recompute, fov_torch, fov_noise, fov_torchx, fov_init |
||
538 | global fov_light_walls, fov_algo_num, fov_algo_names |
||
539 | |||
540 | smap = ['##############################################', |
||
541 | '####################### #################', |
||
542 | '##################### # ###############', |
||
543 | '###################### ### ###########', |
||
544 | '################## ##### ####', |
||
545 | '################ ######## ###### ####', |
||
546 | '############### #################### ####', |
||
547 | '################ ###### ##', |
||
548 | '######## ####### ###### # # # ##', |
||
549 | '######## ###### ### ##', |
||
550 | '######## ##', |
||
551 | '#### ###### ### # # # ##', |
||
552 | '#### ### ########## #### ##', |
||
553 | '#### ### ########## ###########=##########', |
||
554 | '#### ################## ##### #####', |
||
555 | '#### ### #### ##### #####', |
||
556 | '#### # #### #####', |
||
557 | '######## # #### ##### #####', |
||
558 | '######## ##### ####################', |
||
559 | '##############################################', |
||
560 | ] |
||
561 | TORCH_RADIUS = 10 |
||
562 | SQUARED_TORCH_RADIUS = TORCH_RADIUS * TORCH_RADIUS |
||
563 | dx = 0.0 |
||
564 | dy = 0.0 |
||
565 | di = 0.0 |
||
566 | View Code Duplication | if not fov_init: |
|
0 ignored issues
–
show
|
|||
567 | fov_init = True |
||
568 | fov_map = libtcod.map_new(SAMPLE_SCREEN_WIDTH, SAMPLE_SCREEN_HEIGHT) |
||
569 | for y in range(SAMPLE_SCREEN_HEIGHT): |
||
570 | for x in range(SAMPLE_SCREEN_WIDTH): |
||
571 | if smap[y][x] == ' ': |
||
572 | # ground |
||
573 | libtcod.map_set_properties(fov_map, x, y, True, True) |
||
574 | elif smap[y][x] == '=': |
||
575 | # window |
||
576 | libtcod.map_set_properties(fov_map, x, y, True, False) |
||
577 | # 1d noise for the torch flickering |
||
578 | fov_noise = libtcod.noise_new(1, 1.0, 1.0) |
||
579 | torchs = 'off' |
||
580 | lights = 'off' |
||
581 | if fov_torch: |
||
582 | torchs = 'on ' |
||
583 | if fov_light_walls : |
||
584 | lights='on ' |
||
585 | View Code Duplication | if first: |
|
0 ignored issues
–
show
|
|||
586 | libtcod.sys_set_fps(30) |
||
587 | # we draw the foreground only the first time. |
||
588 | # during the player movement, only the @ is redrawn. |
||
589 | # the rest impacts only the background color |
||
590 | # draw the help text & player @ |
||
591 | libtcod.console_clear(sample_console) |
||
592 | libtcod.console_set_default_foreground(sample_console, libtcod.white) |
||
593 | libtcod.console_print(sample_console, 1, 1, |
||
594 | "IJKL : move around\nT : torch fx %s\nW : light walls %s\n+-: algo %s" % |
||
595 | (torchs,lights,fov_algo_names[fov_algo_num])) |
||
596 | libtcod.console_set_default_foreground(sample_console, libtcod.black) |
||
597 | libtcod.console_put_char(sample_console, fov_px, fov_py, '@', |
||
598 | libtcod.BKGND_NONE) |
||
599 | # draw windows |
||
600 | for y in range(SAMPLE_SCREEN_HEIGHT): |
||
601 | for x in range(SAMPLE_SCREEN_WIDTH): |
||
602 | if smap[y][x] == '=': |
||
603 | libtcod.console_put_char(sample_console, x, y, |
||
604 | libtcod.CHAR_DHLINE, |
||
605 | libtcod.BKGND_NONE) |
||
606 | if fov_recompute: |
||
607 | fov_recompute = False |
||
608 | if fov_torch: |
||
609 | libtcod.map_compute_fov(fov_map, fov_px, fov_py, TORCH_RADIUS, fov_light_walls, fov_algo_num) |
||
610 | else: |
||
611 | libtcod.map_compute_fov(fov_map, fov_px, fov_py, 0, fov_light_walls, fov_algo_num) |
||
612 | if fov_torch: |
||
613 | # slightly change the perlin noise parameter |
||
614 | fov_torchx += 0.2 |
||
615 | # randomize the light position between -1.5 and 1.5 |
||
616 | tdx = [fov_torchx + 20.0] |
||
617 | dx = libtcod.noise_get(noise, tdx, libtcod.NOISE_SIMPLEX) * 1.5 |
||
618 | tdx[0] += 30.0 |
||
619 | dy = libtcod.noise_get(noise, tdx, libtcod.NOISE_SIMPLEX) * 1.5 |
||
620 | di = 0.2 * libtcod.noise_get(noise, [fov_torchx], libtcod.NOISE_SIMPLEX) |
||
621 | for y in range(SAMPLE_SCREEN_HEIGHT): |
||
622 | for x in range(SAMPLE_SCREEN_WIDTH): |
||
623 | visible = libtcod.map_is_in_fov(fov_map, x, y) |
||
624 | wall = (smap[y][x] == '#') |
||
625 | if not visible: |
||
626 | if wall: |
||
627 | libtcod.console_set_char_background(sample_console, x, y, |
||
628 | fov_dark_wall, libtcod.BKGND_SET) |
||
629 | else: |
||
630 | libtcod.console_set_char_background(sample_console, x, y, |
||
631 | fov_dark_ground, |
||
632 | libtcod.BKGND_SET) |
||
633 | else: |
||
634 | if not fov_torch: |
||
635 | if wall: |
||
636 | libtcod.console_set_char_background(sample_console, x, y, |
||
637 | fov_light_wall, |
||
638 | libtcod.BKGND_SET ) |
||
639 | else: |
||
640 | libtcod.console_set_char_background(sample_console, x, y, |
||
641 | fov_light_ground, |
||
642 | libtcod.BKGND_SET ) |
||
643 | else: |
||
644 | if wall: |
||
645 | base = fov_dark_wall |
||
646 | light = fov_light_wall |
||
647 | else: |
||
648 | base = fov_dark_ground |
||
649 | light = fov_light_ground |
||
650 | # cell distance to torch (squared) |
||
651 | r = float(x - fov_px + dx) * (x - fov_px + dx) + \ |
||
652 | (y - fov_py + dy) * (y - fov_py + dy) |
||
653 | if r < SQUARED_TORCH_RADIUS: |
||
654 | l = (SQUARED_TORCH_RADIUS - r) / SQUARED_TORCH_RADIUS \ |
||
655 | + di |
||
656 | if l < 0.0: |
||
657 | l = 0.0 |
||
658 | elif l> 1.0: |
||
659 | l = 1.0 |
||
660 | base = libtcod.color_lerp(base, light, l) |
||
661 | libtcod.console_set_char_background(sample_console, x, y, base, |
||
662 | libtcod.BKGND_SET) |
||
663 | if key.c in (ord('I'), ord('i')): |
||
664 | if smap[fov_py-1][fov_px] == ' ': |
||
665 | libtcod.console_put_char(sample_console, fov_px, fov_py, ' ', |
||
666 | libtcod.BKGND_NONE) |
||
667 | fov_py -= 1 |
||
668 | libtcod.console_put_char(sample_console, fov_px, fov_py, '@', |
||
669 | libtcod.BKGND_NONE) |
||
670 | fov_recompute = True |
||
671 | elif key.c in (ord('K'), ord('k')): |
||
672 | if smap[fov_py+1][fov_px] == ' ': |
||
673 | libtcod.console_put_char(sample_console, fov_px, fov_py, ' ', |
||
674 | libtcod.BKGND_NONE) |
||
675 | fov_py += 1 |
||
676 | libtcod.console_put_char(sample_console, fov_px, fov_py, '@', |
||
677 | libtcod.BKGND_NONE) |
||
678 | fov_recompute = True |
||
679 | elif key.c in (ord('J'), ord('j')): |
||
680 | if smap[fov_py][fov_px-1] == ' ': |
||
681 | libtcod.console_put_char(sample_console, fov_px, fov_py, ' ', |
||
682 | libtcod.BKGND_NONE) |
||
683 | fov_px -= 1 |
||
684 | libtcod.console_put_char(sample_console, fov_px, fov_py, '@', |
||
685 | libtcod.BKGND_NONE) |
||
686 | fov_recompute = True |
||
687 | elif key.c in (ord('L'), ord('l')): |
||
688 | if smap[fov_py][fov_px+1] == ' ': |
||
689 | libtcod.console_put_char(sample_console, fov_px, fov_py, ' ', |
||
690 | libtcod.BKGND_NONE) |
||
691 | fov_px += 1 |
||
692 | libtcod.console_put_char(sample_console, fov_px, fov_py, '@', |
||
693 | libtcod.BKGND_NONE) |
||
694 | fov_recompute = True |
||
695 | elif key.c in (ord('T'), ord('t')): |
||
696 | fov_torch = not fov_torch |
||
697 | libtcod.console_set_default_foreground(sample_console, libtcod.white) |
||
698 | libtcod.console_print(sample_console, 1, 1, |
||
699 | "IJKL : move around\nT : torch fx %s\nW : light walls %s\n+-: algo %s" % |
||
700 | (torchs,lights,fov_algo_names[fov_algo_num])) |
||
701 | libtcod.console_set_default_foreground(sample_console, libtcod.black) |
||
702 | elif key.c in (ord('W'), ord('w')): |
||
703 | fov_light_walls = not fov_light_walls |
||
704 | libtcod.console_set_default_foreground(sample_console, libtcod.white) |
||
705 | libtcod.console_print(sample_console, 1, 1, |
||
706 | "IJKL : move around\nT : torch fx %s\nW : light walls %s\n+-: algo %s" % |
||
707 | (torchs,lights,fov_algo_names[fov_algo_num])) |
||
708 | libtcod.console_set_default_foreground(sample_console, libtcod.black) |
||
709 | fov_recompute = True |
||
710 | elif key.c in (ord('+'), ord('-')): |
||
711 | if key.c == ord('+') and fov_algo_num < libtcod.NB_FOV_ALGORITHMS-1: |
||
712 | fov_algo_num = fov_algo_num + 1 |
||
713 | elif fov_algo_num > 0 : |
||
714 | fov_algo_num = fov_algo_num - 1 |
||
715 | libtcod.console_set_default_foreground(sample_console, libtcod.white) |
||
716 | libtcod.console_print(sample_console, 1, 1, |
||
717 | "IJKL : move around\nT : torch fx %s\nW : light walls %s\n+-: algo %s" % |
||
718 | (torchs,lights,fov_algo_names[fov_algo_num])) |
||
719 | libtcod.console_set_default_foreground(sample_console, libtcod.black) |
||
720 | fov_recompute = True |
||
721 | |||
722 | ############################################# |
||
723 | # pathfinding sample |
||
724 | ############################################# |
||
725 | path_px = 20 |
||
726 | path_py = 10 |
||
727 | path_dx = 24 |
||
728 | path_dy = 1 |
||
729 | path_map = None |
||
730 | path = None |
||
731 | path_dijk_dist = 0.0 |
||
732 | path_using_astar = True |
||
733 | path_dijk = None |
||
734 | path_recalculate = False |
||
735 | path_busy = 0.0 |
||
736 | path_oldchar = ' ' |
||
737 | path_init = False |
||
738 | def render_path(first, key, mouse): |
||
739 | global path_px, path_py, path_dx, path_dy, path_map, path, path_busy |
||
740 | global path_oldchar, path_init, path_recalculate |
||
741 | global path_dijk_dist, path_using_astar, path_dijk |
||
742 | |||
743 | smap = ['##############################################', |
||
744 | '####################### #################', |
||
745 | '##################### # ###############', |
||
746 | '###################### ### ###########', |
||
747 | '################## ##### ####', |
||
748 | '################ ######## ###### ####', |
||
749 | '############### #################### ####', |
||
750 | '################ ###### ##', |
||
751 | '######## ####### ###### # # # ##', |
||
752 | '######## ###### ### ##', |
||
753 | '######## ##', |
||
754 | '#### ###### ### # # # ##', |
||
755 | '#### ### ########## #### ##', |
||
756 | '#### ### ########## ###########=##########', |
||
757 | '#### ################## ##### #####', |
||
758 | '#### ### #### ##### #####', |
||
759 | '#### # #### #####', |
||
760 | '######## # #### ##### #####', |
||
761 | '######## ##### ####################', |
||
762 | '##############################################', |
||
763 | ] |
||
764 | TORCH_RADIUS = 10.0 |
||
765 | SQUARED_TORCH_RADIUS = TORCH_RADIUS * TORCH_RADIUS |
||
766 | View Code Duplication | if not path_init: |
|
0 ignored issues
–
show
|
|||
767 | path_init = True |
||
768 | path_map = libtcod.map_new(SAMPLE_SCREEN_WIDTH, SAMPLE_SCREEN_HEIGHT) |
||
769 | for y in range(SAMPLE_SCREEN_HEIGHT): |
||
770 | for x in range(SAMPLE_SCREEN_WIDTH): |
||
771 | if smap[y][x] == ' ': |
||
772 | # ground |
||
773 | libtcod.map_set_properties(path_map, x, y, True, True) |
||
774 | elif smap[y][x] == '=': |
||
775 | # window |
||
776 | libtcod.map_set_properties(path_map, x, y, True, False) |
||
777 | path = libtcod.path_new_using_map(path_map) |
||
778 | path_dijk = libtcod.dijkstra_new(path_map) |
||
779 | View Code Duplication | if first: |
|
0 ignored issues
–
show
|
|||
780 | libtcod.sys_set_fps(30) |
||
781 | # we draw the foreground only the first time. |
||
782 | # during the player movement, only the @ is redrawn. |
||
783 | # the rest impacts only the background color |
||
784 | # draw the help text & player @ |
||
785 | libtcod.console_clear(sample_console) |
||
786 | libtcod.console_set_default_foreground(sample_console, libtcod.white) |
||
787 | libtcod.console_put_char(sample_console, path_dx, path_dy, '+', |
||
788 | libtcod.BKGND_NONE) |
||
789 | libtcod.console_put_char(sample_console, path_px, path_py, '@', |
||
790 | libtcod.BKGND_NONE) |
||
791 | libtcod.console_print(sample_console, 1, 1, |
||
792 | "IJKL / mouse :\nmove destination\nTAB : A*/dijkstra") |
||
793 | libtcod.console_print(sample_console, 1, 4, |
||
794 | "Using : A*") |
||
795 | # draw windows |
||
796 | for y in range(SAMPLE_SCREEN_HEIGHT): |
||
797 | for x in range(SAMPLE_SCREEN_WIDTH): |
||
798 | if smap[y][x] == '=': |
||
799 | libtcod.console_put_char(sample_console, x, y, |
||
800 | libtcod.CHAR_DHLINE, |
||
801 | libtcod.BKGND_NONE) |
||
802 | path_recalculate = True |
||
803 | if path_recalculate: |
||
804 | if path_using_astar : |
||
805 | libtcod.path_compute(path, path_px, path_py, path_dx, path_dy) |
||
806 | else: |
||
807 | path_dijk_dist = 0.0 |
||
808 | # compute dijkstra grid (distance from px,py) |
||
809 | libtcod.dijkstra_compute(path_dijk,path_px,path_py) |
||
810 | # get the maximum distance (needed for rendering) |
||
811 | for y in range(SAMPLE_SCREEN_HEIGHT): |
||
812 | for x in range(SAMPLE_SCREEN_WIDTH): |
||
813 | d=libtcod.dijkstra_get_distance(path_dijk,x,y) |
||
814 | if d > path_dijk_dist: |
||
815 | path_dijk_dist=d |
||
816 | # compute path from px,py to dx,dy |
||
817 | libtcod.dijkstra_path_set(path_dijk,path_dx,path_dy) |
||
818 | path_recalculate = False |
||
819 | path_busy = 0.2 |
||
820 | # draw the dungeon |
||
821 | for y in range(SAMPLE_SCREEN_HEIGHT): |
||
822 | for x in range(SAMPLE_SCREEN_WIDTH): |
||
823 | if smap[y][x] == '#': |
||
824 | libtcod.console_set_char_background(sample_console, x, y, fov_dark_wall, |
||
825 | libtcod.BKGND_SET) |
||
826 | else: |
||
827 | libtcod.console_set_char_background(sample_console, x, y, fov_dark_ground, |
||
828 | libtcod.BKGND_SET) |
||
829 | # draw the path |
||
830 | View Code Duplication | if path_using_astar : |
|
0 ignored issues
–
show
|
|||
831 | for i in range(libtcod.path_size(path)): |
||
832 | x,y = libtcod.path_get(path, i) |
||
833 | libtcod.console_set_char_background(sample_console, x, y, |
||
834 | fov_light_ground, libtcod.BKGND_SET) |
||
835 | else: |
||
836 | for y in range(SAMPLE_SCREEN_HEIGHT): |
||
837 | for x in range(SAMPLE_SCREEN_WIDTH): |
||
838 | if smap[y][x] != '#': |
||
839 | libtcod.console_set_char_background(sample_console, x, y, libtcod.color_lerp(fov_light_ground,fov_dark_ground, |
||
840 | 0.9 * libtcod.dijkstra_get_distance(path_dijk,x,y) / path_dijk_dist), libtcod.BKGND_SET) |
||
841 | for i in range(libtcod.dijkstra_size(path_dijk)): |
||
842 | x,y=libtcod.dijkstra_get(path_dijk,i) |
||
843 | libtcod.console_set_char_background(sample_console,x,y,fov_light_ground, libtcod.BKGND_SET ) |
||
844 | |||
845 | # move the creature |
||
846 | path_busy -= libtcod.sys_get_last_frame_length() |
||
847 | if path_busy <= 0.0: |
||
848 | path_busy = 0.2 |
||
849 | if path_using_astar : |
||
850 | if not libtcod.path_is_empty(path): |
||
851 | libtcod.console_put_char(sample_console, path_px, path_py, ' ', |
||
852 | libtcod.BKGND_NONE) |
||
853 | path_px, path_py = libtcod.path_walk(path, True) |
||
854 | libtcod.console_put_char(sample_console, path_px, path_py, '@', |
||
855 | libtcod.BKGND_NONE) |
||
856 | else: |
||
857 | if not libtcod.dijkstra_is_empty(path_dijk): |
||
858 | libtcod.console_put_char(sample_console, path_px, path_py, ' ', |
||
859 | libtcod.BKGND_NONE) |
||
860 | path_px, path_py = libtcod.dijkstra_path_walk(path_dijk) |
||
861 | libtcod.console_put_char(sample_console, path_px, path_py, '@', |
||
862 | libtcod.BKGND_NONE) |
||
863 | path_recalculate = True |
||
864 | |||
865 | if key.c in (ord('I'), ord('i')) and path_dy > 0: |
||
866 | # destination move north |
||
867 | libtcod.console_put_char(sample_console, path_dx, path_dy, path_oldchar, |
||
868 | libtcod.BKGND_NONE) |
||
869 | path_dy -= 1 |
||
870 | path_oldchar = libtcod.console_get_char(sample_console, path_dx, |
||
871 | path_dy) |
||
872 | libtcod.console_put_char(sample_console, path_dx, path_dy, '+', |
||
873 | libtcod.BKGND_NONE) |
||
874 | if smap[path_dy][path_dx] == ' ': |
||
875 | path_recalculate = True |
||
876 | elif key.c in (ord('K'), ord('k')) and path_dy < SAMPLE_SCREEN_HEIGHT - 1: |
||
877 | # destination move south |
||
878 | libtcod.console_put_char(sample_console, path_dx, path_dy, path_oldchar, |
||
879 | libtcod.BKGND_NONE) |
||
880 | path_dy += 1 |
||
881 | path_oldchar = libtcod.console_get_char(sample_console, path_dx, |
||
882 | path_dy) |
||
883 | libtcod.console_put_char(sample_console, path_dx, path_dy, '+', |
||
884 | libtcod.BKGND_NONE) |
||
885 | if smap[path_dy][path_dx] == ' ': |
||
886 | path_recalculate = True |
||
887 | elif key.c in (ord('J'), ord('j')) and path_dx > 0: |
||
888 | # destination move west |
||
889 | libtcod.console_put_char(sample_console, path_dx, path_dy, path_oldchar, |
||
890 | libtcod.BKGND_NONE) |
||
891 | path_dx -= 1 |
||
892 | path_oldchar = libtcod.console_get_char(sample_console, path_dx, |
||
893 | path_dy) |
||
894 | libtcod.console_put_char(sample_console, path_dx, path_dy, '+', |
||
895 | libtcod.BKGND_NONE) |
||
896 | if smap[path_dy][path_dx] == ' ': |
||
897 | path_recalculate = True |
||
898 | elif key.c in (ord('L'), ord('l')) and path_dx < SAMPLE_SCREEN_WIDTH - 1: |
||
899 | # destination move east |
||
900 | libtcod.console_put_char(sample_console, path_dx, path_dy, path_oldchar, |
||
901 | libtcod.BKGND_NONE) |
||
902 | path_dx += 1 |
||
903 | path_oldchar = libtcod.console_get_char(sample_console, path_dx, |
||
904 | path_dy) |
||
905 | libtcod.console_put_char(sample_console, path_dx, path_dy, '+', |
||
906 | libtcod.BKGND_NONE) |
||
907 | if smap[path_dy][path_dx] == ' ': |
||
908 | path_recalculate = True |
||
909 | elif key.vk == libtcod.KEY_TAB: |
||
910 | path_using_astar = not path_using_astar |
||
911 | if path_using_astar : |
||
912 | libtcod.console_print(sample_console, 1, 4, |
||
913 | "Using : A* ") |
||
914 | else: |
||
915 | libtcod.console_print(sample_console, 1, 4, |
||
916 | "Using : Dijkstra") |
||
917 | path_recalculate=True |
||
918 | |||
919 | mx = mouse.cx - SAMPLE_SCREEN_X |
||
920 | my = mouse.cy - SAMPLE_SCREEN_Y |
||
921 | if 0 <= mx < SAMPLE_SCREEN_WIDTH and 0 <= my < SAMPLE_SCREEN_HEIGHT and \ |
||
922 | (path_dx != mx or path_dy != my): |
||
923 | libtcod.console_put_char(sample_console, path_dx, path_dy, path_oldchar, |
||
924 | libtcod.BKGND_NONE) |
||
925 | path_dx = mx |
||
926 | path_dy = my |
||
927 | path_oldchar = libtcod.console_get_char(sample_console, path_dx, |
||
928 | path_dy) |
||
929 | libtcod.console_put_char(sample_console, path_dx, path_dy, '+', |
||
930 | libtcod.BKGND_NONE) |
||
931 | if smap[path_dy][path_dx] == ' ': |
||
932 | path_recalculate = True |
||
933 | |||
934 | ############################################# |
||
935 | # bsp sample |
||
936 | ############################################# |
||
937 | bsp_depth = 8 |
||
938 | bsp_min_room_size = 4 |
||
939 | # a room fills a random part of the node or the maximum available space ? |
||
940 | bsp_random_room = False |
||
941 | # if true, there is always a wall on north & west side of a room |
||
942 | bsp_room_walls = True |
||
943 | bsp_map = None |
||
944 | # draw a vertical line |
||
945 | def vline(m, x, y1, y2): |
||
946 | if y1 > y2: |
||
947 | y1,y2 = y2,y1 |
||
948 | for y in range(y1,y2+1): |
||
949 | m[x][y] = True |
||
950 | |||
951 | # draw a vertical line up until we reach an empty space |
||
952 | def vline_up(m, x, y): |
||
953 | while y >= 0 and not m[x][y]: |
||
954 | m[x][y] = True |
||
955 | y -= 1 |
||
956 | |||
957 | # draw a vertical line down until we reach an empty space |
||
958 | def vline_down(m, x, y): |
||
959 | while y < SAMPLE_SCREEN_HEIGHT and not m[x][y]: |
||
960 | m[x][y] = True |
||
961 | y += 1 |
||
962 | |||
963 | # draw a horizontal line |
||
964 | def hline(m, x1, y, x2): |
||
965 | if x1 > x2: |
||
966 | x1,x2 = x2,x1 |
||
967 | for x in range(x1,x2+1): |
||
968 | m[x][y] = True |
||
969 | |||
970 | # draw a horizontal line left until we reach an empty space |
||
971 | def hline_left(m, x, y): |
||
972 | while x >= 0 and not m[x][y]: |
||
973 | m[x][y] = True |
||
974 | x -= 1 |
||
975 | |||
976 | # draw a horizontal line right until we reach an empty space |
||
977 | def hline_right(m, x, y): |
||
978 | while x < SAMPLE_SCREEN_WIDTH and not m[x][y]: |
||
979 | m[x][y]=True |
||
980 | x += 1 |
||
981 | |||
982 | # the class building the dungeon from the bsp nodes |
||
983 | View Code Duplication | def traverse_node(node, *dat): |
|
0 ignored issues
–
show
|
|||
984 | global bsp_map |
||
985 | if libtcod.bsp_is_leaf(node): |
||
986 | # calculate the room size |
||
987 | minx = node.x + 1 |
||
988 | maxx = node.x + node.w - 1 |
||
989 | miny = node.y + 1 |
||
990 | maxy = node.y + node.h - 1 |
||
991 | if not bsp_room_walls: |
||
992 | if minx > 1: |
||
993 | minx -= 1 |
||
994 | if miny > 1: |
||
995 | miny -=1 |
||
996 | if maxx == SAMPLE_SCREEN_WIDTH - 1: |
||
997 | maxx -= 1 |
||
998 | if maxy == SAMPLE_SCREEN_HEIGHT - 1: |
||
999 | maxy -= 1 |
||
1000 | if bsp_random_room: |
||
1001 | minx = libtcod.random_get_int(None, minx, maxx - bsp_min_room_size + 1) |
||
1002 | miny = libtcod.random_get_int(None, miny, maxy - bsp_min_room_size + 1) |
||
1003 | maxx = libtcod.random_get_int(None, minx + bsp_min_room_size - 1, maxx) |
||
1004 | maxy = libtcod.random_get_int(None, miny + bsp_min_room_size - 1, maxy) |
||
1005 | # resize the node to fit the room |
||
1006 | node.x = minx |
||
1007 | node.y = miny |
||
1008 | node.w = maxx-minx + 1 |
||
1009 | node.h = maxy-miny + 1 |
||
1010 | # dig the room |
||
1011 | for x in range(minx, maxx + 1): |
||
1012 | for y in range(miny, maxy + 1): |
||
1013 | bsp_map[x][y] = True |
||
1014 | else: |
||
1015 | # resize the node to fit its sons |
||
1016 | left = libtcod.bsp_left(node) |
||
1017 | right = libtcod.bsp_right(node) |
||
1018 | node.x = min(left.x, right.x) |
||
1019 | node.y = min(left.y, right.y) |
||
1020 | node.w = max(left.x + left.w, right.x + right.w) - node.x |
||
1021 | node.h = max(left.y + left.h, right.y + right.h) - node.y |
||
1022 | # create a corridor between the two lower nodes |
||
1023 | if node.horizontal: |
||
1024 | # vertical corridor |
||
1025 | if left.x + left.w - 1 < right.x or right.x + right.w - 1 < left.x: |
||
1026 | # no overlapping zone. we need a Z shaped corridor |
||
1027 | x1 = libtcod.random_get_int(None, left.x, left.x + left.w - 1) |
||
1028 | x2 = libtcod.random_get_int(None, right.x, right.x + right.w - 1) |
||
1029 | y = libtcod.random_get_int(None, left.y + left.h, right.y) |
||
1030 | vline_up(bsp_map, x1, y - 1) |
||
1031 | hline(bsp_map, x1, y, x2) |
||
1032 | vline_down(bsp_map, x2, y + 1) |
||
1033 | else: |
||
1034 | # straight vertical corridor |
||
1035 | minx = max(left.x, right.x) |
||
1036 | maxx = min(left.x + left.w - 1, right.x + right.w - 1) |
||
1037 | x = libtcod.random_get_int(None, minx, maxx) |
||
1038 | vline_down(bsp_map, x, right.y) |
||
1039 | vline_up(bsp_map, x, right.y - 1) |
||
1040 | else: |
||
1041 | # horizontal corridor |
||
1042 | if left.y + left.h - 1 < right.y or right.y + right.h - 1 < left.y: |
||
1043 | # no overlapping zone. we need a Z shaped corridor |
||
1044 | y1 = libtcod.random_get_int(None, left.y, left.y + left.h - 1) |
||
1045 | y2 = libtcod.random_get_int(None, right.y, right.y + right.h - 1) |
||
1046 | x = libtcod.random_get_int(None, left.x + left.w, right.x) |
||
1047 | hline_left(bsp_map, x - 1, y1) |
||
1048 | vline(bsp_map, x, y1, y2) |
||
1049 | hline_right(bsp_map, x + 1, y2) |
||
1050 | else: |
||
1051 | # straight horizontal corridor |
||
1052 | miny = max(left.y, right.y) |
||
1053 | maxy = min(left.y + left.h - 1, right.y + right.h - 1) |
||
1054 | y = libtcod.random_get_int(None, miny, maxy) |
||
1055 | hline_left(bsp_map, right.x - 1, y) |
||
1056 | hline_right(bsp_map, right.x, y) |
||
1057 | return True |
||
1058 | |||
1059 | bsp = None |
||
1060 | bsp_generate = True |
||
1061 | bsp_refresh = False |
||
1062 | def render_bsp(first, key, mouse): |
||
1063 | global bsp, bsp_generate, bsp_refresh, bsp_map |
||
1064 | global bsp_random_room, bsp_room_walls, bsp_depth, bsp_min_room_size |
||
1065 | View Code Duplication | if bsp_generate or bsp_refresh: |
|
0 ignored issues
–
show
|
|||
1066 | # dungeon generation |
||
1067 | if bsp is None: |
||
1068 | # create the bsp |
||
1069 | bsp = libtcod.bsp_new_with_size(0, 0, SAMPLE_SCREEN_WIDTH, |
||
1070 | SAMPLE_SCREEN_HEIGHT) |
||
1071 | else: |
||
1072 | # restore the nodes size |
||
1073 | libtcod.bsp_resize(bsp, 0, 0, SAMPLE_SCREEN_WIDTH, |
||
1074 | SAMPLE_SCREEN_HEIGHT) |
||
1075 | bsp_map = list() |
||
1076 | for x in range(SAMPLE_SCREEN_WIDTH): |
||
1077 | bsp_map.append([False] * SAMPLE_SCREEN_HEIGHT) |
||
1078 | if bsp_generate: |
||
1079 | # build a new random bsp tree |
||
1080 | libtcod.bsp_remove_sons(bsp) |
||
1081 | if bsp_room_walls: |
||
1082 | libtcod.bsp_split_recursive(bsp, 0, bsp_depth, |
||
1083 | bsp_min_room_size + 1, |
||
1084 | bsp_min_room_size + 1, 1.5, 1.5) |
||
1085 | else: |
||
1086 | libtcod.bsp_split_recursive(bsp, 0, bsp_depth, |
||
1087 | bsp_min_room_size, |
||
1088 | bsp_min_room_size, 1.5, 1.5) |
||
1089 | # create the dungeon from the bsp |
||
1090 | libtcod.bsp_traverse_inverted_level_order(bsp, traverse_node) |
||
1091 | bsp_generate = False |
||
1092 | bsp_refresh = False |
||
1093 | libtcod.console_clear(sample_console) |
||
1094 | libtcod.console_set_default_foreground(sample_console, libtcod.white) |
||
1095 | rooms = 'OFF' |
||
1096 | if bsp_random_room: |
||
1097 | rooms = 'ON' |
||
1098 | libtcod.console_print(sample_console, 1, 1, |
||
1099 | "ENTER : rebuild bsp\n" |
||
1100 | "SPACE : rebuild dungeon\n" |
||
1101 | "+-: bsp depth %d\n" |
||
1102 | "*/: room size %d\n" |
||
1103 | "1 : random room size %s" % (bsp_depth, |
||
1104 | bsp_min_room_size, rooms)) |
||
1105 | if bsp_random_room: |
||
1106 | walls = 'OFF' |
||
1107 | if bsp_room_walls: |
||
1108 | walls ='ON' |
||
1109 | libtcod.console_print(sample_console, 1, 6, |
||
1110 | '2 : room walls %s' % walls) |
||
1111 | # render the level |
||
1112 | for y in range(SAMPLE_SCREEN_HEIGHT): |
||
1113 | for x in range(SAMPLE_SCREEN_WIDTH): |
||
1114 | if not bsp_map[x][y]: |
||
1115 | libtcod.console_set_char_background(sample_console, x, y, fov_dark_wall, |
||
1116 | libtcod.BKGND_SET) |
||
1117 | else: |
||
1118 | libtcod.console_set_char_background(sample_console, x, y, fov_dark_ground, |
||
1119 | libtcod.BKGND_SET) |
||
1120 | View Code Duplication | if key.vk in (libtcod.KEY_ENTER ,libtcod.KEY_KPENTER): |
|
0 ignored issues
–
show
|
|||
1121 | bsp_generate = True |
||
1122 | elif key.c==ord(' '): |
||
1123 | bsp_refresh = True |
||
1124 | elif key.c == ord('+'): |
||
1125 | bsp_depth += 1 |
||
1126 | bsp_generate = True |
||
1127 | elif key.c == ord('-') and bsp_depth > 1: |
||
1128 | bsp_depth -= 1 |
||
1129 | bsp_generate = True |
||
1130 | elif key.c==ord('*'): |
||
1131 | bsp_min_room_size += 1 |
||
1132 | bsp_generate = True |
||
1133 | elif key.c == ord('/') and bsp_min_room_size > 2: |
||
1134 | bsp_min_room_size -= 1 |
||
1135 | bsp_generate = True |
||
1136 | elif key.c == ord('1') or key.vk in (libtcod.KEY_1, libtcod.KEY_KP1): |
||
1137 | bsp_random_room = not bsp_random_room |
||
1138 | if not bsp_random_room: |
||
1139 | bsp_room_walls = True |
||
1140 | bsp_refresh = True |
||
1141 | elif key.c == ord('2') or key.vk in (libtcod.KEY_2, libtcod.KEY_KP2): |
||
1142 | bsp_room_walls = not bsp_room_walls |
||
1143 | bsp_refresh = True |
||
1144 | |||
1145 | ############################################# |
||
1146 | # image sample |
||
1147 | ############################################# |
||
1148 | img = None |
||
1149 | img_circle = None |
||
1150 | img_blue = libtcod.Color(0, 0, 255) |
||
1151 | img_green = libtcod.Color(0, 255, 0) |
||
1152 | def render_image(first, key, mouse): |
||
1153 | global img,img_circle,img_blue,img_green |
||
1154 | if img is None: |
||
1155 | img = libtcod.image_load(os.path.join(b'data',b'img',b'skull.png')) |
||
1156 | libtcod.image_set_key_color(img,libtcod.black) |
||
1157 | img_circle = libtcod.image_load(os.path.join(b'data',b'img',b'circle.png')) |
||
1158 | if first: |
||
1159 | libtcod.sys_set_fps(30) |
||
1160 | libtcod.console_set_default_background(sample_console, libtcod.black) |
||
1161 | libtcod.console_clear(sample_console) |
||
1162 | x = SAMPLE_SCREEN_WIDTH / 2 + math.cos(libtcod.sys_elapsed_seconds()) * 10.0 |
||
1163 | y = float(SAMPLE_SCREEN_HEIGHT / 2) |
||
1164 | scalex=0.2 + 1.8 * (1.0 + math.cos(libtcod.sys_elapsed_seconds() / 2)) / 2.0 |
||
1165 | scaley = scalex |
||
1166 | angle = libtcod.sys_elapsed_seconds() |
||
1167 | elapsed = libtcod.sys_elapsed_milli() // 2000 |
||
1168 | if elapsed & 1 != 0: |
||
1169 | # split the color channels of circle.png |
||
1170 | # the red channel |
||
1171 | libtcod.console_set_default_background(sample_console, libtcod.red) |
||
1172 | libtcod.console_rect(sample_console, 0, 3, 15, 15, False, |
||
1173 | libtcod.BKGND_SET) |
||
1174 | libtcod.image_blit_rect(img_circle, sample_console, 0, 3, -1, -1, |
||
1175 | libtcod.BKGND_MULTIPLY) |
||
1176 | # the green channel |
||
1177 | libtcod.console_set_default_background(sample_console, img_green) |
||
1178 | libtcod.console_rect(sample_console, 15, 3, 15, 15, False, |
||
1179 | libtcod.BKGND_SET) |
||
1180 | libtcod.image_blit_rect(img_circle,sample_console, 15, 3, -1, -1, |
||
1181 | libtcod.BKGND_MULTIPLY) |
||
1182 | # the blue channel |
||
1183 | libtcod.console_set_default_background(sample_console, img_blue) |
||
1184 | libtcod.console_rect(sample_console, 30, 3, 15, 15, False, |
||
1185 | libtcod.BKGND_SET) |
||
1186 | libtcod.image_blit_rect(img_circle, sample_console, 30, 3, -1, -1, |
||
1187 | libtcod.BKGND_MULTIPLY) |
||
1188 | else: |
||
1189 | # render circle.png with normal blitting |
||
1190 | libtcod.image_blit_rect(img_circle, sample_console, 0, 3, -1, -1, |
||
1191 | libtcod.BKGND_SET) |
||
1192 | libtcod.image_blit_rect(img_circle, sample_console, 15, 3, -1, -1, |
||
1193 | libtcod.BKGND_SET) |
||
1194 | libtcod.image_blit_rect(img_circle, sample_console, 30, 3, -1, -1, |
||
1195 | libtcod.BKGND_SET) |
||
1196 | libtcod.image_blit(img, sample_console, x, y, libtcod.BKGND_SET, |
||
1197 | scalex, scaley, angle) |
||
1198 | |||
1199 | ############################################# |
||
1200 | # mouse sample |
||
1201 | ############################################# |
||
1202 | mouse_lbut = 0 |
||
1203 | mouse_mbut = 0 |
||
1204 | mouse_rbut = 0 |
||
1205 | def render_mouse(first, key, mouse): |
||
1206 | global mouse_lbut |
||
1207 | global mouse_mbut |
||
1208 | global mouse_rbut |
||
1209 | butstatus=('OFF', 'ON') |
||
1210 | if first: |
||
1211 | libtcod.console_set_default_background(sample_console, libtcod.grey) |
||
1212 | libtcod.console_set_default_foreground(sample_console, |
||
1213 | libtcod.light_yellow) |
||
1214 | libtcod.mouse_move(320, 200) |
||
1215 | libtcod.mouse_show_cursor(True) |
||
1216 | libtcod.sys_set_fps(30) |
||
1217 | libtcod.console_clear(sample_console) |
||
1218 | if mouse.lbutton_pressed: |
||
1219 | mouse_lbut = 1 - mouse_lbut |
||
1220 | if mouse.rbutton_pressed: |
||
1221 | mouse_rbut = 1 - mouse_rbut |
||
1222 | if mouse.mbutton_pressed: |
||
1223 | mouse_mbut = 1 - mouse_mbut |
||
1224 | wheel="" |
||
1225 | if mouse.wheel_up : |
||
1226 | wheel="UP" |
||
1227 | elif mouse.wheel_down : |
||
1228 | wheel="DOWN" |
||
1229 | libtcod.console_print(sample_console, 1, 1, |
||
1230 | "Mouse position : %4dx%4d\n" |
||
1231 | "Mouse cell : %4dx%4d\n" |
||
1232 | "Mouse movement : %4dx%4d\n" |
||
1233 | "Left button : %s (toggle %s)\n" |
||
1234 | "Right button : %s (toggle %s)\n" |
||
1235 | "Middle button : %s (toggle %s)\n" |
||
1236 | "Wheel : %s" % |
||
1237 | (mouse.x, mouse.y, |
||
1238 | mouse.cx, mouse.cy, |
||
1239 | mouse.dx, mouse.dy, |
||
1240 | butstatus[mouse.lbutton], butstatus[mouse_lbut], |
||
1241 | butstatus[mouse.rbutton], butstatus[mouse_rbut], |
||
1242 | butstatus[mouse.mbutton], butstatus[mouse_mbut], |
||
1243 | wheel)) |
||
1244 | libtcod.console_print(sample_console, 1, 10, |
||
1245 | "1 : Hide cursor\n2 : Show cursor") |
||
1246 | if key.c == ord('1'): |
||
1247 | libtcod.mouse_show_cursor(False) |
||
1248 | elif key.c == ord('2'): |
||
1249 | libtcod.mouse_show_cursor(True) |
||
1250 | |||
1251 | ############################################# |
||
1252 | # name generator sample |
||
1253 | ############################################# |
||
1254 | ng_curset = 0 |
||
1255 | ng_nbsets = 0 |
||
1256 | ng_delay = 0.0 |
||
1257 | ng_names = [] |
||
1258 | ng_sets = None |
||
1259 | def render_name(first, key, mouse): |
||
1260 | global ng_curset |
||
1261 | global ng_nbsets |
||
1262 | global ng_delay |
||
1263 | global ng_names |
||
1264 | global ng_sets |
||
1265 | if ng_nbsets == 0: |
||
1266 | # parse all *.cfg files in data/namegen |
||
1267 | for file in os.listdir(b'data/namegen') : |
||
1268 | if file.find(b'.cfg') > 0 : |
||
1269 | libtcod.namegen_parse(os.path.join(b'data',b'namegen',file)) |
||
1270 | # get the sets list |
||
1271 | ng_sets=libtcod.namegen_get_sets() |
||
1272 | print (ng_sets) |
||
1273 | ng_nbsets=len(ng_sets) |
||
1274 | if first: |
||
1275 | libtcod.sys_set_fps(30) |
||
1276 | while len(ng_names)> 15: |
||
1277 | ng_names.pop(0) |
||
1278 | libtcod.console_clear(sample_console) |
||
1279 | libtcod.console_set_default_foreground(sample_console,libtcod.white) |
||
1280 | libtcod.console_print(sample_console,1,1,"%s\n\n+ : next generator\n- : prev generator" % |
||
1281 | ng_sets[ng_curset]) |
||
1282 | for i in range(len(ng_names)) : |
||
1283 | libtcod.console_print_ex(sample_console,SAMPLE_SCREEN_WIDTH-2,2+i, |
||
1284 | libtcod.BKGND_NONE,libtcod.RIGHT,ng_names[i]) |
||
1285 | ng_delay += libtcod.sys_get_last_frame_length() |
||
1286 | if ng_delay > 0.5 : |
||
1287 | ng_delay -= 0.5 |
||
1288 | ng_names.append(libtcod.namegen_generate(ng_sets[ng_curset])) |
||
1289 | if key.c == ord('+'): |
||
1290 | ng_curset += 1 |
||
1291 | if ng_curset == ng_nbsets : |
||
1292 | ng_curset=0 |
||
1293 | ng_names.append("======") |
||
1294 | elif key.c == ord('-'): |
||
1295 | ng_curset -= 1 |
||
1296 | if ng_curset < 0 : |
||
1297 | ng_curset=ng_nbsets-1 |
||
1298 | ng_names.append("======") |
||
1299 | |||
1300 | ############################################# |
||
1301 | # python fast render sample |
||
1302 | ############################################# |
||
1303 | try: #import NumPy |
||
1304 | import numpy as np |
||
1305 | numpy_available = True |
||
1306 | except ImportError: |
||
1307 | numpy_available = False |
||
1308 | |||
1309 | use_numpy = numpy_available #default option |
||
1310 | SCREEN_W = SAMPLE_SCREEN_WIDTH |
||
1311 | SCREEN_H = SAMPLE_SCREEN_HEIGHT |
||
1312 | HALF_W = SCREEN_W // 2 |
||
1313 | HALF_H = SCREEN_H // 2 |
||
1314 | RES_U = 80 #texture resolution |
||
1315 | RES_V = 80 |
||
1316 | TEX_STRETCH = 5 #texture stretching with tunnel depth |
||
1317 | SPEED = 15 |
||
1318 | LIGHT_BRIGHTNESS = 3.5 #brightness multiplier for all lights (changes their radius) |
||
1319 | LIGHTS_CHANCE = 0.07 #chance of a light appearing |
||
1320 | MAX_LIGHTS = 6 |
||
1321 | MIN_LIGHT_STRENGTH = 0.2 |
||
1322 | LIGHT_UPDATE = 0.05 #how much the ambient light changes to reflect current light sources |
||
1323 | AMBIENT_LIGHT = 0.8 #brightness of tunnel texture |
||
1324 | |||
1325 | #the coordinates of all tiles in the screen, as numpy arrays. example: (4x3 pixels screen) |
||
1326 | #xc = [[1, 2, 3, 4], [1, 2, 3, 4], [1, 2, 3, 4]] |
||
1327 | #yc = [[1, 1, 1, 1], [2, 2, 2, 2], [3, 3, 3, 3]] |
||
1328 | if numpy_available: |
||
1329 | (xc, yc) = np.meshgrid(range(SCREEN_W), range(SCREEN_H)) |
||
1330 | #translate coordinates of all pixels to center |
||
1331 | xc = xc - HALF_W |
||
1332 | yc = yc - HALF_H |
||
1333 | |||
1334 | noise2d = libtcod.noise_new(2, 0.5, 2.0) |
||
1335 | if numpy_available: #the texture starts empty |
||
1336 | texture = np.zeros((RES_U, RES_V)) |
||
1337 | |||
1338 | #create lists to work without numpy |
||
1339 | texture2 = [0 for i in range(RES_U * RES_V)] |
||
1340 | brightness2 = [0 for i in range(SCREEN_W * SCREEN_H)] |
||
1341 | R2 = [0 for i in range(SCREEN_W * SCREEN_H)] |
||
1342 | G2 = [0 for i in range(SCREEN_W * SCREEN_H)] |
||
1343 | B2 = [0 for i in range(SCREEN_W * SCREEN_H)] |
||
1344 | |||
1345 | class Light: |
||
1346 | def __init__(self, x, y, z, r, g, b, strength): |
||
1347 | self.x, self.y, self.z = x, y, z #pos. |
||
1348 | self.r, self.g, self.b = r, g, b #color |
||
1349 | self.strength = strength #between 0 and 1, defines brightness |
||
1350 | |||
1351 | def render_py(first, key, mouse): |
||
1352 | global use_numpy, frac_t, abs_t, lights, tex_r, tex_g, tex_b, xc, yc, texture, texture2, brightness2, R2, G2, B2 |
||
1353 | |||
1354 | if key.c == ord(' ') and numpy_available: #toggle renderer |
||
1355 | use_numpy = not use_numpy |
||
1356 | first = True |
||
1357 | if first: #initialize stuff |
||
1358 | libtcod.sys_set_fps(0) |
||
1359 | libtcod.console_clear(sample_console) #render status message |
||
1360 | if not numpy_available: text = 'NumPy uninstalled, using default renderer' |
||
1361 | elif use_numpy: text = 'Renderer: NumPy \nSpacebar to change' |
||
1362 | else: text = 'Renderer: default\nSpacebar to change' |
||
1363 | libtcod.console_set_default_foreground(sample_console,libtcod.white) |
||
1364 | libtcod.console_print(sample_console, 1, SCREEN_H - 3, text) |
||
1365 | |||
1366 | frac_t = RES_V - 1 #time is represented in number of pixels of the texture, start later in time to initialize texture |
||
1367 | abs_t = RES_V - 1 |
||
1368 | lights = [] #lights list, and current color of the tunnel texture |
||
1369 | tex_r, tex_g, tex_b = 0, 0, 0 |
||
1370 | |||
1371 | time_delta = libtcod.sys_get_last_frame_length() * SPEED #advance time |
||
1372 | frac_t += time_delta #increase fractional (always < 1.0) time |
||
1373 | abs_t += time_delta #increase absolute elapsed time |
||
1374 | int_t = int(frac_t) #integer time units that passed this frame (number of texture pixels to advance) |
||
1375 | frac_t -= int_t #keep this < 1.0 |
||
1376 | |||
1377 | #change texture color according to presence of lights (basically, sum them |
||
1378 | #to get ambient light and smoothly change the current color into that) |
||
1379 | ambient_r = AMBIENT_LIGHT * sum([light.r * light.strength for light in lights]) |
||
1380 | ambient_g = AMBIENT_LIGHT * sum([light.g * light.strength for light in lights]) |
||
1381 | ambient_b = AMBIENT_LIGHT * sum([light.b * light.strength for light in lights]) |
||
1382 | alpha = LIGHT_UPDATE * time_delta |
||
1383 | tex_r = tex_r * (1 - alpha) + ambient_r * alpha |
||
1384 | tex_g = tex_g * (1 - alpha) + ambient_g * alpha |
||
1385 | tex_b = tex_b * (1 - alpha) + ambient_b * alpha |
||
1386 | |||
1387 | if int_t >= 1: #roll texture (ie, advance in tunnel) according to int_t |
||
1388 | int_t = int_t % RES_V #can't roll more than the texture's size (can happen when time_delta is large) |
||
1389 | int_abs_t = int(abs_t) #new pixels are based on absolute elapsed time |
||
1390 | |||
1391 | if use_numpy: |
||
1392 | texture = np.roll(texture, -int_t, 1) |
||
1393 | #replace new stretch of texture with new values |
||
1394 | for v in range(RES_V - int_t, RES_V): |
||
1395 | for u in range(0, RES_U): |
||
1396 | tex_v = (v + int_abs_t) / float(RES_V) |
||
1397 | texture[u,v] = (libtcod.noise_get_fbm(noise2d, [u/float(RES_U), tex_v], 32.0) + |
||
1398 | libtcod.noise_get_fbm(noise2d, [1 - u/float(RES_U), tex_v], 32.0)) |
||
1399 | |||
1400 | else: #"roll" texture, without numpy |
||
1401 | temp = texture2[0 : RES_U*int_t] |
||
1402 | texture2 = texture2[RES_U*int_t : ] |
||
1403 | texture2.extend(temp) |
||
1404 | |||
1405 | #replace new stretch of texture with new values |
||
1406 | for v in range(RES_V - int_t, RES_V): |
||
1407 | for u in range(0, RES_U): |
||
1408 | tex_v = (v + int_abs_t) / float(RES_V) |
||
1409 | texture2[u + v*RES_U] = ( |
||
1410 | libtcod.noise_get_fbm(noise2d, [u/float(RES_U), tex_v], 32.0) + |
||
1411 | libtcod.noise_get_fbm(noise2d, [1 - u/float(RES_U), tex_v], 32.0)) |
||
1412 | if use_numpy: |
||
1413 | #squared distance from center, clipped to sensible minimum and maximum values |
||
1414 | sqr_dist = xc**2 + yc**2 |
||
1415 | sqr_dist = sqr_dist.clip(1.0 / RES_V, RES_V**2) |
||
1416 | |||
1417 | #one coordinate into the texture, represents depth in the tunnel |
||
1418 | v = TEX_STRETCH * float(RES_V) / sqr_dist + frac_t |
||
1419 | v = v.clip(0, RES_V - 1) |
||
1420 | |||
1421 | #another coordinate, represents rotation around the tunnel |
||
1422 | u = np.mod(RES_U * (np.arctan2(yc, xc) / (2 * np.pi) + 0.5), RES_U) |
||
1423 | |||
1424 | #retrieve corresponding pixels from texture |
||
1425 | brightness = texture[u.astype(int), v.astype(int)] / 4.0 + 0.5 |
||
1426 | |||
1427 | #use the brightness map to compose the final color of the tunnel |
||
1428 | R = brightness * tex_r |
||
1429 | G = brightness * tex_g |
||
1430 | B = brightness * tex_b |
||
1431 | else: |
||
1432 | i = 0 |
||
1433 | for y in range(-HALF_H, HALF_H): |
||
1434 | for x in range(-HALF_W, HALF_W): |
||
1435 | #squared distance from center, clipped to sensible minimum and maximum values |
||
1436 | sqr_dist = x**2 + y**2 |
||
1437 | sqr_dist = min(max(sqr_dist, 1.0 / RES_V), RES_V**2) |
||
1438 | |||
1439 | #one coordinate into the texture, represents depth in the tunnel |
||
1440 | v = TEX_STRETCH * float(RES_V) / sqr_dist + frac_t |
||
1441 | v = min(v, RES_V - 1) |
||
1442 | |||
1443 | #another coordinate, represents rotation around the tunnel |
||
1444 | u = (RES_U * (math.atan2(y, x) / (2 * math.pi) + 0.5)) % RES_U |
||
1445 | |||
1446 | #retrieve corresponding pixels from texture |
||
1447 | brightness = texture2[int(u) + int(v)*RES_U] / 4.0 + 0.5 |
||
1448 | |||
1449 | #use the brightness map to compose the final color of the tunnel |
||
1450 | R2[i] = brightness * tex_r |
||
1451 | G2[i] = brightness * tex_g |
||
1452 | B2[i] = brightness * tex_b |
||
1453 | i += 1 |
||
1454 | |||
1455 | #create new light source |
||
1456 | if libtcod.random_get_float(0, 0, 1) <= time_delta * LIGHTS_CHANCE and len(lights) < MAX_LIGHTS: |
||
1457 | x = libtcod.random_get_float(0, -0.5, 0.5) |
||
1458 | y = libtcod.random_get_float(0, -0.5, 0.5) |
||
1459 | strength = libtcod.random_get_float(0, MIN_LIGHT_STRENGTH, 1.0) |
||
1460 | |||
1461 | color = libtcod.Color(0, 0, 0) #create bright colors with random hue |
||
1462 | hue = libtcod.random_get_float(0, 0, 360) |
||
1463 | libtcod.color_set_hsv(color, hue, 0.5, strength) |
||
1464 | lights.append(Light(x, y, TEX_STRETCH, color.r, color.g, color.b, strength)) |
||
1465 | |||
1466 | #eliminate lights that are going to be out of view |
||
1467 | lights = [light for light in lights if light.z - time_delta > 1.0 / RES_V] |
||
1468 | |||
1469 | for light in lights: #render lights |
||
1470 | #move light's Z coordinate with time, then project its XYZ coordinates to screen-space |
||
1471 | light.z -= float(time_delta) / TEX_STRETCH |
||
1472 | xl = light.x / light.z * SCREEN_H |
||
1473 | yl = light.y / light.z * SCREEN_H |
||
1474 | |||
1475 | if use_numpy: |
||
1476 | #calculate brightness of light according to distance from viewer and strength, |
||
1477 | #then calculate brightness of each pixel with inverse square distance law |
||
1478 | light_brightness = LIGHT_BRIGHTNESS * light.strength * (1.0 - light.z / TEX_STRETCH) |
||
1479 | brightness = light_brightness / ((xc - xl)**2 + (yc - yl)**2) |
||
1480 | |||
1481 | #make all pixels shine around this light |
||
1482 | R += brightness * light.r |
||
1483 | G += brightness * light.g |
||
1484 | B += brightness * light.b |
||
1485 | else: |
||
1486 | i = 0 #same, without numpy |
||
1487 | for y in range(-HALF_H, HALF_H): |
||
1488 | for x in range(-HALF_W, HALF_W): |
||
1489 | light_brightness = LIGHT_BRIGHTNESS * light.strength * (1.0 - light.z / TEX_STRETCH) |
||
1490 | brightness = light_brightness / ((x - xl)**2 + (y - yl)**2) |
||
1491 | |||
1492 | R2[i] += brightness * light.r |
||
1493 | G2[i] += brightness * light.g |
||
1494 | B2[i] += brightness * light.b |
||
1495 | i += 1 |
||
1496 | |||
1497 | if use_numpy: |
||
1498 | #truncate values |
||
1499 | R = R.clip(0, 255) |
||
1500 | G = G.clip(0, 255) |
||
1501 | B = B.clip(0, 255) |
||
1502 | |||
1503 | #fill the screen with these background colors |
||
1504 | libtcod.console_fill_background(sample_console, R, G, B) |
||
1505 | else: |
||
1506 | #truncate and convert to integer |
||
1507 | R2 = [int(min(r, 255)) for r in R2] |
||
1508 | G2 = [int(min(g, 255)) for g in G2] |
||
1509 | B2 = [int(min(b, 255)) for b in B2] |
||
1510 | |||
1511 | #fill the screen with these background colors |
||
1512 | libtcod.console_fill_background(sample_console, R2, G2, B2) |
||
1513 | |||
1514 | ############################################# |
||
1515 | # main loop |
||
1516 | ############################################# |
||
1517 | class Sample: |
||
1518 | def __init__(self, name, func): |
||
1519 | self.name = name |
||
1520 | self.func = func |
||
1521 | |||
1522 | samples = (Sample(' True colors ', render_colors), |
||
1523 | Sample(' Offscreen console ', render_offscreen), |
||
1524 | Sample(' Line drawing ', render_lines), |
||
1525 | Sample(' Noise ', render_noise), |
||
1526 | Sample(' Field of view ', render_fov), |
||
1527 | Sample(' Path finding ', render_path), |
||
1528 | Sample(' Bsp toolkit ', render_bsp), |
||
1529 | Sample(' Image toolkit ', render_image), |
||
1530 | Sample(' Mouse support ', render_mouse), |
||
1531 | Sample(' Name generator ', render_name), |
||
1532 | Sample(' Python fast render ', render_py)) |
||
1533 | cur_sample = 0 |
||
1534 | credits_end = False |
||
1535 | first = True |
||
1536 | cur_renderer = 0 |
||
1537 | renderer_name=('F1 GLSL ','F2 OPENGL ','F3 SDL ') |
||
1538 | key=libtcod.Key() |
||
1539 | mouse=libtcod.Mouse() |
||
1540 | while not libtcod.console_is_window_closed(): |
||
1541 | libtcod.sys_check_for_event(libtcod.EVENT_KEY_PRESS|libtcod.EVENT_MOUSE,key,mouse) |
||
1542 | # render the sample |
||
1543 | samples[cur_sample].func(first, key, mouse) |
||
1544 | first = False |
||
1545 | libtcod.console_blit(sample_console, |
||
1546 | 0, 0, SAMPLE_SCREEN_WIDTH, SAMPLE_SCREEN_HEIGHT, |
||
1547 | 0, SAMPLE_SCREEN_X, SAMPLE_SCREEN_Y) |
||
1548 | # render credits |
||
1549 | if not credits_end: |
||
1550 | credits_end = libtcod.console_credits_render(60, 43, 0) |
||
1551 | # render sample list |
||
1552 | for i in range(len(samples)): |
||
1553 | if i == cur_sample: |
||
1554 | libtcod.console_set_default_foreground(None, libtcod.white) |
||
1555 | libtcod.console_set_default_background(None, libtcod.light_blue) |
||
1556 | else: |
||
1557 | libtcod.console_set_default_foreground(None, libtcod.grey) |
||
1558 | libtcod.console_set_default_background(None, libtcod.black) |
||
1559 | libtcod.console_print_ex(None, 2, 46 - (len(samples) - i), |
||
1560 | libtcod.BKGND_SET, libtcod.LEFT, samples[i].name) |
||
1561 | # render stats |
||
1562 | libtcod.console_set_default_foreground(None, libtcod.grey) |
||
1563 | libtcod.console_print_ex(None, 79, 46, libtcod.BKGND_NONE, libtcod.RIGHT, |
||
1564 | 'last frame : %3d ms (%3d fps)' % |
||
1565 | (int(libtcod.sys_get_last_frame_length() * |
||
1566 | 1000.0), libtcod.sys_get_fps())) |
||
1567 | libtcod.console_print_ex(None, 79, 47, libtcod.BKGND_NONE, libtcod.RIGHT, |
||
1568 | 'elapsed : %8d ms %4.2fs' % |
||
1569 | (libtcod.sys_elapsed_milli(), |
||
1570 | libtcod.sys_elapsed_seconds())) |
||
1571 | |||
1572 | cur_renderer=libtcod.sys_get_renderer() |
||
1573 | libtcod.console_set_default_foreground(None,libtcod.grey) |
||
1574 | libtcod.console_set_default_background(None,libtcod.black) |
||
1575 | libtcod.console_print_ex(None,42,46-(libtcod.NB_RENDERERS+1),libtcod.BKGND_SET, libtcod.LEFT, "Renderer :") |
||
1576 | for i in range(libtcod.NB_RENDERERS) : |
||
1577 | if i==cur_renderer : |
||
1578 | libtcod.console_set_default_foreground(None,libtcod.white) |
||
1579 | libtcod.console_set_default_background(None,libtcod.light_blue) |
||
1580 | else : |
||
1581 | libtcod.console_set_default_foreground(None,libtcod.grey) |
||
1582 | libtcod.console_set_default_background(None,libtcod.black) |
||
1583 | libtcod.console_print_ex(None,42,46-(libtcod.NB_RENDERERS-i),libtcod.BKGND_SET,libtcod.LEFT,renderer_name[i]) |
||
1584 | |||
1585 | # key handler |
||
1586 | if key.vk == libtcod.KEY_DOWN: |
||
1587 | cur_sample = (cur_sample+1) % len(samples) |
||
1588 | first = True |
||
1589 | elif key.vk == libtcod.KEY_UP: |
||
1590 | cur_sample = (cur_sample-1) % len(samples) |
||
1591 | first = True |
||
1592 | View Code Duplication | elif key.vk == libtcod.KEY_ENTER and key.lalt: |
|
0 ignored issues
–
show
|
|||
1593 | libtcod.console_set_fullscreen(not libtcod.console_is_fullscreen()) |
||
1594 | elif key.vk == libtcod.KEY_PRINTSCREEN or key.c == 'p': |
||
1595 | print ("screenshot") |
||
1596 | if key.lalt : |
||
1597 | libtcod.console_save_apf(None,"samples.apf") |
||
1598 | print ("apf") |
||
1599 | else : |
||
1600 | libtcod.sys_save_screenshot() |
||
1601 | print ("png") |
||
1602 | elif key.vk == libtcod.KEY_ESCAPE: |
||
1603 | break |
||
1604 | elif key.vk == libtcod.KEY_F1: |
||
1605 | libtcod.sys_set_renderer(libtcod.RENDERER_GLSL) |
||
1606 | elif key.vk == libtcod.KEY_F2: |
||
1607 | libtcod.sys_set_renderer(libtcod.RENDERER_OPENGL) |
||
1608 | elif key.vk == libtcod.KEY_F3: |
||
1609 | libtcod.sys_set_renderer(libtcod.RENDERER_SDL) |
||
1610 | libtcod.console_flush() |
||
1611 | |||
1612 | |||
1613 |