Fog of War works but it's in the wrong place and needs to be based on light.

master
Zed A. Shaw 23 hours ago
parent 2802a44ba4
commit d264760405
  1. 23
      gui/map_view.cpp
  2. 1
      gui/map_view.hpp
  3. 12
      systems.cpp
  4. 2
      systems.hpp
  5. 5
      tests/map.cpp

@ -13,9 +13,8 @@
#include <fstream> #include <fstream>
#include "palette.hpp" #include "palette.hpp"
constexpr const int map_width=13; constexpr const int MAP_WIDTH=13;
constexpr const int map_height=13; constexpr const int MAP_HEIGHT=13;
namespace gui { namespace gui {
using namespace components; using namespace components;
@ -25,7 +24,8 @@ namespace gui {
$level(level), $level(level),
$map_render(std::make_shared<sf::RenderTexture>()), $map_render(std::make_shared<sf::RenderTexture>()),
$map_sprite($map_render->getTexture()), $map_sprite($map_render->getTexture()),
$map_tiles(matrix::make(map_width, map_height)) $map_tiles(matrix::make(MAP_WIDTH, MAP_HEIGHT)),
$fow(matrix::make($level.map->width(), $level.map->height()))
{ {
auto player = $level.world->get_the<Player>(); auto player = $level.world->get_the<Player>();
$player_display = $level.world->get<Tile>(player.entity).display; $player_display = $level.world->get<Tile>(player.entity).display;
@ -33,6 +33,7 @@ namespace gui {
void MapViewUI::update_level(GameLevel &level) { void MapViewUI::update_level(GameLevel &level) {
$level = level; $level = level;
$fow = matrix::make($level.map->width(), $level.map->height());
} }
void MapViewUI::init() { void MapViewUI::init() {
@ -44,7 +45,7 @@ namespace gui {
$gui.set<Rectangle>($log_to, {10, THEME.DARK_MID, THEME.BORDER_COLOR, 10}); $gui.set<Rectangle>($log_to, {10, THEME.DARK_MID, THEME.BORDER_COLOR, 10});
$gui.set<Textual>($log_to, {L"Welcome to the Game!", 25, THEME.TEXT_COLOR, 10}); $gui.set<Textual>($log_to, {L"Welcome to the Game!", 25, THEME.TEXT_COLOR, 10});
auto map_cell = lel::center(MAP_TILE_DIM * map_width, MAP_TILE_DIM * map_height, $gui.cell_for("map_grid")); auto map_cell = lel::center(MAP_TILE_DIM * MAP_WIDTH, MAP_TILE_DIM * MAP_HEIGHT, $gui.cell_for("map_grid"));
$map_sprite.setPosition({(float)map_cell.x, (float)map_cell.y + 30}); $map_sprite.setPosition({(float)map_cell.x, (float)map_cell.y + 30});
$gui.init(); $gui.init();
@ -62,7 +63,17 @@ namespace gui {
void MapViewUI::render(sf::RenderWindow &window, int compass_dir) { void MapViewUI::render(sf::RenderWindow &window, int compass_dir) {
$gui.render(window); $gui.render(window);
System::draw_map($level, $map_tiles, $entity_map); auto player = $level.world->get_the<components::Player>();
auto player_pos = $level.world->get<components::Position>(player.entity).location;
// NOTE: FoW is probably better done in the lighting system, because it illuminates where you've been. The light calcs could then simply set the light the player touches to 1 when it's run.
for(matrix::circle it{$fow, player_pos, 2.5}; it.next();) {
for(int x = it.left; x < it.right; x++) {
$fow[it.y][x] = 1;
}
}
System::draw_map($level, $map_tiles, $fow, $entity_map);
System::render_map($map_tiles, $entity_map, *$map_render, compass_dir, $player_display); System::render_map($map_tiles, $entity_map, *$map_render, compass_dir, $player_display);
$map_sprite.setTexture($map_render->getTexture(), true); $map_sprite.setTexture($map_render->getTexture(), true);
window.draw($map_sprite); window.draw($map_sprite);

@ -17,6 +17,7 @@ namespace gui {
std::shared_ptr<sf::RenderTexture> $map_render; std::shared_ptr<sf::RenderTexture> $map_render;
sf::Sprite $map_sprite; sf::Sprite $map_sprite;
matrix::Matrix $map_tiles; matrix::Matrix $map_tiles;
matrix::Matrix $fow;
MapViewUI(GameLevel &level); MapViewUI(GameLevel &level);
void init(); void init();

@ -526,7 +526,7 @@ bool System::inventory_occupied(GameLevel& level, Entity container_id, const std
} }
void System::draw_map(GameLevel& level, Matrix& grid, EntityGrid& entity_map) { void System::draw_map(GameLevel& level, Matrix& grid, Matrix& fow, EntityGrid& entity_map) {
World &world = *level.world; World &world = *level.world;
Map &map = *level.map; Map &map = *level.map;
size_t view_x = matrix::width(grid) - 1; size_t view_x = matrix::width(grid) - 1;
@ -547,7 +547,7 @@ void System::draw_map(GameLevel& level, Matrix& grid, EntityGrid& entity_map) {
size_t tile_y = size_t(it.y) + cam_orig.y; size_t tile_y = size_t(it.y) + cam_orig.y;
size_t tile_x = size_t(it.x) + cam_orig.x; size_t tile_x = size_t(it.x) + cam_orig.x;
if(matrix::inbounds(tiles, tile_x, tile_y)) { if(matrix::inbounds(tiles, tile_x, tile_y) && fow[tile_y][tile_x]) {
size_t tid = tiles[tile_y][tile_x]; size_t tid = tiles[tile_y][tile_x];
grid[it.y][it.x] = tile_set[tid]; grid[it.y][it.x] = tile_set[tid];
} else { } else {
@ -558,12 +558,16 @@ void System::draw_map(GameLevel& level, Matrix& grid, EntityGrid& entity_map) {
// then get the enemy/item/device tiles and fill those in // then get the enemy/item/device tiles and fill those in
world.query<Position, Tile>([&](auto, auto &pos, auto &entity_glyph) { world.query<Position, Tile>([&](auto, auto &pos, auto &entity_glyph) {
// BUG: don't I have a within bounds macro somewhere? // BUG: don't I have a within bounds macro somewhere?
if(pos.location.x >= cam_orig.x && pos.location.x <= cam_orig.x + view_x if(pos.location.x >= cam_orig.x
&& pos.location.y >= cam_orig.y && pos.location.y <= cam_orig.y + view_y) && pos.location.x <= cam_orig.x + view_x
&& pos.location.y >= cam_orig.y
&& pos.location.y <= cam_orig.y + view_y)
{ {
if(fow[pos.location.y][pos.location.x]) {
Point view_pos = map.map_to_camera(pos.location, cam_orig); Point view_pos = map.map_to_camera(pos.location, cam_orig);
entity_map.insert_or_assign(view_pos, entity_glyph.display); entity_map.insert_or_assign(view_pos, entity_glyph.display);
} }
}
}); });
} }

@ -39,6 +39,6 @@ namespace System {
void inventory_swap(GameLevel &level, Entity container_id, const std::string& a_name, const std::string &b_name); void inventory_swap(GameLevel &level, Entity container_id, const std::string& a_name, const std::string &b_name);
bool inventory_occupied(GameLevel& level, Entity container_id, const std::string& name); bool inventory_occupied(GameLevel& level, Entity container_id, const std::string& name);
void draw_map(GameLevel& level, Matrix& grid, EntityGrid& entity_map); void draw_map(GameLevel& level, Matrix& grid, Matrix& fow, EntityGrid& entity_map);
void render_map(Matrix& tiles, EntityGrid& entity_map, sf::RenderTexture& render, int compass_dir, wchar_t player_display); void render_map(Matrix& tiles, EntityGrid& entity_map, sf::RenderTexture& render, int compass_dir, wchar_t player_display);
} }

@ -100,8 +100,11 @@ TEST_CASE("map image test", "[map-sprite]") {
for(matrix::each_row it{level.map->walls()}; it.next();) { for(matrix::each_row it{level.map->walls()}; it.next();) {
player_pos.location.x = it.x; player_pos.location.x = it.x;
player_pos.location.y = it.y; player_pos.location.y = it.y;
size_t width = level.map->width();
size_t height = level.map->height();
System::draw_map(level, map_tiles, entity_map); Matrix fow = matrix::make(width, height);
System::draw_map(level, map_tiles, fow, entity_map);
System::render_map(map_tiles, entity_map, *render, 2, player_display); System::render_map(map_tiles, entity_map, *render, 2, player_display);
#ifdef TEST_RENDER #ifdef TEST_RENDER

Loading…
Cancel
Save