Add a map shroud over tiles and compute field of view based on player position!!!

This commit is contained in:
Eryn Wells 2022-05-04 09:22:40 -07:00
parent 25aa5506c8
commit 084385f8f2
3 changed files with 51 additions and 7 deletions

View file

@ -37,6 +37,8 @@ class Engine:
position = self.map.random_walkable_position()
self.entities.add(Entity('@', position=position, fg=tcod.yellow))
self.update_field_of_view()
def handle_event(self, event: tcod.event.Event):
action = self.event_handler.dispatch(event)
@ -45,8 +47,23 @@ class Engine:
action.perform(self, self.player)
self.update_field_of_view()
def print_to_console(self, console):
self.map.print_to_console(console)
for ent in self.entities:
# Only print entities that are in the field of view
if not self.map.visible[tuple(ent.position)]:
continue
ent.print_to_console(console)
def update_field_of_view(self) -> None:
'''Compute visible area of the map based on the player's position and point of view.'''
self.map.visible[:] = tcod.map.compute_fov(
self.map.tiles['transparent'],
tuple(self.player.position),
radius=8)
# Visible tiles should be added to the explored list
self.map.explored |= self.map.visible

View file

@ -6,7 +6,7 @@ import numpy as np
import random
import tcod
from .geometry import Direction, Point, Rect, Size
from .tile import Empty, Floor, Wall
from .tile import Empty, Floor, Shroud, Wall
from dataclasses import dataclass
from typing import Iterator, List, Optional
@ -19,6 +19,11 @@ class Map:
self.generator = RoomsAndCorridorsGenerator(size=size)
self.tiles = self.generator.generate()
# Map tiles that are currently visible to the player
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=False, order='F')
def random_walkable_position(self) -> Point:
# TODO: Include hallways
random_room: RectangularRoom = random.choice(self.generator.rooms)
@ -34,8 +39,15 @@ class Map:
return self.tiles[point.x, point.y]['walkable']
def print_to_console(self, console: tcod.Console) -> None:
'''Render the map to the console.'''
size = self.size
console.tiles_rgb[0:size.width, 0:size.height] = self.tiles["dark"]
# 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']],
default=Shroud)
class MapGenerator:
def __init__(self, *, size: Size):

View file

@ -20,11 +20,26 @@ tile_datatype = np.dtype([
('transparent', np.bool),
# A graphic struct (as above) defining the look of this tile when it's not visible
('dark', graphic_datatype),
# A graphic struct (as above) defining the look of this tile when it's visible
('light', graphic_datatype),
])
def tile(*, walkable: int, transparent: int, dark: Tuple[int, Tuple[int, int, int], Tuple[int, int ,int]]) -> np.ndarray:
return np.array((walkable, transparent, dark), dtype=tile_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)
Empty = tile(walkable=False, transparent=False, dark=(ord(' '), (255, 255, 255), (0, 0, 0)))
Floor = tile(walkable=True, transparent=True, dark=(ord(' '), (255, 255, 255), (50, 50, 150)))
Wall = tile(walkable=False, transparent=False, dark=(ord(' '), (255, 255, 255), (0, 0, 150)))
# 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)
Empty = tile(walkable=False, transparent=False,
dark=(ord(' '), (255, 255, 255), (0, 0, 0)),
light=(ord(' '), (255, 255, 255), (0, 0, 0)))
Floor = tile(walkable=True, transparent=True,
dark=(ord('·'), (80, 80, 100), (50, 50, 50)),
light=(ord('·'), (100, 100, 120), (80, 80, 100)))
Wall = tile(walkable=False, transparent=False,
dark=(ord(' '), (255, 255, 255), (0, 0, 150)),
light=(ord(' '), (255, 255, 255), (50, 50, 200)))