From 9ac8da30ea6a1db161d9f9d7732917e33f459f42 Mon Sep 17 00:00:00 2001 From: "Zed A. Shaw" Date: Wed, 25 Dec 2024 06:03:11 -0500 Subject: [PATCH] Circle adjusted to work better but now I think hirdrac was right that it's easier to just calculate a distance from center and use that to determine light levels rather than a whole dpath. --- lights.cpp | 8 ++++---- lights.hpp | 2 +- main.cpp | 4 ++-- matrix.cpp | 16 ++++++++-------- matrix.hpp | 7 ++++--- systems.cpp | 2 +- tests/matrix.cpp | 6 +++--- 7 files changed, 23 insertions(+), 22 deletions(-) diff --git a/lights.cpp b/lights.cpp index d3c70b3..9110a99 100644 --- a/lights.cpp +++ b/lights.cpp @@ -7,7 +7,7 @@ using std::vector; namespace lighting { void LightRender::render_circle_light(LightSource source, Point at, PointList &has_light) { - for(matrix::circle it{$lightmap, at, source.distance + 1}; it.next();) { + for(matrix::circle it{$lightmap, at, source.radius}; it.next();) { for(int x = it.left; x < it.right; x++) { $lightmap[it.y][x] = light_level(source.strength, x, it.y); has_light.push_back({(size_t)x, (size_t)it.y}); @@ -25,7 +25,7 @@ namespace lighting { } void LightRender::render_square_light(LightSource source, Point at, PointList &has_light) { - for(matrix::in_box it{$lightmap, at.x, at.y, (size_t)source.distance}; it.next();) { + for(matrix::in_box it{$lightmap, at.x, at.y, (size_t)floor(source.radius)}; it.next();) { if($paths.$paths[it.y][it.x] != WALL_PATH_LIMIT) { $lightmap[it.y][it.x] = light_level(source.strength, it.x, it.y); has_light.push_back({it.x, it.y}); @@ -38,9 +38,9 @@ namespace lighting { clear_light_target(at); PointList has_light; - if(source.distance == 0) { + if(source.radius < 1.5f) { render_compass_light(source, at, has_light); - } else if(source.distance == 1) { + } else if(source.radius < 2.0f) { render_square_light(source, at, has_light); } else { render_circle_light(source, at, has_light); diff --git a/lights.hpp b/lights.hpp index 48e3ee8..a7c9572 100644 --- a/lights.hpp +++ b/lights.hpp @@ -10,7 +10,7 @@ namespace lighting { struct LightSource { int strength = 0; // lower is better - int distance = 1; // higher is farther, in squares + float radius = 1.0f; // higher is farther, in squares }; const int MIN = 50; diff --git a/main.cpp b/main.cpp index b00c5a6..2d138fd 100644 --- a/main.cpp +++ b/main.cpp @@ -33,7 +33,7 @@ void configure_world(DinkyECS::World &world, Map &game_map) { world.set(player.entity, {100, 10}); world.set(player.entity, {config.PLAYER_TILE}); world.set(player.entity, {5}); - world.set(player.entity, {6,1}); + world.set(player.entity, {6,2.1}); auto enemy = world.entity(); world.set(enemy, {game_map.place_entity(1)}); @@ -55,7 +55,7 @@ void configure_world(DinkyECS::World &world, Map &game_map) { auto wall_torch = world.entity(); world.set(wall_torch, {game_map.place_entity(4)}); - world.set(wall_torch, {3,4}); + world.set(wall_torch, {3,2.4}); world.set(wall_torch, {"☀"}); } diff --git a/matrix.cpp b/matrix.cpp index edc4681..f79df5e 100644 --- a/matrix.cpp +++ b/matrix.cpp @@ -180,24 +180,24 @@ namespace matrix { } - circle::circle(Matrix &mat, Point center, int radius) : - center(center), radius(radius) + circle::circle(Matrix &mat, Point center, float radius) : + center_x(center.x), center_y(center.y), radius(radius) { width = matrix::width(mat); height = matrix::height(mat); - top = max(int(center.y - radius), 0); - bottom = min(int(center.y + radius), height); + top = max(int(floor(center_y - radius)), 0); + bottom = min(int(floor(center_y + radius)), height - 1); y = top; } bool circle::next() { y++; - if(y < bottom) { - dy = y - center.y; + if(y <= bottom) { + dy = y - center_y; dx = floor(sqrt(radius * radius - dy * dy)); - left = max(0, int(center.x - dx)); - right = min(width, int(center.x + dx)); + left = max(0, int(center_x) - dx); + right = min(width, int(center_x) + dx + 1); return true; } else { return false; diff --git a/matrix.hpp b/matrix.hpp index 710a1ef..9482f1f 100644 --- a/matrix.hpp +++ b/matrix.hpp @@ -118,8 +118,9 @@ namespace matrix { }; struct circle { - Point center; - int radius = 0; + float center_x; + float center_y; + float radius = 0.0f; int y = 0; int dx = 0; int dy = 0; @@ -130,7 +131,7 @@ namespace matrix { int width = 0; int height = 0; - circle(Matrix &mat, Point center, int radius); + circle(Matrix &mat, Point center, float radius); void update(); bool next(); }; diff --git a/systems.cpp b/systems.cpp index f306f43..96b7db3 100644 --- a/systems.cpp +++ b/systems.cpp @@ -144,7 +144,7 @@ void System::collision(DinkyECS::World &world, Player &player) { world.send(Events::GUI::LOOT, entity, loot); inventory.gold += loot.amount; light.strength = 4; - light.distance = 2; + light.radius = 2.3; collider.remove(loot_pos.location); } else { println("UNKNOWN COLLISION TYPE {}", entity); diff --git a/tests/matrix.cpp b/tests/matrix.cpp index 5ff10ff..360651f 100644 --- a/tests/matrix.cpp +++ b/tests/matrix.cpp @@ -226,7 +226,7 @@ TEST_CASE("prototype line algorithm", "[matrix:line]") { } TEST_CASE("prototype circle algorithm", "[matrix:circle]") { - for(int count = 0; count < 2000; count++) { + for(int count = 0; count < 2; count++) { size_t width = Random::uniform(10, 13); size_t height = Random::uniform(10, 15); int pos_mod = Random::uniform(-3,3); @@ -234,7 +234,7 @@ TEST_CASE("prototype circle algorithm", "[matrix:circle]") { // create a target for the paths Point start{.x=map.width() / 2 + pos_mod, .y=map.height()/2 + pos_mod}; - for(int radius = 2; radius < 10; radius++) { + for(float radius = 1.0f; radius < 4.0f; radius += 0.1f) { // use an empty map Matrix result = map.walls(); @@ -250,7 +250,7 @@ TEST_CASE("prototype circle algorithm", "[matrix:circle]") { } } - // matrix::dump("RESULT AFTER CIRCLE", result, start.x, start.y); + matrix::dump(format("RESULT AFTER CIRCLE radius {}", radius), result, start.x, start.y); } } }