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('_') WALL_CHAR: Final = ord('_')
VERTICAL_WALL_CHAR: Final = ord('|') VERTICAL_WALL_CHAR: Final = ord('|')

View file

@ -6,13 +6,14 @@ from random import Random
import attrs import attrs
import tcod.console import tcod.console
import tcod.constants import tcod.constants
import tcod.ecs
import tcod.event import tcod.event
from tcod.event import KeySym from tcod.event import KeySym
from tcod.map import Map from tcod.map import Map
import g import g
from game.components import Action, Gold, Graphic, Position 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.screens import Push, Screen, ScreenResult
from game.tags import IsDoor, IsItem, IsPlayer, IsActor from game.tags import IsDoor, IsItem, IsPlayer, IsActor
from game.constants import WALL_CHAR, VERTICAL_WALL_CHAR from game.constants import WALL_CHAR, VERTICAL_WALL_CHAR
@ -52,6 +53,18 @@ def _handle_action(player):
entity.components[Action](entity) entity.components[Action](entity)
_recalc_fov(player_pos) _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() @attrs.define()
class MainScreen(Screen): class MainScreen(Screen):
"""Primary in-game state.""" """Primary in-game state."""
@ -82,42 +95,35 @@ class MainScreen(Screen):
w = console.width//2 w = console.width//2
map: Map = g.world[None].components[Map] 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 # Draw walls
doors = [ world_pos_to_map_pos(d.components[Position]) for d in g.world.Q.all_of(tags=[IsDoor]) ] 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 i in range(console.width):
for (x, val) in enumerate(row): for j in range(console.height):
pos = map_pos_to_world_pos(Position(x,y)) world_pos = Position(i-w,j-h)+camera_pos
ch = 0 map_pos = world_pos_to_map_pos(world_pos)
if not val: 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 ch = VERTICAL_WALL_CHAR
if map.walkable[y+1,x] and not Position(x,y+1) in doors: if map.walkable[map_pos.y+1, map_pos.x] and world_pos+Position(0,1) not in doors:
ch = WALL_CHAR ch = WALL_CHAR
graphic = Graphic(ch) console.rgb[["ch","fg"]][j, i] = ch, (255,255,255)
draw(pos, graphic)
# draw all entities that are not actors # draw all entities that are not actors
for entity in g.world.Q.all_of(components=[Position, Graphic]).none_of(tags=[IsActor]): 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 # draw all actors
for actor in g.world.Q.all_of(components=[Position, Graphic], tags=[IsActor]).none_of(tags=[IsPlayer]): 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 # draw the player
for player in g.world.Q.all_of(tags=[IsPlayer]): 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)): 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)) 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('!')))
tileset.set_tile(ord('_'), terraintiles.get_tile(ord('0'))) tileset.set_tile(ord('_'), terraintiles.get_tile(ord('0')))
tileset.set_tile(ord('\\'), terraintiles.get_tile(ord('/'))) 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 return tileset

View file

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