imporved wall rendering and added floor rendering
This commit is contained in:
parent
b23194ea46
commit
f29f067aad
4 changed files with 40 additions and 31 deletions
|
|
@ -41,5 +41,7 @@ ACTION_KEYS: Final = {
|
|||
|
||||
}
|
||||
|
||||
GRASS_CHAR: Final = ord(',')
|
||||
FLOOR_CHAR: Final = ord('.')
|
||||
WALL_CHAR: Final = ord('_')
|
||||
VERTICAL_WALL_CHAR: Final = ord('|')
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -37,7 +37,6 @@ def add_door(world, pos):
|
|||
)
|
||||
add_wall(world, pos)
|
||||
|
||||
|
||||
def new_world() -> Registry:
|
||||
"""Return a freshly generated world."""
|
||||
world = Registry()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue