From e42647d7273092f6b9a3e55d4455e043ae9ca553 Mon Sep 17 00:00:00 2001 From: "Zed A. Shaw" Date: Wed, 16 Oct 2024 20:31:00 -0400 Subject: [PATCH] I think I've got my head around what ECS does and am slowly reshaping the engine to use it better. --- components.hpp | 28 +++++++++++++++++ gui.cpp | 82 ++++---------------------------------------------- meson.build | 1 + systems.cpp | 46 ++++++++++++++++++++++++++++ systems.hpp | 12 ++++++++ 5 files changed, 93 insertions(+), 76 deletions(-) create mode 100644 components.hpp create mode 100644 systems.cpp create mode 100644 systems.hpp diff --git a/components.hpp b/components.hpp new file mode 100644 index 0000000..725555f --- /dev/null +++ b/components.hpp @@ -0,0 +1,28 @@ +#pragma once +#include "dinkyecs.hpp" + +struct Player { + DinkyECS::Entity entity; +}; + +struct Position { + Point location; +}; + +struct Motion { + int dx; + int dy; +}; + +struct Combat { + int hp; + int damage; +}; + +struct Treasure { + int amount; +}; + +struct Tile { + std::string chr = "!"; +}; diff --git a/gui.cpp b/gui.cpp index 5e9ef3f..7f3049b 100644 --- a/gui.cpp +++ b/gui.cpp @@ -19,38 +19,14 @@ #include "dbc.hpp" #include "gui.hpp" #include "rand.hpp" +#include "components.hpp" +#include "systems.hpp" using std::string; using namespace fmt; using namespace std::chrono_literals; using namespace ftxui; -struct Player { - DinkyECS::Entity entity; -}; - -struct Position { - Point location; -}; - -struct Motion { - int dx; - int dy; -}; - -struct Combat { - int hp; - int damage; -}; - -struct Treasure { - int amount; -}; - -struct Tile { - std::string chr = "!"; -}; - std::array VALUES{ sf::Color{1, 4, 2}, // black sf::Color{9, 29, 16}, // dark dark @@ -121,10 +97,7 @@ void GUI::create_renderer() { } } - $world.system([&](const auto &ent, auto &pos, auto &tile) { - $canvas.DrawText(pos.location.x*2, pos.location.y*4, tile.chr); - }); - + System::draw_entities($world, $canvas); return canvas($canvas); }); @@ -164,42 +137,9 @@ void GUI::handle_events() { // COMPOSE system? You create a bunch of callbacks and then combine them into // a single run over the data? - - // move enemies system - $world.system([&](const auto &ent, auto &position, auto &motion) { - if(ent != player.entity) { - Point out = position.location; - $game_map.neighbors(out, false); - motion = { int(out.x - position.location.x), int(out.y - position.location.y)}; - } - }); - - // motion system - $world.system([&](const auto &ent, auto &position, auto &motion) { - Point move_to = { - position.location.x + motion.dx, - position.location.y + motion.dy - }; - motion = {0,0}; // clear it after getting it - - if($game_map.inmap(move_to.x, move_to.y) && !$game_map.iswall(move_to.x,move_to.y)) { - $game_map.clear_target(position.location); - position.location = move_to; - } - }); - - // combat system - auto combatSystem = [&]() { - const auto& player_position = $world.component(player.entity); - $world.system([&](const auto &ent, auto &pos, auto &combat) { - if(ent != player.entity && pos.location.x == player_position.location.x && - pos.location.y == player_position.location.y) { - $burn_baby_burn = true; - } - }); - }; - - combatSystem(); + System::enemy_pathing($world, $game_map, player); + System::motion($world, $game_map); + System::combat($world, player); } } } @@ -276,16 +216,6 @@ void GUI::render_scene() { std::wstring map_screen_utf8 = $converter.from_bytes($map_screenout); $map_text.setString(map_screen_utf8); - if($shake_it) { - shake(); - $shake_it = false; - } - - if($burn_baby_burn) { - burn(); - $burn_baby_burn = false; - } - draw_screen(); } diff --git a/meson.build b/meson.build index 6d758fc..89fb5aa 100644 --- a/meson.build +++ b/meson.build @@ -29,6 +29,7 @@ roguish = executable('roguish', [ 'map.cpp', 'gui.cpp', 'rand.cpp', + 'systems.cpp', ], dependencies: dependencies) diff --git a/systems.cpp b/systems.cpp new file mode 100644 index 0000000..2a9b30e --- /dev/null +++ b/systems.cpp @@ -0,0 +1,46 @@ +#include "systems.hpp" + +void System::enemy_pathing(DinkyECS::World &world, Map &game_map, Player &player) { + // move enemies system + world.system([&](const auto &ent, auto &position, auto &motion) { + if(ent != player.entity) { + Point out = position.location; + game_map.neighbors(out, false); + motion = { int(out.x - position.location.x), int(out.y - position.location.y)}; + } + }); +} + + +void System::motion(DinkyECS::World &world, Map &game_map) { + world.system([&](const auto &ent, auto &position, auto &motion) { + Point move_to = { + position.location.x + motion.dx, + position.location.y + motion.dy + }; + motion = {0,0}; // clear it after getting it + + if(game_map.inmap(move_to.x, move_to.y) && !game_map.iswall(move_to.x,move_to.y)) { + game_map.clear_target(position.location); + position.location = move_to; + } + }); +} + + +void System::combat(DinkyECS::World &world, Player &player) { + const auto& player_position = world.component(player.entity); + + world.system([&](const auto &ent, auto &pos, auto &combat) { + if(ent != player.entity && pos.location.x == player_position.location.x && + pos.location.y == player_position.location.y) { + } + }); +}; + + +void System::draw_entities(DinkyECS::World &world, ftxui::Canvas &canvas) { + world.system([&](const auto &ent, auto &pos, auto &tile) { + canvas.DrawText(pos.location.x*2, pos.location.y*4, tile.chr); + }); +} diff --git a/systems.hpp b/systems.hpp new file mode 100644 index 0000000..9a7a19a --- /dev/null +++ b/systems.hpp @@ -0,0 +1,12 @@ +#pragma once +#include "dinkyecs.hpp" +#include "map.hpp" +#include "components.hpp" +#include + +namespace System { + void motion(DinkyECS::World &world, Map &game_map); + void combat(DinkyECS::World &world, Player &player); + void draw_entities(DinkyECS::World &world, ftxui::Canvas &canvas); + void enemy_pathing(DinkyECS::World &world, Map &game_map, Player &player); +}