Add a map shroud over tiles and compute field of view based on player position!!!
This commit is contained in:
		
							parent
							
								
									25aa5506c8
								
							
						
					
					
						commit
						084385f8f2
					
				
					 3 changed files with 51 additions and 7 deletions
				
			
		| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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):
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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)))
 | 
			
		||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue