@@ -77,8 +77,7 @@ def _get_elapsed_time() -> float:
7777
7878
7979class Sample(tcod.event.EventDispatch[None]):
80- def __init__(self, name: str = "") -> None:
81- self.name = name
80+ name: str = "???"
8281
8382 def on_enter(self) -> None:
8483 pass
@@ -114,74 +113,73 @@ def ev_keydown(self, event: tcod.event.KeyDown) -> None:
114113
115114
116115class TrueColorSample(Sample):
116+ name = "True colors"
117+
117118 def __init__(self) -> None:
118- self.name = "True colors"
119- # corner colors
120- self.colors: NDArray[np.int16] = np.array(
121- [(50, 40, 150), (240, 85, 5), (50, 35, 240), (10, 200, 130)],
122- dtype=np.int16,
123- )
124- # color shift direction
125- self.slide_dir: NDArray[np.int16] = np.array([[1, 1, 1], [-1, -1, 1], [1, -1, 1], [1, 1, -1]], dtype=np.int16)
126- # corner indexes
127- self.corners: NDArray[np.int16] = np.array([0, 1, 2, 3], dtype=np.int16)
119+ self.noise = tcod.noise.Noise(2, tcod.noise.Algorithm.SIMPLEX)
120+ """Noise for generating color."""
121+
122+ self.generator = np.random.default_rng()
123+ """Numpy generator for random text."""
128124
129125 def on_draw(self) -> None:
130- self.slide_corner_colors()
131126 self.interpolate_corner_colors()
132127 self.darken_background_characters()
133128 self.randomize_sample_console()
134- self.print_banner()
135-
136- def slide_corner_colors(self) -> None:
137- # pick random RGB channels for each corner
138- rand_channels = np.random.randint(low=0, high=3, size=4)
139-
140- # shift picked color channels in the direction of slide_dir
141- self.colors[self.corners, rand_channels] += self.slide_dir[self.corners, rand_channels] * 5
129+ sample_console.print(
130+ x=1,
131+ y=5,
132+ width=sample_console.width - 2,
133+ height=sample_console.height - 1,
134+ text="The Doryen library uses 24 bits colors, for both background and foreground.",
135+ fg=WHITE,
136+ bg=GREY,
137+ bg_blend=libtcodpy.BKGND_MULTIPLY,
138+ alignment=libtcodpy.CENTER,
139+ )
142140
143- # reverse slide_dir values when limits are reached
144- self.slide_dir[self.colors[:] == 255] = -1
145- self.slide_dir[self.colors[:] == 0] = 1
141+ def get_corner_colors(self) -> NDArray[np.uint8]:
142+ """Return 4 random 8-bit colors, smoothed over time."""
143+ noise_samples_ij = (
144+ [ # i coordinates are per color channel per color
145+ [0, 1, 2],
146+ [3, 4, 5],
147+ [6, 7, 8],
148+ [9, 10, 11],
149+ ],
150+ time.perf_counter(), # j coordinate is time broadcast to all samples
151+ )
152+ colors = self.noise[noise_samples_ij]
153+ colors = ((colors + 1.0) * (0.5 * 255.0)).clip(min=0, max=255) # Convert -1..1 to 0..255
154+ return colors.astype(np.uint8)
146155
147156 def interpolate_corner_colors(self) -> None:
148- # interpolate corner colors across the sample console
149- left = np.linspace(self.colors[0], self.colors[2], SAMPLE_SCREEN_HEIGHT)
150- right = np.linspace(self.colors[1], self.colors[3], SAMPLE_SCREEN_HEIGHT)
157+ """Interpolate corner colors across the sample console."""
158+ colors = self.get_corner_colors()
159+ left = np.linspace(colors[0], colors[2], SAMPLE_SCREEN_HEIGHT)
160+ right = np.linspace(colors[1], colors[3], SAMPLE_SCREEN_HEIGHT)
151161 sample_console.bg[:] = np.linspace(left, right, SAMPLE_SCREEN_WIDTH)
152162
153163 def darken_background_characters(self) -> None:
154- # darken background characters
164+ """Darken background characters."""
155165 sample_console.fg[:] = sample_console.bg[:]
156166 sample_console.fg[:] //= 2
157167
158168 def randomize_sample_console(self) -> None:
159- # randomize sample console characters
160- sample_console.ch[:] = np.random.randint (
169+ """Randomize sample console characters."""
170+ sample_console.ch[:] = self.generator.integers (
161171 low=ord("a"),
162- high=ord("z") + 1,
172+ high=ord("z"),
173+ endpoint=True,
163174 size=sample_console.ch.size,
164175 dtype=np.intc,
165176 ).reshape(sample_console.ch.shape)
166177
167- def print_banner(self) -> None:
168- # print text on top of samples
169- sample_console.print_box(
170- x=1,
171- y=5,
172- width=sample_console.width - 2,
173- height=sample_console.height - 1,
174- string="The Doryen library uses 24 bits colors, for both background and foreground.",
175- fg=WHITE,
176- bg=GREY,
177- bg_blend=libtcodpy.BKGND_MULTIPLY,
178- alignment=libtcodpy.CENTER,
179- )
180-
181178
182179class OffscreenConsoleSample(Sample):
180+ name = "Offscreen console"
181+
183182 def __init__(self) -> None:
184- self.name = "Offscreen console"
185183 self.secondary = tcod.console.Console(sample_console.width // 2, sample_console.height // 2)
186184 self.screenshot = tcod.console.Console(sample_console.width, sample_console.height)
187185 self.counter = 0.0
@@ -245,6 +243,8 @@ def on_draw(self) -> None:
245243
246244
247245class LineDrawingSample(Sample):
246+ name = "Line drawing"
247+
248248 FLAG_NAMES = (
249249 "BKGND_NONE",
250250 "BKGND_SET",
@@ -262,7 +262,6 @@ class LineDrawingSample(Sample):
262262 )
263263
264264 def __init__(self) -> None:
265- self.name = "Line drawing"
266265 self.mk_flag = libtcodpy.BKGND_SET
267266 self.bk_flag = libtcodpy.BKGND_SET
268267
@@ -322,6 +321,8 @@ def on_draw(self) -> None:
322321
323322
324323class NoiseSample(Sample):
324+ name = "Noise"
325+
325326 NOISE_OPTIONS = ( # (name, algorithm, implementation)
326327 (
327328 "perlin noise",
@@ -371,7 +372,6 @@ class NoiseSample(Sample):
371372 )
372373
373374 def __init__(self) -> None:
374- self.name = "Noise"
375375 self.func = 0
376376 self.dx = 0.0
377377 self.dy = 0.0
@@ -548,9 +548,9 @@ def ev_keydown(self, event: tcod.event.KeyDown) -> None:
548548
549549
550550class FOVSample(Sample):
551- def __init__(self) -> None:
552- self.name = "Field of view"
551+ name = "Field of view"
553552
553+ def __init__(self) -> None:
554554 self.player_x = 20
555555 self.player_y = 10
556556 self.torch = False
@@ -674,10 +674,10 @@ def ev_keydown(self, event: tcod.event.KeyDown) -> None:
674674
675675
676676class PathfindingSample(Sample):
677+ name = "Path finding"
678+
677679 def __init__(self) -> None:
678680 """Initialize this sample."""
679- self.name = "Path finding"
680-
681681 self.player_x = 20
682682 self.player_y = 10
683683 self.dest_x = 24
@@ -873,8 +873,9 @@ def traverse_node(bsp_map: NDArray[np.bool_], node: tcod.bsp.BSP) -> None:
873873
874874
875875class BSPSample(Sample):
876+ name = "Bsp toolkit"
877+
876878 def __init__(self) -> None:
877- self.name = "Bsp toolkit"
878879 self.bsp = tcod.bsp.BSP(1, 1, SAMPLE_SCREEN_WIDTH - 1, SAMPLE_SCREEN_HEIGHT - 1)
879880 self.bsp_map: NDArray[np.bool_] = np.zeros((SAMPLE_SCREEN_WIDTH, SAMPLE_SCREEN_HEIGHT), dtype=bool, order="F")
880881 self.bsp_generate()
@@ -956,9 +957,9 @@ def ev_keydown(self, event: tcod.event.KeyDown) -> None:
956957
957958
958959class ImageSample(Sample):
959- def __init__(self) -> None:
960- self.name = "Image toolkit"
960+ name = "Image toolkit"
961961
962+ def __init__(self) -> None:
962963 self.img = tcod.image.Image.from_file(DATA_DIR / "img/skull.png")
963964 self.img.set_key_color(BLACK)
964965 self.circle = tcod.image.Image.from_file(DATA_DIR / "img/circle.png")
@@ -990,9 +991,9 @@ def on_draw(self) -> None:
990991
991992
992993class MouseSample(Sample):
993- def __init__(self) -> None:
994- self.name = "Mouse support"
994+ name = "Mouse support"
995995
996+ def __init__(self) -> None:
996997 self.motion = tcod.event.MouseMotion()
997998 self.mouse_left = self.mouse_middle = self.mouse_right = 0
998999 self.log: list[str] = []
@@ -1054,9 +1055,9 @@ def ev_keydown(self, event: tcod.event.KeyDown) -> None:
10541055
10551056
10561057class NameGeneratorSample(Sample):
1057- def __init__(self) -> None:
1058- self.name = "Name generator"
1058+ name = "Name generator"
10591059
1060+ def __init__(self) -> None:
10601061 self.current_set = 0
10611062 self.delay = 0.0
10621063 self.names: list[str] = []
@@ -1160,8 +1161,7 @@ def __init__(
11601161
11611162
11621163class FastRenderSample(Sample):
1163- def __init__(self) -> None:
1164- self.name = "Python fast render"
1164+ name = "Python fast render"
11651165
11661166 def on_enter(self) -> None:
11671167 sample_console.clear() # render status message
0 commit comments