I think the actual map drawing is more of a view thing than in the system, so I've moved it to the MapViewUI out of system.

main
Zed A. Shaw 10 months ago
parent 380e18b91a
commit 5adeb4e078
  1. 40
      gui.cpp
  2. 1
      gui.hpp
  3. 37
      systems.cpp
  4. 1
      systems.hpp
  5. 41
      tests/render.cpp

@ -84,10 +84,48 @@ MapViewUI::MapViewUI(DinkyECS::World& world, LightRender& lights, Map& game_map)
$world(world), $lights(lights), $game_map(game_map)
{}
void MapViewUI::draw_map() {
const auto& debug = $world.get_the<Debug>();
const auto& player = $world.get_the<Player>();
const auto& player_position = $world.get<Position>(player.entity);
Point start = $game_map.center_camera(player_position.location, width, height);
auto &tiles = $game_map.tiles();
auto &paths = $game_map.paths();
auto &lighting = $lights.lighting();
// WARN: this is exploiting that -1 in size_t becomes largest
size_t end_x = std::min(size_t(width), $game_map.width() - start.x);
size_t end_y = std::min(size_t(height), $game_map.height() - start.y);
for(size_t y = 0; y < end_y; ++y) {
for(size_t x = 0; x < end_x; ++x) {
const TileCell& tile = tiles.at(start.x+x, start.y+y);
// light value is an integer that's a percent
float light_value = debug.LIGHT ? 80 * PERCENT : lighting[start.y+y][start.x+x] * PERCENT;
int dnum = debug.PATHS ? paths[start.y+y][start.x+x] : WALL_PATH_LIMIT;
if(debug.PATHS && dnum != WALL_PATH_LIMIT) {
string num = dnum > 15 ? "*" : format("{:x}", dnum);
$canvas.DrawText(x * 2, y * 4, num, [dnum, tile, light_value](auto &pixel) {
pixel.foreground_color = Color::HSV(dnum * 20, 150, 200);
pixel.background_color = Color::HSV(30, 20, tile.bg_v * 50 * PERCENT);
});
} else {
$canvas.DrawText(x * 2, y * 4, tile.display, [tile, light_value](auto &pixel) {
pixel.foreground_color = Color::HSV(tile.fg_h, tile.fg_s, tile.fg_v * light_value);
pixel.background_color = Color::HSV(tile.bg_h, tile.bg_s, tile.bg_v * light_value);
});
}
}
}
System::draw_entities($world, $game_map, lighting, $canvas, start, width, height);
}
void MapViewUI::create_render() {
set_renderer(Renderer([&] {
System::draw_map($world, $game_map, $lights.lighting(), $canvas, width, height);
draw_map();
return canvas($canvas);
}));
}

@ -82,6 +82,7 @@ class MapViewUI : public Panel {
MapViewUI(DinkyECS::World& world, LightRender& lights, Map& game_map);
void create_render();
void resize_canvas();
void draw_map();
};
class GUI {

@ -173,40 +173,3 @@ void System::draw_entities(DinkyECS::World &world, Map &game_map, const Matrix &
}
});
}
void System::draw_map(DinkyECS::World &world, Map &game_map, const Matrix &lighting, ftxui::Canvas &canvas, size_t view_x, size_t view_y) {
const auto& debug = world.get_the<Debug>();
const auto& player = world.get_the<Player>();
const auto& player_position = world.get<Position>(player.entity);
Point start = game_map.center_camera(player_position.location, view_x, view_y);
auto &tiles = game_map.tiles();
auto &paths = game_map.paths();
size_t end_x = std::min(view_x, game_map.width() - start.x);
size_t end_y = std::min(view_y, game_map.height() - start.y);
for(size_t y = 0; y < end_y; ++y) {
for(size_t x = 0; x < end_x; ++x) {
const TileCell& tile = tiles.at(start.x+x, start.y+y);
// light value is an integer that's a percent
float light_value = debug.LIGHT ? 80 * PERCENT : lighting[start.y+y][start.x+x] * PERCENT;
int dnum = debug.PATHS ? paths[start.y+y][start.x+x] : WALL_PATH_LIMIT;
if(debug.PATHS && dnum != WALL_PATH_LIMIT) {
string num = dnum > 15 ? "*" : format("{:x}", dnum);
canvas.DrawText(x * 2, y * 4, num, [dnum, tile, light_value](auto &pixel) {
pixel.foreground_color = Color::HSV(dnum * 20, 150, 200);
pixel.background_color = Color::HSV(30, 20, tile.bg_v * 50 * PERCENT);
});
} else {
canvas.DrawText(x * 2, y * 4, tile.display, [tile, light_value](auto &pixel) {
pixel.foreground_color = Color::HSV(tile.fg_h, tile.fg_s, tile.fg_v * light_value);
pixel.background_color = Color::HSV(tile.bg_h, tile.bg_s, tile.bg_v * light_value);
});
}
}
}
System::draw_entities(world, game_map, lighting, canvas, start, view_x, view_y);
}

@ -14,7 +14,6 @@ namespace System {
void collision(DinkyECS::World &world, Player &player);
void death(DinkyECS::World &world);
void enemy_pathing(DinkyECS::World &world, Map &game_map, Player &player);
void draw_map(DinkyECS::World &world, Map &game_map, const Matrix &lighting, ftxui::Canvas &canvas, size_t view_x, size_t view_y);
void draw_entities(DinkyECS::World &world, Map &game_map, const Matrix &lighting, ftxui::Canvas &canvas, const Point &cam_orig, size_t view_x, size_t view_y);
void init_positions(DinkyECS::World &world);
}

@ -41,43 +41,6 @@ TEST_CASE("can render a text panel", "[render]") {
renderer.close();
}
TEST_CASE("can render a text", "[render]") {
SFMLRender renderer;
renderer.init_terminal();
DinkyECS::World world;
save::load_configs(world);
const auto& config = world.get_the<MapConfig>();
Panel map_view(0, 0, 20, 20, true);
Map map(20,20);
WorldBuilder builder(map);
builder.generate();
Player player{world.entity()};
world.set_the<Debug>({});
world.set_the<Player>(player);
world.set<Tile>(player.entity, {config.PLAYER_TILE});
world.set<LightSource>(player.entity, {6,1});
world.set<Position>(player.entity, {map.place_entity(0)});
LightRender lights(map.width(), map.height());
Canvas map_canvas(map_view.width * 2, map_view.height * 4);
map_view.set_renderer(Renderer([&] {
System::draw_map(world, map, lights.lighting(), map_canvas, map_view.width, map_view.height);
return canvas(map_canvas);
}));
run_renderer(renderer, map_view);
for(int i = 2; i < 14; i++) {
renderer.resize_grid(i * 10, map_view);
map_canvas = Canvas(map_view.width * 2, map_view.height * 4);
run_renderer(renderer, map_view);
}
renderer.close();
TEST_CASE("can render a grid", "[render]") {
dbc::log("!!!! NEEDS A REWRITE");
}