Tried to set the background color in the ftxui canvas and weirdly it started doing almost what I want with lighting, but I didn't write any code to do that. There's some bug in how I'm doing it that's causing it to set the colors...correctly. Must find out why.

main
Zed A. Shaw 10 hours ago
parent fb1fd9d8bc
commit 1bb04b4562
  1. 19
      gui.cpp
  2. 2
      gui.hpp
  3. 9
      map.cpp
  4. 7
      status.txt
  5. 31
      systems.cpp

@ -32,6 +32,7 @@ using namespace ftxui;
using namespace components; using namespace components;
GUI::GUI(DinkyECS::World &world, Map& game_map) : GUI::GUI(DinkyECS::World &world, Map& game_map) :
$darkness({1600,800}),
$game_map(game_map), $game_map(game_map),
$log({{"Welcome to the game!"}}), $log({{"Welcome to the game!"}}),
$status_ui(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT), $status_ui(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT),
@ -46,6 +47,10 @@ GUI::GUI(DinkyECS::World &world, Map& game_map) :
$sounds.load("combat_player_hit", "combat_player_hit.mp3"); $sounds.load("combat_player_hit", "combat_player_hit.mp3");
$sounds.load("combat_enemy_hit", "combat_enemy_hit.mp3"); $sounds.load("combat_enemy_hit", "combat_enemy_hit.mp3");
$sounds.load("combat_miss", "combat_miss.mp3"); $sounds.load("combat_miss", "combat_miss.mp3");
$light_test.loadFromFile("./assets/light_test.png");
$darkness.setTexture(&$light_test);
resize_map(MAX_FONT_SIZE); resize_map(MAX_FONT_SIZE);
} }
@ -220,8 +225,8 @@ bool GUI::handle_ui_events() {
void GUI::run_systems() { void GUI::run_systems() {
auto player = $world.get_the<Player>(); auto player = $world.get_the<Player>();
System::enemy_pathing($world, $game_map, player);
System::motion($world, $game_map); System::motion($world, $game_map);
System::enemy_pathing($world, $game_map, player);
System::collision($world, player); System::collision($world, player);
System::death($world); System::death($world);
} }
@ -240,11 +245,13 @@ void GUI::shake() {
void GUI::render_scene() { void GUI::render_scene() {
$renderer.clear(); $renderer.clear();
$status_ui.render();
$renderer.draw($status_ui);
$map_view.render(); $map_view.render();
$renderer.draw($map_view); $renderer.draw($map_view);
$status_ui.render();
$renderer.draw($status_ui);
$renderer.display(); $renderer.display();
} }
@ -253,16 +260,16 @@ int GUI::main() {
create_renderer(); create_renderer();
run_systems(); run_systems();
while($renderer.is_open()) { do {
render_scene(); render_scene();
if(handle_ui_events()) { if(handle_ui_events()) {
run_systems(); run_systems();
handle_world_events();
} }
handle_world_events();
std::this_thread::sleep_for(10ms); std::this_thread::sleep_for(10ms);
} } while($renderer.is_open());
return 0; return 0;
} }

@ -39,6 +39,8 @@ struct ActionLog {
const int GAME_MAP_POS = 600; const int GAME_MAP_POS = 600;
class GUI { class GUI {
sf::RectangleShape $darkness;
sf::Texture $light_test;
string $status_text = "NOT DEAD"; string $status_text = "NOT DEAD";
Canvas $canvas; Canvas $canvas;
Map& $game_map; Map& $game_map;

@ -178,10 +178,13 @@ bool Map::neighbors(Point &out, bool greater) {
int cur = $paths[out.y][out.x]; int cur = $paths[out.y][out.x];
// BUG: sometimes cur is in a wall so finding neighbors fails // BUG: sometimes cur is in a wall so finding neighbors fails
for(size_t i = 0; i < dirs.size(); ++i) {
for(int i = 0; i < 4; ++i) {
Point dir = dirs[i]; Point dir = dirs[i];
int diff = inmap(dir.x, dir.y) ? cur - $paths[dir.y][dir.x] : -1000; int target = inmap(dir.x, dir.y) ? $paths[dir.y][dir.x] : 1000;
if(target == 1000) continue; // skip unpathable stuff
int diff = cur - target;
if(diff == 1) { if(diff == 1) {
out = {.x=dir.x, .y=dir.y}; out = {.x=dir.x, .y=dir.y};

@ -1,8 +1,13 @@
TODAY'S GOAL: TODAY'S GOAL:
* Use d-map to create a mapping of light strength and use that to alter the value of colors in the map.
* Make it possible to visualize the d-map when I need to.
TODO: TODO:
* Keep panel unified by implementing border and backing on grids too. * Neighbors needs a rewrite
* Neighbors algo isn't using greater parameter
* Look in system.cpp::draw_map for notes on a Lighting system.
* Write a method for renderer that can translate coordinates.
* Can std::any be defaulted to a noop in the events? * Can std::any be defaulted to a noop in the events?
* Save file isn't saving gold. * Save file isn't saving gold.
* Inventory needs to be better, but need some kinds of "weapons" or other loot to get and not just gold. * Inventory needs to be better, but need some kinds of "weapons" or other loot to get and not just gold.

@ -9,6 +9,8 @@
#include "ftxui/screen/terminal.hpp" // for SetColorSupport, Color, TrueColor #include "ftxui/screen/terminal.hpp" // for SetColorSupport, Color, TrueColor
#include "dbc.hpp" #include "dbc.hpp"
const bool DEBUG_MAP=false;
using std::string; using std::string;
using namespace fmt; using namespace fmt;
using namespace components; using namespace components;
@ -132,6 +134,8 @@ void System::draw_entities(DinkyECS::World &world, Map &game_map, ftxui::Canvas
&& pos.location.y >= cam_orig.y && pos.location.y <= cam_orig.y + view_y) { && pos.location.y >= cam_orig.y && pos.location.y <= cam_orig.y + view_y) {
Point loc = game_map.map_to_camera(pos.location, cam_orig); Point loc = game_map.map_to_camera(pos.location, cam_orig);
// the 2 and 4 are from ftxui::Canvas since it does a kind of "subpixel" drawing // the 2 and 4 are from ftxui::Canvas since it does a kind of "subpixel" drawing
// BUG: this color is a made up BS color for seeing entities until I can work on them
canvas.DrawText(loc.x*2, loc.y*4, tile.chr, Color::RGB(255, 50, 50)); canvas.DrawText(loc.x*2, loc.y*4, tile.chr, Color::RGB(255, 50, 50));
} }
}); });
@ -142,7 +146,8 @@ void System::draw_map(DinkyECS::World &world, Map &game_map, ftxui::Canvas &canv
const auto& player = world.get_the<Player>(); const auto& player = world.get_the<Player>();
const auto& player_position = world.get<Position>(player.entity); const auto& player_position = world.get<Position>(player.entity);
Point start = game_map.center_camera(player_position.location, view_x, view_y); Point start = game_map.center_camera(player_position.location, view_x, view_y);
Matrix &walls = game_map.walls(); auto &walls = game_map.walls();
auto &paths = game_map.paths();
size_t end_x = std::min(view_x, game_map.width() - start.x); 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); size_t end_y = std::min(view_y, game_map.height() - start.y);
@ -151,10 +156,30 @@ void System::draw_map(DinkyECS::World &world, Map &game_map, ftxui::Canvas &canv
for(size_t y = 0; y < end_y; ++y) { for(size_t y = 0; y < end_y; ++y) {
string tile = walls[start.y+y][start.x+x] == 1 ? config.WALL_TILE : config.FLOOR_TILE; string tile = walls[start.y+y][start.x+x] == 1 ? config.WALL_TILE : config.FLOOR_TILE;
// the 2 and 4 are from ftxui::Canvas since it does a kind of "subpixel" drawing // the 2 and 4 are from ftxui::Canvas since it does a kind of "subpixel" drawing
// LIGHT: if tile is in light then color ++ otherwise --
// LIGHT: is put into the/a collision map and if a cell is a light's neighbor
// it gets brighter.
const int LIGHT_MIN = 30;
const int LIGHT_MAX = 180;
Point light_at{start.x+x, start.y+y};
int dnum = paths[light_at.y][light_at.x];
int light_value = std::clamp(255 - (dnum * 75), LIGHT_MIN, LIGHT_MAX);
if(tile == config.WALL_TILE) { if(tile == config.WALL_TILE) {
canvas.DrawText(x * 2, y * 4, tile, Color::RGB(70, 70, 70)); canvas.DrawText(x * 2, y * 4, tile, Color::HSV(230, 20, 20));
} else if(DEBUG_MAP) {
string num = format("{:x}", dnum);
num = num.size() > 2 ? "*" : num;
canvas.DrawText(x * 2, y * 4, num, Color::HSV(dnum * 20, 150, light_value));
} else { } else {
canvas.DrawText(x * 2, y * 4, tile, Color::RGB(20, 20, 20)); // floor tile or similar
// BUG: no idea why this works but this actually implements decent light
canvas.DrawText(x * 2, y * 4, tile, [&, light_value](auto &pixel) {
pixel.foreground_color = Color::HSV(30, light_value / 2, light_value);
pixel.background_color = Color::HSV(30, 20, light_value);
});
} }
} }
} }

Loading…
Cancel
Save