render_bsp()   F
last analyzed

Complexity

Conditions 26

Size

Total Lines 82

Duplication

Lines 52
Ratio 63.41 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 26
dl 52
loc 82
rs 0
c 2
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

Complexity

Complex classes like render_bsp() often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

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
This code seems to be duplicated in your project.
Loading history...
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
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
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
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
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
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
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
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
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
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
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
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
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
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
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
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
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
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
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