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.
This commit is contained in:
parent
8a94108874
commit
9ac8da30ea
7 changed files with 23 additions and 22 deletions
|
@ -7,7 +7,7 @@ using std::vector;
|
||||||
namespace lighting {
|
namespace lighting {
|
||||||
|
|
||||||
void LightRender::render_circle_light(LightSource source, Point at, PointList &has_light) {
|
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++) {
|
for(int x = it.left; x < it.right; x++) {
|
||||||
$lightmap[it.y][x] = light_level(source.strength, x, it.y);
|
$lightmap[it.y][x] = light_level(source.strength, x, it.y);
|
||||||
has_light.push_back({(size_t)x, (size_t)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) {
|
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) {
|
if($paths.$paths[it.y][it.x] != WALL_PATH_LIMIT) {
|
||||||
$lightmap[it.y][it.x] = light_level(source.strength, it.x, it.y);
|
$lightmap[it.y][it.x] = light_level(source.strength, it.x, it.y);
|
||||||
has_light.push_back({it.x, it.y});
|
has_light.push_back({it.x, it.y});
|
||||||
|
@ -38,9 +38,9 @@ namespace lighting {
|
||||||
clear_light_target(at);
|
clear_light_target(at);
|
||||||
PointList has_light;
|
PointList has_light;
|
||||||
|
|
||||||
if(source.distance == 0) {
|
if(source.radius < 1.5f) {
|
||||||
render_compass_light(source, at, has_light);
|
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);
|
render_square_light(source, at, has_light);
|
||||||
} else {
|
} else {
|
||||||
render_circle_light(source, at, has_light);
|
render_circle_light(source, at, has_light);
|
||||||
|
|
|
@ -10,7 +10,7 @@ namespace lighting {
|
||||||
|
|
||||||
struct LightSource {
|
struct LightSource {
|
||||||
int strength = 0; // lower is better
|
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;
|
const int MIN = 50;
|
||||||
|
|
4
main.cpp
4
main.cpp
|
@ -33,7 +33,7 @@ void configure_world(DinkyECS::World &world, Map &game_map) {
|
||||||
world.set<Combat>(player.entity, {100, 10});
|
world.set<Combat>(player.entity, {100, 10});
|
||||||
world.set<Tile>(player.entity, {config.PLAYER_TILE});
|
world.set<Tile>(player.entity, {config.PLAYER_TILE});
|
||||||
world.set<Inventory>(player.entity, {5});
|
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();
|
auto enemy = world.entity();
|
||||||
world.set<Position>(enemy, {game_map.place_entity(1)});
|
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();
|
auto wall_torch = world.entity();
|
||||||
world.set<Position>(wall_torch, {game_map.place_entity(4)});
|
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, {"☀"});
|
world.set<Tile>(wall_torch, {"☀"});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
16
matrix.cpp
16
matrix.cpp
|
@ -180,24 +180,24 @@ namespace matrix {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
circle::circle(Matrix &mat, Point center, int radius) :
|
circle::circle(Matrix &mat, Point center, float radius) :
|
||||||
center(center), radius(radius)
|
center_x(center.x), center_y(center.y), radius(radius)
|
||||||
{
|
{
|
||||||
width = matrix::width(mat);
|
width = matrix::width(mat);
|
||||||
height = matrix::height(mat);
|
height = matrix::height(mat);
|
||||||
top = max(int(center.y - radius), 0);
|
top = max(int(floor(center_y - radius)), 0);
|
||||||
bottom = min(int(center.y + radius), height);
|
bottom = min(int(floor(center_y + radius)), height - 1);
|
||||||
|
|
||||||
y = top;
|
y = top;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool circle::next() {
|
bool circle::next() {
|
||||||
y++;
|
y++;
|
||||||
if(y < bottom) {
|
if(y <= bottom) {
|
||||||
dy = y - center.y;
|
dy = y - center_y;
|
||||||
dx = floor(sqrt(radius * radius - dy * dy));
|
dx = floor(sqrt(radius * radius - dy * dy));
|
||||||
left = max(0, int(center.x - dx));
|
left = max(0, int(center_x) - dx);
|
||||||
right = min(width, int(center.x + dx));
|
right = min(width, int(center_x) + dx + 1);
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -118,8 +118,9 @@ namespace matrix {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct circle {
|
struct circle {
|
||||||
Point center;
|
float center_x;
|
||||||
int radius = 0;
|
float center_y;
|
||||||
|
float radius = 0.0f;
|
||||||
int y = 0;
|
int y = 0;
|
||||||
int dx = 0;
|
int dx = 0;
|
||||||
int dy = 0;
|
int dy = 0;
|
||||||
|
@ -130,7 +131,7 @@ namespace matrix {
|
||||||
int width = 0;
|
int width = 0;
|
||||||
int height = 0;
|
int height = 0;
|
||||||
|
|
||||||
circle(Matrix &mat, Point center, int radius);
|
circle(Matrix &mat, Point center, float radius);
|
||||||
void update();
|
void update();
|
||||||
bool next();
|
bool next();
|
||||||
};
|
};
|
||||||
|
|
|
@ -144,7 +144,7 @@ void System::collision(DinkyECS::World &world, Player &player) {
|
||||||
world.send<Events::GUI>(Events::GUI::LOOT, entity, loot);
|
world.send<Events::GUI>(Events::GUI::LOOT, entity, loot);
|
||||||
inventory.gold += loot.amount;
|
inventory.gold += loot.amount;
|
||||||
light.strength = 4;
|
light.strength = 4;
|
||||||
light.distance = 2;
|
light.radius = 2.3;
|
||||||
collider.remove(loot_pos.location);
|
collider.remove(loot_pos.location);
|
||||||
} else {
|
} else {
|
||||||
println("UNKNOWN COLLISION TYPE {}", entity);
|
println("UNKNOWN COLLISION TYPE {}", entity);
|
||||||
|
|
|
@ -226,7 +226,7 @@ TEST_CASE("prototype line algorithm", "[matrix:line]") {
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("prototype circle algorithm", "[matrix:circle]") {
|
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 width = Random::uniform<size_t>(10, 13);
|
||||||
size_t height = Random::uniform<size_t>(10, 15);
|
size_t height = Random::uniform<size_t>(10, 15);
|
||||||
int pos_mod = Random::uniform<int>(-3,3);
|
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
|
// create a target for the paths
|
||||||
Point start{.x=map.width() / 2 + pos_mod, .y=map.height()/2 + pos_mod};
|
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
|
// use an empty map
|
||||||
Matrix result = map.walls();
|
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…
Add table
Add a link
Reference in a new issue