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 {
|
||||
|
||||
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;
|
||||
|
|
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<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, {"☀"});
|
||||
}
|
||||
|
||||
|
|
16
matrix.cpp
16
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;
|
||||
|
|
|
@ -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…
Add table
Add a link
Reference in a new issue