Draw a path from the hero to the current mouse point

Add a highlight grid to Map, with locations set to True if that point should be
drawn with a "highlight" treatment.

Add the highlight graphic_dtype to all Tiles.
This commit is contained in:
Eryn Wells 2023-02-10 22:35:51 -08:00
parent f05dfdef55
commit 6c9d01771f
4 changed files with 80 additions and 29 deletions

View file

@ -6,6 +6,7 @@ parts of a map.
'''
import random
from typing import Iterable
import numpy as np
import numpy.typing as npt
@ -20,17 +21,17 @@ class Map:
def __init__(self, size: Size, generator: MapGenerator):
self.size = size
self.generator = generator
self.tiles = np.full(tuple(size), fill_value=Empty, order='F')
generator.generate(self.tiles)
self.up_stairs = generator.up_stairs
self.down_stairs = generator.down_stairs
self.highlighted = np.full(tuple(self.size), fill_value=False, order='F')
# Map tiles that are currently visible to the player
self.visible = np.full(tuple(self.size), fill_value=True, order='F')
self.visible = np.full(tuple(self.size), fill_value=False, order='F')
# Map tiles that the player has explored
self.explored = np.full(tuple(self.size), fill_value=True, order='F')
self.explored = np.full(tuple(self.size), fill_value=False, order='F')
self.__walkable_points = None
@ -47,7 +48,14 @@ class Map:
def tile_is_walkable(self, point: Point) -> bool:
'''Return True if the tile at the given point is walkable'''
return self.tiles[point.x, point.y]['walkable']
return self.tile_is_in_bounds(point) and self.tiles[point.x, point.y]['walkable']
def highlight_points(self, points: Iterable[Point]):
'''Update the highlight graph with the list of points to highlight.'''
self.highlighted.fill(False)
for pt in points if points:
self.highlighted[pt.x, pt.y] = True
def print_to_console(self, console: tcod.Console) -> None:
'''Render the map to the console.'''
@ -56,6 +64,6 @@ class Map:
# If a tile is in the visible array, draw it with the "light" color. If it's not, but it's in the explored
# array, draw it with the "dark" color. Otherwise, draw it as Empty.
console.tiles_rgb[0:size.width, 0:size.height] = np.select(
condlist=[self.visible, self.explored],
choicelist=[self.tiles['light'], self.tiles['dark']],
condlist=[self.highlighted, self.visible, self.explored],
choicelist=[self.tiles['highlighted'], self.tiles['light'], self.tiles['dark']],
default=Shroud)

View file

@ -6,9 +6,9 @@ graphic_datatype = np.dtype([
# Character, a Unicode codepoint represented as an int32
('ch', np.int32),
# Foreground color, three bytes
('fg', '3B'),
('fg', '4B'),
# Background color, three bytes
('bg', '3B'),
('bg', '4B'),
])
tile_datatype = np.dtype([
@ -20,37 +20,45 @@ tile_datatype = np.dtype([
('dark', graphic_datatype),
# A graphic struct (as above) defining the look of this tile when it's visible
('light', graphic_datatype),
# A graphic struct (as above) defining the look of this tile when it's highlighted
('highlighted', graphic_datatype),
])
def tile(*,
walkable: int,
transparent: int,
dark: Tuple[int, Tuple[int, int, int], Tuple[int, int, int]],
light: Tuple[int, Tuple[int, int, int], Tuple[int, int, int]]) -> np.ndarray:
return np.array((walkable, transparent, dark, light), dtype=tile_datatype)
dark: Tuple[int, Tuple[int, int, int, int], Tuple[int, int, int, int]],
light: Tuple[int, Tuple[int, int, int, int], Tuple[int, int, int, int]],
highlighted: Tuple[int, Tuple[int, int, int, int], Tuple[int, int, int, int]]) -> np.ndarray:
return np.array((walkable, transparent, dark, light, highlighted), dtype=tile_datatype)
# An overlay color for tiles that are not visible and have not been explored
Shroud = np.array((ord(' '), (255, 255, 255), (0, 0, 0)), dtype=graphic_datatype)
Shroud = np.array((ord(' '), (255, 255, 255, 255), (0, 0, 0, 0)), dtype=graphic_datatype)
Empty = tile(
walkable=False, transparent=False,
dark=(ord(' '), (255, 255, 255), (0, 0, 0)),
light=(ord(' '), (255, 255, 255), (0, 0, 0)))
dark=(ord('#'), (20, 20, 20, 255), (0, 0, 0, 0)),
light=(ord('#'), (20, 20, 20, 255), (0, 0, 0, 0)),
highlighted=(ord('#'), (20, 20, 20, 255), (30, 30, 30, 255)))
Floor = tile(
walkable=True, transparent=True,
dark=(ord('·'), (80, 80, 100), (50, 50, 50)),
light=(ord('·'), (100, 100, 120), (80, 80, 100)))
dark=(ord('·'), (80, 80, 100, 255), (50, 50, 50, 255)),
light=(ord('·'), (100, 100, 120, 255), (80, 80, 100, 255)),
highlighted=(ord('·'), (100, 100, 120, 255), (80, 80, 150, 255)))
StairsUp = tile(
walkable=True, transparent=True,
dark=(ord('<'), (80, 80, 100), (50, 50, 50)),
light=(ord('<'), (100, 100, 120), (80, 80, 100)))
dark=(ord('<'), (80, 80, 100, 255), (50, 50, 50, 255)),
light=(ord('<'), (100, 100, 120, 255), (80, 80, 100, 255)),
highlighted=(ord('<'), (100, 100, 120, 255), (80, 80, 150, 255)))
StairsDown = tile(
walkable=True, transparent=True,
dark=(ord('>'), (80, 80, 100), (50, 50, 50)),
light=(ord('>'), (100, 100, 120), (80, 80, 100)))
dark=(ord('>'), (80, 80, 100, 255), (50, 50, 50, 255)),
light=(ord('>'), (100, 100, 120, 255), (80, 80, 100, 255)),
highlighted=(ord('>'), (100, 100, 120, 255), (80, 80, 150, 255)))
Wall = tile(
walkable=False, transparent=False,
dark=(ord(' '), (255, 255, 255), (0, 0, 150)),
light=(ord(' '), (255, 255, 255), (50, 50, 200)))
dark=(ord('#'), (80, 80, 80, 255), (0, 0, 0, 255)),
light=(ord('#'), (100, 100, 100, 255), (20, 20, 20, 255)),
highlighted=(ord('#'), (100, 100, 100, 255), (20, 20, 20, 255)))