From 1bb04b4562014945fb4f7c6ac43f30fc65cb1461 Mon Sep 17 00:00:00 2001 From: "Zed A. Shaw" Date: Sat, 23 Nov 2024 23:11:20 -0500 Subject: [PATCH] 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. --- gui.cpp | 19 +++++++++++++------ gui.hpp | 2 ++ map.cpp | 9 ++++++--- status.txt | 7 ++++++- systems.cpp | 31 ++++++++++++++++++++++++++++--- 5 files changed, 55 insertions(+), 13 deletions(-) diff --git a/gui.cpp b/gui.cpp index ceb0df7..7c10b81 100644 --- a/gui.cpp +++ b/gui.cpp @@ -32,6 +32,7 @@ using namespace ftxui; using namespace components; GUI::GUI(DinkyECS::World &world, Map& game_map) : + $darkness({1600,800}), $game_map(game_map), $log({{"Welcome to the game!"}}), $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_enemy_hit", "combat_enemy_hit.mp3"); $sounds.load("combat_miss", "combat_miss.mp3"); + + $light_test.loadFromFile("./assets/light_test.png"); + $darkness.setTexture(&$light_test); + resize_map(MAX_FONT_SIZE); } @@ -220,8 +225,8 @@ bool GUI::handle_ui_events() { void GUI::run_systems() { auto player = $world.get_the(); - System::enemy_pathing($world, $game_map, player); System::motion($world, $game_map); + System::enemy_pathing($world, $game_map, player); System::collision($world, player); System::death($world); } @@ -240,11 +245,13 @@ void GUI::shake() { void GUI::render_scene() { $renderer.clear(); - $status_ui.render(); - $renderer.draw($status_ui); $map_view.render(); $renderer.draw($map_view); + $status_ui.render(); + $renderer.draw($status_ui); + + $renderer.display(); } @@ -253,16 +260,16 @@ int GUI::main() { create_renderer(); run_systems(); - while($renderer.is_open()) { + do { render_scene(); if(handle_ui_events()) { run_systems(); + handle_world_events(); } - handle_world_events(); std::this_thread::sleep_for(10ms); - } + } while($renderer.is_open()); return 0; } diff --git a/gui.hpp b/gui.hpp index 7eec6be..f2f6514 100644 --- a/gui.hpp +++ b/gui.hpp @@ -39,6 +39,8 @@ struct ActionLog { const int GAME_MAP_POS = 600; class GUI { + sf::RectangleShape $darkness; + sf::Texture $light_test; string $status_text = "NOT DEAD"; Canvas $canvas; Map& $game_map; diff --git a/map.cpp b/map.cpp index fc423fd..329ee1b 100644 --- a/map.cpp +++ b/map.cpp @@ -178,10 +178,13 @@ bool Map::neighbors(Point &out, bool greater) { int cur = $paths[out.y][out.x]; // BUG: sometimes cur is in a wall so finding neighbors fails - - for(int i = 0; i < 4; ++i) { + for(size_t i = 0; i < dirs.size(); ++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) { out = {.x=dir.x, .y=dir.y}; diff --git a/status.txt b/status.txt index e44b30e..1df2ebd 100644 --- a/status.txt +++ b/status.txt @@ -1,8 +1,13 @@ 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: -* 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? * 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. diff --git a/systems.cpp b/systems.cpp index f8cf76b..9b17ba9 100644 --- a/systems.cpp +++ b/systems.cpp @@ -9,6 +9,8 @@ #include "ftxui/screen/terminal.hpp" // for SetColorSupport, Color, TrueColor #include "dbc.hpp" +const bool DEBUG_MAP=false; + using std::string; using namespace fmt; 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) { 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 + + // 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)); } }); @@ -142,7 +146,8 @@ void System::draw_map(DinkyECS::World &world, Map &game_map, ftxui::Canvas &canv const auto& player = world.get_the(); const auto& player_position = world.get(player.entity); 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_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) { 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 + // 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) { - 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 { - 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); + }); } } }