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.

main
Zed A. Shaw 1 month ago
parent 8a94108874
commit 9ac8da30ea
  1. 8
      lights.cpp
  2. 2
      lights.hpp
  3. 4
      main.cpp
  4. 16
      matrix.cpp
  5. 7
      matrix.hpp
  6. 2
      systems.cpp
  7. 6
      tests/matrix.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);

@ -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;

@ -33,7 +33,7 @@ void configure_world(DinkyECS::World &world, Map &game_map) {
world.set<Combat>(player.entity, {100, 10});
world.set<Tile>(player.entity, {config.PLAYER_TILE});
world.set<Inventory>(player.entity, {5});
world.set<LightSource>(player.entity, {6,1});
world.set<LightSource>(player.entity, {6,2.1});
auto enemy = world.entity();
world.set<Position>(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<Position>(wall_torch, {game_map.place_entity(4)});
world.set<LightSource>(wall_torch, {3,4});
world.set<LightSource>(wall_torch, {3,2.4});
world.set<Tile>(wall_torch, {""});
}

@ -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;

@ -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();
};

@ -144,7 +144,7 @@ void System::collision(DinkyECS::World &world, Player &player) {
world.send<Events::GUI>(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);

@ -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<size_t>(10, 13);
size_t height = Random::uniform<size_t>(10, 15);
int pos_mod = Random::uniform<int>(-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);
}
}
}

Loading…
Cancel
Save