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('_')
|
WALL_CHAR: Final = ord('_')
|
||||||
VERTICAL_WALL_CHAR: Final = ord('|')
|
VERTICAL_WALL_CHAR: Final = ord('|')
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
ch = VERTICAL_WALL_CHAR
|
in_fov = in_map and map.fov[map_pos.y,map_pos.x]
|
||||||
if map.walkable[y+1,x] and not Position(x,y+1) in doors:
|
if not in_fov:
|
||||||
ch = WALL_CHAR
|
console.rgb[["ch","fg"]][j, i] = 0x2591, (50,50,50)
|
||||||
graphic = Graphic(ch)
|
continue
|
||||||
draw(pos, graphic)
|
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
|
# 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))
|
||||||
|
|
|
||||||
|
|
@ -17,10 +17,12 @@ def valid_tileset():
|
||||||
terraintiles = tcod.tileset.load_tilesheet(
|
terraintiles = tcod.tileset.load_tilesheet(
|
||||||
"Oryx/oryx_roguelike_2.0/Terrain.png", columns=16, rows=11, charmap=tcod.tileset.CHARMAP_CP437
|
"Oryx/oryx_roguelike_2.0/Terrain.png", columns=16, rows=11, charmap=tcod.tileset.CHARMAP_CP437
|
||||||
)
|
)
|
||||||
|
|
||||||
tileset.set_tile(ord('@'), monstertiles.get_tile(1))
|
tileset.set_tile(ord('@'), monstertiles.get_tile(1))
|
||||||
tileset.set_tile(ord('/'), terraintiles.get_tile(ord('?')))
|
tileset.set_tile(ord('/'), terraintiles.get_tile(ord('?')))
|
||||||
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
|
||||||
|
|
|
||||||
|
|
@ -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()
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue