I think I've got my head around what ECS does and am slowly reshaping the engine to use it better.

main
Zed A. Shaw 1 month ago
parent da04c5ec54
commit e42647d727
  1. 28
      components.hpp
  2. 82
      gui.cpp
  3. 1
      meson.build
  4. 46
      systems.cpp
  5. 12
      systems.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 = "!";
};

@ -19,38 +19,14 @@
#include "dbc.hpp" #include "dbc.hpp"
#include "gui.hpp" #include "gui.hpp"
#include "rand.hpp" #include "rand.hpp"
#include "components.hpp"
#include "systems.hpp"
using std::string; using std::string;
using namespace fmt; using namespace fmt;
using namespace std::chrono_literals; using namespace std::chrono_literals;
using namespace ftxui; 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<sf::Color, 10> VALUES{ std::array<sf::Color, 10> VALUES{
sf::Color{1, 4, 2}, // black sf::Color{1, 4, 2}, // black
sf::Color{9, 29, 16}, // dark dark sf::Color{9, 29, 16}, // dark dark
@ -121,10 +97,7 @@ void GUI::create_renderer() {
} }
} }
$world.system<Position, Tile>([&](const auto &ent, auto &pos, auto &tile) { System::draw_entities($world, $canvas);
$canvas.DrawText(pos.location.x*2, pos.location.y*4, tile.chr);
});
return canvas($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 // COMPOSE system? You create a bunch of callbacks and then combine them into
// a single run over the data? // a single run over the data?
System::enemy_pathing($world, $game_map, player);
// move enemies system System::motion($world, $game_map);
$world.system<Position, Motion>([&](const auto &ent, auto &position, auto &motion) { System::combat($world, player);
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<Position, Motion>([&](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<Position>(player.entity);
$world.system<Position, Combat>([&](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();
} }
} }
} }
@ -276,16 +216,6 @@ void GUI::render_scene() {
std::wstring map_screen_utf8 = $converter.from_bytes($map_screenout); std::wstring map_screen_utf8 = $converter.from_bytes($map_screenout);
$map_text.setString(map_screen_utf8); $map_text.setString(map_screen_utf8);
if($shake_it) {
shake();
$shake_it = false;
}
if($burn_baby_burn) {
burn();
$burn_baby_burn = false;
}
draw_screen(); draw_screen();
} }

@ -29,6 +29,7 @@ roguish = executable('roguish', [
'map.cpp', 'map.cpp',
'gui.cpp', 'gui.cpp',
'rand.cpp', 'rand.cpp',
'systems.cpp',
], ],
dependencies: dependencies) dependencies: dependencies)

@ -0,0 +1,46 @@
#include "systems.hpp"
void System::enemy_pathing(DinkyECS::World &world, Map &game_map, Player &player) {
// move enemies system
world.system<Position, Motion>([&](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<Position, Motion>([&](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<Position>(player.entity);
world.system<Position, Combat>([&](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<Position, Tile>([&](const auto &ent, auto &pos, auto &tile) {
canvas.DrawText(pos.location.x*2, pos.location.y*4, tile.chr);
});
}

@ -0,0 +1,12 @@
#pragma once
#include "dinkyecs.hpp"
#include "map.hpp"
#include "components.hpp"
#include <ftxui/dom/canvas.hpp>
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);
}
Loading…
Cancel
Save