imporved wall rendering and added floor rendering

This commit is contained in:
Lukas Nöllemeyer 2024-08-18 13:28:14 +02:00
parent b23194ea46
commit f29f067aad
4 changed files with 40 additions and 31 deletions

View file

@ -41,5 +41,7 @@ ACTION_KEYS: Final = {
}
GRASS_CHAR: Final = ord(',')
FLOOR_CHAR: Final = ord('.')
WALL_CHAR: Final = ord('_')
VERTICAL_WALL_CHAR: Final = ord('|')

View file

@ -6,13 +6,14 @@ from random import Random
import attrs
import tcod.console
import tcod.constants
import tcod.ecs
import tcod.event
from tcod.event import KeySym
from tcod.map import Map
import g
from game.components import Action, Gold, Graphic, Position
from game.constants import DIRECTION_KEYS, ACTION_KEYS
from game.constants import DIRECTION_KEYS, ACTION_KEYS, FLOOR_CHAR
from game.screens import Push, Screen, ScreenResult
from game.tags import IsDoor, IsItem, IsPlayer, IsActor
from game.constants import WALL_CHAR, VERTICAL_WALL_CHAR
@ -52,6 +53,18 @@ def _handle_action(player):
entity.components[Action](entity)
_recalc_fov(player_pos)
def _draw_entity(entity: tcod.ecs.Entity, camera_pos, camera_radius_x, camera_radius_y):
pos = entity.components[Position]
screen_pos = pos - camera_pos
if not (-camera_radius_x <= screen_pos.x < camera_radius_x\
and -camera_radius_y <= screen_pos.y < camera_radius_y):
return
map_pos = world_pos_to_map_pos(pos)
if g.world[None].components[Map].fov[map_pos.y, map_pos.x]:
graphic = entity.components[Graphic]
g.console.rgb[["ch", "fg"]][screen_pos.y + camera_radius_y, screen_pos.x + camera_radius_x] = graphic.ch, graphic.fg
@attrs.define()
class MainScreen(Screen):
"""Primary in-game state."""
@ -82,42 +95,35 @@ class MainScreen(Screen):
w = console.width//2
map: Map = g.world[None].components[Map]
# TODO: eigentlich wäre andersrum rendern schöner
# also nicht alle objekte zu rendern und dabei rauszufinden ob sie auf dem screen sind,
# sondern über alle screen zellen laufen, über prüfen ob es im fov ist und dann gucken ob es dort ein objekt
# gibt und es entsprechend rendern
def draw(e_pos, e_graph):
screen_pos = e_pos - camera_pos
map_pos = world_pos_to_map_pos(e_pos)
if (-w <= screen_pos.x < w\
and -h <= screen_pos.y < h):
if map.fov[map_pos.y, map_pos.x]:
graphic = e_graph
else:
graphic = Graphic(0x2591, (50, 50, 50))
if graphic.ch != 0:
console.rgb[["ch", "fg"]][screen_pos.y + h, screen_pos.x + w] = graphic.ch, graphic.fg
# Draw walls
doors = [ world_pos_to_map_pos(d.components[Position]) for d in g.world.Q.all_of(tags=[IsDoor]) ]
for (y, row) in enumerate(map.walkable):
for (x, val) in enumerate(row):
pos = map_pos_to_world_pos(Position(x,y))
ch = 0
if not val:
ch = VERTICAL_WALL_CHAR
if map.walkable[y+1,x] and not Position(x,y+1) in doors:
ch = WALL_CHAR
graphic = Graphic(ch)
draw(pos, graphic)
for i in range(console.width):
for j in range(console.height):
world_pos = Position(i-w,j-h)+camera_pos
map_pos = world_pos_to_map_pos(world_pos)
in_map = 0 <= map_pos.x < map.width and 0 <= map_pos.y < map.height
in_fov = in_map and map.fov[map_pos.y,map_pos.x]
if not in_fov:
console.rgb[["ch","fg"]][j, i] = 0x2591, (50,50,50)
continue
walkable = (not in_map) or map.walkable[map_pos.y, map_pos.x]
if walkable:
console.rgb[["ch","fg"]][j, i] = FLOOR_CHAR, (70,70,70)
continue
ch = VERTICAL_WALL_CHAR
if map.walkable[map_pos.y+1, map_pos.x] and world_pos+Position(0,1) not in doors:
ch = WALL_CHAR
console.rgb[["ch","fg"]][j, i] = ch, (255,255,255)
# draw all entities that are not actors
for entity in g.world.Q.all_of(components=[Position, Graphic]).none_of(tags=[IsActor]):
draw(entity.components[Position], entity.components[Graphic])
_draw_entity(entity, camera_pos, w, h)
# draw all actors
for actor in g.world.Q.all_of(components=[Position, Graphic], tags=[IsActor]).none_of(tags=[IsPlayer]):
draw(actor.components[Position], entity.components[Graphic])
_draw_entity(actor, camera_pos, w, h)
# draw the player
for player in g.world.Q.all_of(tags=[IsPlayer]):
draw(player.components[Position], player.components[Graphic])
_draw_entity(player, camera_pos, w, h)
if text := g.world[None].components.get(("Text", str)):
console.print(x=0, y=console.height - 1, string=text, fg=(255, 255, 255), bg=(0, 0, 0))

View file

@ -23,4 +23,6 @@ def valid_tileset():
tileset.set_tile(ord('|'), terraintiles.get_tile(ord('!')))
tileset.set_tile(ord('_'), terraintiles.get_tile(ord('0')))
tileset.set_tile(ord('\\'), terraintiles.get_tile(ord('/')))
tileset.set_tile(ord('.'), terraintiles.get_tile(2))
tileset.set_tile(ord(','), terraintiles.get_tile(11))
return tileset

View file

@ -37,7 +37,6 @@ def add_door(world, pos):
)
add_wall(world, pos)
def new_world() -> Registry:
"""Return a freshly generated world."""
world = Registry()