Lighting system now works and does illumination for the whole map plus entities, but not walls or multiple lights yet.
This commit is contained in:
parent
62f986719d
commit
4ceacecfda
5 changed files with 49 additions and 25 deletions
1
gui.cpp
1
gui.cpp
|
@ -227,6 +227,7 @@ void GUI::run_systems() {
|
|||
auto player = $world.get_the<Player>();
|
||||
System::motion($world, $game_map);
|
||||
System::enemy_pathing($world, $game_map, player);
|
||||
System::lighting($world, $game_map, player);
|
||||
System::collision($world, player);
|
||||
System::death($world);
|
||||
}
|
||||
|
|
18
map.cpp
18
map.cpp
|
@ -43,9 +43,21 @@ inline void add_neighbors(PointList &neighbors, Matrix &closed, size_t y, size_t
|
|||
* can run make_rooms and generate on. It will
|
||||
* NOT be valid until you actually run generate.
|
||||
*/
|
||||
Map::Map(size_t width, size_t height) : $limit(1000) {
|
||||
$walls = Matrix(height, MatrixRow(width, INV_WALL));
|
||||
$input_map = Matrix(height, MatrixRow(width, 1));
|
||||
Map::Map(size_t width, size_t height) :
|
||||
$limit(1000),
|
||||
$input_map(height, MatrixRow(width, 1)),
|
||||
$walls(height, MatrixRow(width, INV_WALL)),
|
||||
$paths(height, MatrixRow(width, 1)),
|
||||
$lighting(height, MatrixRow(width, 0))
|
||||
{
|
||||
}
|
||||
|
||||
// make explicit
|
||||
Map::Map(Matrix input_map, Matrix walls_map, int limit) :
|
||||
$limit(limit),
|
||||
$input_map(input_map),
|
||||
$walls(walls_map)
|
||||
{
|
||||
}
|
||||
|
||||
void Map::make_paths() {
|
||||
|
|
10
map.hpp
10
map.hpp
|
@ -32,17 +32,14 @@ void add_neighbors(Matrix &closed, size_t j, size_t i);
|
|||
|
||||
class Map {
|
||||
public:
|
||||
int $limit;
|
||||
Matrix $input_map;
|
||||
Matrix $walls;
|
||||
Matrix $paths;
|
||||
Matrix $lighting; // BUG: this is not the place
|
||||
std::vector<Room> $rooms;
|
||||
int $limit = 0;
|
||||
|
||||
// make explicit
|
||||
Map(Matrix input_map, Matrix walls_map, int limit) :
|
||||
$input_map(input_map),
|
||||
$walls(walls_map), $limit(limit) {
|
||||
}
|
||||
Map(Matrix input_map, Matrix walls_map, int limit);
|
||||
|
||||
// make random
|
||||
Map(size_t width, size_t height);
|
||||
|
@ -51,6 +48,7 @@ public:
|
|||
Map(Map &map) = delete;
|
||||
|
||||
Matrix& paths() { return $paths; }
|
||||
Matrix& lighting() { return $lighting; }
|
||||
Matrix& input_map() { return $input_map; }
|
||||
Matrix& walls() { return $walls; }
|
||||
int limit() { return $limit; }
|
||||
|
|
44
systems.cpp
44
systems.cpp
|
@ -16,6 +16,21 @@ using namespace fmt;
|
|||
using namespace components;
|
||||
using ftxui::Color;
|
||||
|
||||
void System::lighting(DinkyECS::World &world, Map &game_map, Player &player) {
|
||||
const auto& player_light = world.get<LightSource>(player.entity);
|
||||
auto &paths = game_map.paths();
|
||||
auto &lighting = game_map.lighting();
|
||||
const int LIGHT_MIN = 10;
|
||||
const int LIGHT_MAX = 110;
|
||||
|
||||
for(size_t x = 0; x < game_map.width(); ++x) {
|
||||
for(size_t y = 0; y < game_map.height(); ++y) {
|
||||
int dnum = paths[y][x];
|
||||
lighting[y][x] = std::clamp(255 - (dnum * player_light.strength), LIGHT_MIN, LIGHT_MAX);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void System::enemy_pathing(DinkyECS::World &world, Map &game_map, Player &player) {
|
||||
// TODO: this will be on each enemy not a global thing
|
||||
const auto &config = world.get_the<EnemyConfig>();
|
||||
|
@ -128,17 +143,22 @@ void System::collision(DinkyECS::World &world, Player &player) {
|
|||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
void System::draw_entities(DinkyECS::World &world, Map &game_map, ftxui::Canvas &canvas, const Point &cam_orig, size_t view_x, size_t view_y) {
|
||||
auto &lighting = game_map.lighting();
|
||||
|
||||
world.query<Position, Tile>([&](const auto &ent, auto &pos, auto &tile) {
|
||||
if(pos.location.x >= cam_orig.x && pos.location.x <= cam_orig.x + view_x
|
||||
&& 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);
|
||||
// the 2 and 4 are from ftxui::Canvas since it does a kind of "subpixel" drawing
|
||||
int light_value = lighting[pos.location.y][pos.location.x];
|
||||
|
||||
// BUG: this color is a made up BS color for seeing entities until I can work on them
|
||||
canvas.DrawText(loc.x*2, loc.y*4, tile.chr, Color::RGB(255, 50, 50));
|
||||
// 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](auto &pixel) {
|
||||
pixel.foreground_color = Color::HSV(255, 200, light_value + 20);
|
||||
pixel.background_color = Color::HSV(30, 20, light_value / 5);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -147,10 +167,10 @@ void System::draw_map(DinkyECS::World &world, Map &game_map, ftxui::Canvas &canv
|
|||
const auto& config = world.get_the<MapConfig>();
|
||||
const auto& player = world.get_the<Player>();
|
||||
const auto& player_position = world.get<Position>(player.entity);
|
||||
const auto& player_light = world.get<LightSource>(player.entity);
|
||||
Point start = game_map.center_camera(player_position.location, view_x, view_y);
|
||||
auto &walls = game_map.walls();
|
||||
auto &paths = game_map.paths();
|
||||
auto &lighting = game_map.lighting();
|
||||
|
||||
size_t end_x = std::min(view_x, game_map.width() - start.x);
|
||||
size_t end_y = std::min(view_y, game_map.height() - start.y);
|
||||
|
@ -158,25 +178,17 @@ void System::draw_map(DinkyECS::World &world, Map &game_map, ftxui::Canvas &canv
|
|||
for(size_t x = 0; x < end_x; ++x) {
|
||||
for(size_t y = 0; y < end_y; ++y) {
|
||||
string tile = walls[start.y+y][start.x+x] == 1 ? config.WALL_TILE : config.FLOOR_TILE;
|
||||
// the 2 and 4 are from ftxui::Canvas since it does a kind of "subpixel" drawing
|
||||
// LIGHT: if tile is in light then color ++ otherwise --
|
||||
// LIGHT: is put into the/a collision map and if a cell is a light's neighbor
|
||||
// it gets brighter.
|
||||
const int LIGHT_MIN = 10;
|
||||
const int LIGHT_MAX = 110;
|
||||
|
||||
Point light_at{start.x+x, start.y+y};
|
||||
int dnum = paths[light_at.y][light_at.x];
|
||||
int light_value = std::clamp(255 - (dnum * player_light.strength), LIGHT_MIN, LIGHT_MAX);
|
||||
|
||||
// "WALL_TILE": "\u2591",
|
||||
// "WALL_TILE": "\ua5b8",
|
||||
int light_value = lighting[start.y+y][start.x+x];
|
||||
|
||||
if(tile == config.WALL_TILE) {
|
||||
canvas.DrawText(x * 2, y * 4, config.WALL_TILE, [](auto &pixel) {
|
||||
pixel.foreground_color = Color::HSV(230, 20, 10);
|
||||
pixel.background_color = Color::HSV(230, 20, 30);
|
||||
});
|
||||
} else if(DEBUG_MAP) {
|
||||
int dnum = paths[start.y+y][start.x+x];
|
||||
string num = format("{:x}", dnum);
|
||||
num = num.size() > 2 ? "*" : num;
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
using namespace components;
|
||||
|
||||
namespace System {
|
||||
void lighting(DinkyECS::World &world, Map &game_map, Player &player);
|
||||
void motion(DinkyECS::World &world, Map &game_map);
|
||||
void collision(DinkyECS::World &world, Player &player);
|
||||
void death(DinkyECS::World &world);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue