From 16f8d12f4cc9b2b74fb7c564dfe3d235736c96ba Mon Sep 17 00:00:00 2001 From: Kayne Ruse Date: Fri, 21 Mar 2025 12:06:08 +1100 Subject: [PATCH] FOV working --- source/engine.py | 27 +++++++++++++++++++++++++-- source/floor_map.py | 13 ++++++++++++- source/procgen.py | 3 +-- source/tile_types.py | 4 +++- 4 files changed, 41 insertions(+), 6 deletions(-) diff --git a/source/engine.py b/source/engine.py index b378962..a53a067 100644 --- a/source/engine.py +++ b/source/engine.py @@ -2,17 +2,26 @@ from typing import Any, Iterable from tcod.context import Context from tcod.console import Console +from tcod.map import compute_fov from entity import Entity from floor_map import FloorMap #TODO: replace with "DungeonMap" class Engine: def __init__(self, floor_map: FloorMap): - from event_handler import EventHandler + from event_handler import EventHandler #here to prevent circular imports self.event_handler = EventHandler(self) self.player = Entity(0, 0, "@", (255, 255, 255)) self.floor_map = floor_map + self.entities: Iterable[Entity] = [] + + #spawn the player, add to render list + self.player.x, self.player.y = self.floor_map.spawn + self.entities.append(self.player) + + #kick off the render + self.update_fov() def handle_events(self, events: Iterable[Any]) -> None: for event in events: @@ -23,10 +32,24 @@ class Engine: action.apply(self) + self.update_fov() #update before the next action + + def update_fov(self): + self.floor_map.visible[:] = compute_fov( + self.floor_map.tiles["transparent"], + (self.player.x, self.player.y), + radius = 8, + ) + + #add the visible tiles to the explored list + self.floor_map.explored |= self.floor_map.visible + def render(self, context: Context, console: Console) -> None: self.floor_map.render(console) - console.print(self.player.x, self.player.y, self.player.char, fg=self.player.color) + for entity in self.entities: + if self.floor_map.visible[entity.x, entity.y]: + console.print(entity.x, entity.y, entity.char, fg=entity.color) #send to the screen context.present(console) diff --git a/source/floor_map.py b/source/floor_map.py index a3d9ecb..6686e12 100644 --- a/source/floor_map.py +++ b/source/floor_map.py @@ -1,3 +1,5 @@ +from typing import Tuple + import numpy as np from tcod.console import Console @@ -10,8 +12,17 @@ class FloorMap: self.height = height self.tiles = np.full((width, height), fill_value=tile_types.wall, order="F") + self.visible = np.full((width, height), fill_value=False, order="F") + self.explored = np.full((width, height), fill_value=False, order="F") + + self.spawn: Tuple[int, int] = 0, 0 + def in_bounds(self, x: int, y: int) -> bool: return 0 <= x < self.width and 0 <= y < self.height def render(self, console: Console) -> None: - console.rgb[0:self.width, 0:self.height] = self.tiles["dark"] \ No newline at end of file + console.rgb[0:self.width, 0:self.height] = np.select( + condlist = [self.visible, self.explored], + choicelist = [self.tiles["light"], self.tiles["dark"]], + default = tile_types.SHROUD + ) \ No newline at end of file diff --git a/source/procgen.py b/source/procgen.py index 9323cab..df09624 100644 --- a/source/procgen.py +++ b/source/procgen.py @@ -72,8 +72,7 @@ def generate_floor_map(map_width: int, map_height: int, room_width_max: int, roo floor_map.tiles[new_room.inner] = tile_types.floor if len(rooms) == 0: - # TODO: specify player spawn point - pass + floor_map.spawn = new_room.center else: for x, y in make_corridor(rooms[-1].center, new_room.center): floor_map.tiles[x, y] = tile_types.floor diff --git a/source/tile_types.py b/source/tile_types.py index 9b310b5..8046034 100644 --- a/source/tile_types.py +++ b/source/tile_types.py @@ -16,7 +16,7 @@ tile_dt = np.dtype( ("walkable", np.bool), ("transparent", np.bool), ("light", graphics_dt), #when this tile is in FOV - ("dark", graphics_dt), #when this tile is *not* in FOV + ("dark", graphics_dt), #when this tile *was* in FOV ] ) @@ -24,6 +24,8 @@ def new_tile(*, walkable: np.bool, transparent: np.bool, light: graphics_dt, dar return np.array((walkable, transparent, light, dark), dtype = tile_dt) #list of tile types +SHROUD = np.array((ord(" "), (255, 255, 255), (0, 0, 0)), dtype=graphics_dt) + wall = new_tile( walkable=False, transparent=False,