How to use the ECS made by MR. PET
To use the ECS you will need the registry, the registry will store all entity and SparseArray of component.
Registry r;
After that you will need to spawn an entity and get component you need then, modify it for the value of the id of the Entity
Entity player = r.spawn_entity(); // Method of the registry to spawn an entity
auto &positions = r.get_components<ecs::component::Position>(); // Method to get a component, using a template of the component, here it is the Position component
positions[player.getId()] = ecs::component::Positions{ 100, 100, false }; // setting the entity's position to x = 100, y = 100, and changeDirection to false
if you want to register a new components, juste put it in the template, to modify it just change de value of the component, you can refere to the doxygen documentation. To display it, it depends the library you use, here is an exemple with the SFML
#define FRAME_PER_SECONDS(x) (int)(1 / x)
class MouvePlayer {
public:
void operator()(Registry &r)
{
auto &animations = r.get_components<ecs::component::Animations>();
auto &positions = r.get_components<ecs::component::Position>();
auto &controllable = r.get_components<ecs::component::Controllable>();
for (auto &&[anim, pos, ctrl] : ecs::custom_zip(animations, positions, controllable)) {
if (!anim || !pos || !ctrl || anim->_type != ecs::component::Type::Basic) {
continue;
}
if (anim->_object == ecs::component::Player) {
pos->_x += ctrl->_speed;
}
}
}
}
int main(void)
{
sf::RenderWindow _gameWin;
ecs::Clock _drawClock;
ecs::Clock _systemClock;
Registry r;
Entity player = r.spawn_entity();
auto &positions = r.get_components<ecs::component::Position>();
auto &animations = r.get_components<ecs::component::Animation>();
auto &drawables = r.get_components<ecs::component::Drawable>();
auto &sprites = r.get_components<ecs::component::Sprite>();
auto &controllable = r.get_components<ecs::component::Controllable>();
positions[player.getId()] = ecs::component::Positions{ 100, 100, false };
drawables[player.getId()] = ecs::component::Drawable{ true };
animations[player.getId()] = ecs::component::Animations{
ecs::Clock(), 20, 18, 0, 0, 0, ecs::component::Object::Player, ecs::component::Type::None
sprites[player.getId()] = ecs::component::Positions{ "path/to/sprite.png/jpg/gif..." };
controllable[player.getId()] = ecs::component::Controllable{ true, 5 }
r.add_system(MouvePlayer());
while (_gameWin.isOpen()) { // Main Loop of the window
sf::Event event;
while (_gameWin.pollEvent(event)) { // Loop of the event
if (event.type == sf::Event::Closed) {
_gameWin.close();
}
}
if (_systemClock.getSeconds() > FRAME_PER_SECONDS(5)) { // Run the Systems 5 times per seconds
r.run_systems(); // run all systems
}
if (_drawClock.getSeconds() > FRAME_PER_SECONDS(60)) { // Display 60 times per seconds (60 FPS)
_gameWin.clear(); // Clearing window
for (auto &&[draws, anim, spri, pos] :
ecs::custom_zip(drawables, animations, sprites, positions)) { // iteration on your component
if (!draws || !anim || !spri || !si || !pos) { // check if your component is all have a value, and there is no nullopt to avoid crashes
continue;
}
if (spri->_pathToSprite.empty()) {
continue;
}
sf::Sprite sprite;
sf::Texture texture;
texture.loadFromFiles(spri->_pathToSprite); // set the Image to the Texture
sprite.setPosition(pos->_x, pos->_y); // Set the position of the Sprite
sprite.setTextureRect(sf::IntRect(anim->_x, anim->_y, anim->_width, anim->_height)); // Set the rectangle on the image
sprite.setTexture(texture); // set the Texture to the Sprite
_gameWin.draw(sprite); // Draw the Sprite
}
_drawClock.restart(); // restart the clock
}
_gameWin.display(); // display the imega
}
}