Lighting is working way better and now for world generation work.
This commit is contained in:
parent
9c03e850b5
commit
194cc6664b
8 changed files with 57 additions and 63 deletions
|
@ -1,57 +1,57 @@
|
|||
{
|
||||
"WALL_TILE": {
|
||||
"foreground": [230, 20, 0],
|
||||
"background": [230, 20, 2],
|
||||
"foreground": [230, 20, 30],
|
||||
"background": [230, 20, 120],
|
||||
"display": "\ua5b8"
|
||||
},
|
||||
"FLOOR_TILE": {
|
||||
"foreground": [40, 15, 0],
|
||||
"background": [200, 15, 2],
|
||||
"foreground": [40, 15, 125],
|
||||
"background": [200, 15, 75],
|
||||
"display":"\u289e"
|
||||
},
|
||||
"MOSAIC_TILE_1": {
|
||||
"foreground": [40, 15, 0],
|
||||
"background": [200, 29, 2],
|
||||
"foreground": [40, 15, 125],
|
||||
"background": [200, 29, 75],
|
||||
"display":"\u19f0"
|
||||
},
|
||||
"MOSAIC_TILE_2": {
|
||||
"foreground": [40, 15, 0],
|
||||
"background": [200, 29, 2],
|
||||
"foreground": [40, 15, 125],
|
||||
"background": [200, 29, 75],
|
||||
"display":"\u16de"
|
||||
},
|
||||
"MOSAIC_TILE_3": {
|
||||
"foreground": [40, 15, 0],
|
||||
"background": [200, 29, 2],
|
||||
"foreground": [40, 15, 125],
|
||||
"background": [200, 29, 75],
|
||||
"display":"\u1378"
|
||||
},
|
||||
"PLAYER_TILE": {
|
||||
"foreground": [255, 200, 0],
|
||||
"background": [30, 20, 2],
|
||||
"foreground": [255, 200, 125],
|
||||
"background": [30, 20, 75],
|
||||
"display":"\ua66b"
|
||||
},
|
||||
"ENEMY_TILE": {
|
||||
"foreground": [255, 200, 0],
|
||||
"background": [30, 20, 2],
|
||||
"foreground": [255, 200, 125],
|
||||
"background": [30, 20, 75],
|
||||
"display":"\u1d5c"
|
||||
},
|
||||
"BG_TILE": {
|
||||
"foreground": [230, 20, 0],
|
||||
"background": [230, 20, 2],
|
||||
"foreground": [230, 20, 125],
|
||||
"background": [230, 20, 125],
|
||||
"display":"█"
|
||||
},
|
||||
"WATER_TILE": {
|
||||
"foreground": [132, 200, 0],
|
||||
"background": [147, 220, 2],
|
||||
"foreground": [132, 200, 180],
|
||||
"background": [147, 220, 100],
|
||||
"display":"\u098c"
|
||||
},
|
||||
"SAND_TILE": {
|
||||
"foreground": [24, 106, 0],
|
||||
"background": [24, 123, 2],
|
||||
"foreground": [24, 106, 180],
|
||||
"background": [24, 123, 100],
|
||||
"display":"\u17f6"
|
||||
},
|
||||
"GRASS_TILE": {
|
||||
"foreground": [41, 180, 0],
|
||||
"background": [75, 100, 2],
|
||||
"foreground": [41, 180, 180],
|
||||
"background": [75, 100, 100],
|
||||
"display":"\u0799"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,5 +17,6 @@ const int MAX_FONT_SIZE = 140;
|
|||
const int MIN_FONT_SIZE = 20;
|
||||
const int SCREEN_WIDTH = 40;
|
||||
const int SCREEN_HEIGHT = 30;
|
||||
const float PERCENT = 0.01f;
|
||||
#define FONT_FILE_NAME "./assets/text.otf"
|
||||
#define TILE_MAP_CONFIG "./assets/tiles.json"
|
||||
|
|
|
@ -8,6 +8,9 @@ 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)floor(source.radius)}; it.next();) {
|
||||
if($paths.$paths[it.y][it.x] != WALL_PATH_LIMIT) {
|
||||
if(it.x == at.x && it.y == at.y) {
|
||||
println("distance at center: {}", it.distance());
|
||||
}
|
||||
$lightmap[it.y][it.x] = light_level(source.strength, it.distance(), it.x, it.y);
|
||||
has_light.push_back({it.x, it.y});
|
||||
}
|
||||
|
@ -33,10 +36,10 @@ namespace lighting {
|
|||
}
|
||||
}
|
||||
|
||||
int LightRender::light_level(int level, float distance, size_t x, size_t y) {
|
||||
size_t at = level + ceil(distance);
|
||||
int LightRender::light_level(int strength, float distance, size_t x, size_t y) {
|
||||
int cur_level = $lightmap[y][x];
|
||||
int new_level = at < lighting::LEVELS.size() ? lighting::LEVELS[at] : lighting::MIN;
|
||||
int new_level = strength / sqrt(distance + 0.6f);
|
||||
|
||||
return cur_level < new_level ? new_level : cur_level;
|
||||
}
|
||||
|
||||
|
|
22
lights.hpp
22
lights.hpp
|
@ -9,26 +9,12 @@
|
|||
namespace lighting {
|
||||
|
||||
struct LightSource {
|
||||
int strength = 0; // lower is better
|
||||
float radius = 1.0f; // higher is farther, in squares
|
||||
int strength = 0;
|
||||
float radius = 1.0f;
|
||||
};
|
||||
|
||||
const int MIN = 50;
|
||||
const int MAX = 170;
|
||||
const int MID = 130;
|
||||
|
||||
const std::array<int, 10> LEVELS{
|
||||
MAX,
|
||||
160,
|
||||
150,
|
||||
140,
|
||||
MID,
|
||||
120,
|
||||
110,
|
||||
90,
|
||||
70,
|
||||
MIN,
|
||||
};
|
||||
const int MIN = 35;
|
||||
const int MAX = 95;
|
||||
|
||||
class LightRender {
|
||||
public:
|
||||
|
|
6
main.cpp
6
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.0});
|
||||
world.set<LightSource>(player.entity, {70,1.0});
|
||||
|
||||
auto enemy = world.entity();
|
||||
world.set<Position>(enemy, {game_map.place_entity(1)});
|
||||
|
@ -46,7 +46,7 @@ void configure_world(DinkyECS::World &world, Map &game_map) {
|
|||
world.set<Motion>(enemy2, {0,0});
|
||||
world.set<Combat>(enemy2, {20, 10});
|
||||
world.set<Tile>(enemy2, {"*"});
|
||||
world.set<LightSource>(enemy2, {7,0});
|
||||
world.set<LightSource>(enemy2, {60,0.2f});
|
||||
|
||||
auto gold = world.entity();
|
||||
world.set<Position>(gold, {game_map.place_entity(3)});
|
||||
|
@ -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, {4,3});
|
||||
world.set<LightSource>(wall_torch, {90,3.0f});
|
||||
world.set<Tile>(wall_torch, {"☀"});
|
||||
}
|
||||
|
||||
|
|
19
systems.cpp
19
systems.cpp
|
@ -143,7 +143,7 @@ void System::collision(DinkyECS::World &world, Player &player) {
|
|||
|
||||
world.send<Events::GUI>(Events::GUI::LOOT, entity, loot);
|
||||
inventory.gold += loot.amount;
|
||||
light.strength = 5;
|
||||
light.strength = 70;
|
||||
light.radius = 2;
|
||||
collider.remove(loot_pos.location);
|
||||
} else {
|
||||
|
@ -162,13 +162,13 @@ void System::draw_entities(DinkyECS::World &world, Map &game_map, const Matrix &
|
|||
&& 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);
|
||||
|
||||
int light_value = lighting[pos.location.y][pos.location.x];
|
||||
float light_value = lighting[pos.location.y][pos.location.x] * PERCENT;
|
||||
const TileCell& cell = tiles.at(pos.location.x, pos.location.y);
|
||||
|
||||
// the 2 and 4 are from ftxui::Canvas since it does a kind of "subpixel" drawing
|
||||
canvas.DrawText(loc.x*2, loc.y*4, tile.chr, [light_value, cell](auto &pixel) {
|
||||
pixel.foreground_color = Color::HSV(255, 200, light_value + 20);
|
||||
pixel.background_color = Color::HSV(cell.bg_h, cell.bg_s, light_value / cell.bg_v);
|
||||
pixel.foreground_color = Color::HSV(255, 200, 180 * light_value);
|
||||
pixel.background_color = Color::HSV(cell.bg_h, cell.bg_s, cell.bg_v * light_value);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
@ -188,20 +188,21 @@ void System::draw_map(DinkyECS::World &world, Map &game_map, const Matrix &light
|
|||
for(size_t y = 0; y < end_y; ++y) {
|
||||
for(size_t x = 0; x < end_x; ++x) {
|
||||
const TileCell& tile = tiles.at(start.x+x, start.y+y);
|
||||
int light_value = debug.LIGHT ? 160 : lighting[start.y+y][start.x+x];
|
||||
// light value is an integer that's a percent
|
||||
float light_value = debug.LIGHT ? 80 * PERCENT : lighting[start.y+y][start.x+x] * PERCENT;
|
||||
int dnum = debug.PATHS ? paths[start.y+y][start.x+x] : WALL_PATH_LIMIT;
|
||||
|
||||
if(debug.PATHS && dnum != WALL_PATH_LIMIT) {
|
||||
string num = dnum > 15 ? "*" : format("{:x}", dnum);
|
||||
|
||||
canvas.DrawText(x * 2, y * 4, num, [dnum, light_value](auto &pixel) {
|
||||
canvas.DrawText(x * 2, y * 4, num, [dnum, tile, light_value](auto &pixel) {
|
||||
pixel.foreground_color = Color::HSV(dnum * 20, 150, 200);
|
||||
pixel.background_color = Color::HSV(30, 20, light_value / 2);
|
||||
pixel.background_color = Color::HSV(30, 20, tile.bg_v * 50 * PERCENT);
|
||||
});
|
||||
} else {
|
||||
canvas.DrawText(x * 2, y * 4, tile.display, [tile, light_value](auto &pixel) {
|
||||
pixel.foreground_color = Color::HSV(tile.fg_h, tile.fg_s, light_value - tile.fg_v);
|
||||
pixel.background_color = Color::HSV(tile.bg_h, tile.bg_s, light_value / tile.bg_v);
|
||||
pixel.foreground_color = Color::HSV(tile.fg_h, tile.fg_s, tile.fg_v * light_value);
|
||||
pixel.background_color = Color::HSV(tile.bg_h, tile.bg_s, tile.bg_v * light_value);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -40,8 +40,4 @@ TEST_CASE("lighting a map works", "[lighting]") {
|
|||
matrix::dump("PATHS=====", lr.paths(), light1.x, light1.y);
|
||||
matrix::dump("LIGHTING 1", lighting, light1.x, light1.y);
|
||||
matrix::dump("LIGHTING 2", lighting, light2.x, light2.y);
|
||||
|
||||
// confirm light is set at least at and around the two points
|
||||
REQUIRE(lighting[light1.y][light1.x] == lighting::LEVELS[source1.strength]);
|
||||
REQUIRE(lighting[light2.y][light2.x] == lighting::LEVELS[source2.strength]);
|
||||
}
|
||||
|
|
|
@ -153,10 +153,17 @@ void WorldBuilder::generate() {
|
|||
}
|
||||
|
||||
$map.load_tiles();
|
||||
stylize_room(3, "WATER_TILE", 2.5);
|
||||
stylize_room(2, "SAND_TILE", 4.5);
|
||||
stylize_room(4, "MOSAIC_TILE_2", 7.0);
|
||||
stylize_room(1, "GRASS_TILE", 3.4);
|
||||
|
||||
std::array<string, 6> room_types{
|
||||
"WATER_TILE", "SAND_TILE", "MOSAIC_TILE_1",
|
||||
"MOSAIC_TILE_2", "MOSAIC_TILE_3", "GRASS_TILE"
|
||||
};
|
||||
|
||||
for(size_t i = 0; i < $map.$rooms.size() - 1; i++) {
|
||||
size_t room_type = Random::uniform<size_t>(0, room_types.size() - 1);
|
||||
int room_size = Random::uniform<int>(100, 800);
|
||||
stylize_room(i, room_types[room_type], room_size * 0.01f);
|
||||
}
|
||||
}
|
||||
|
||||
void WorldBuilder::make_room(size_t origin_x, size_t origin_y, size_t w, size_t h) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue