#include <veritas/utilities/strong_typedef.hpp>
#include <veritas/veritas.hpp>
#include <SFML/System.hpp>
#include <SFML/Graphics.hpp>
#include <cmath>
veritas_strong_typedef(sf::Vector2f, Velocity);
veritas_strong_typedef(sf::Vector2f, Position);
veritas_strong_typedef(sf::SphereShape, Graphics);
struct Collider { float radius; };
namespace vt = veritas;
//***************************
auto& movement_group = vt::create_entity_group<Velocity, Position>();
auto& collision_group = vt::create_entity_group<Collider, Position>();
auto& graphics_group = vt::create_entity_group<Graphics, Position>();
//***************************
void movement_system(float dt)
{
for (auto& entity : movement_group)
{
auto& position = entity.get_component<Position>();
auto& velocity = entity.get_component<Velocity>();
position += dt * velocity;
}
}
void collision_system()
{
for (auto& entity1 : collision_group)
{
auto& position1 = entity1.get_component<Position>();
auto& collider1 = entity1.get_component<Collider>();
for (auto& entity2 : collision_group)
{
auto& position2 = entity2.get_component<Position>();
auto& collider2 = entity2.get_component<Collider>();
auto distance = [](Position pos1, Position pos2){
Position diff = pos1 - pos2;
return sqrt(diff.x*diff.x + diff.y*diff.y);};
if (entity1.id != entity2.id &&
distance(position1, position2) < collider1.radius + collider2.radius)
{
vt::event_bus::store(CollisionEvent{entity1, entity2});
}
}
}
vt::event_bus::emit_stored<CollisionEvent>();
}
void graphics_system(sf::RenderWindow& window)
{
window.clear();
for (auto& entity : graphics_group)
{
auto& position = entity.get_component<Position>();
auto& graphics = entity.get_component<Graphics>();
graphics.setPosition(position);
window.draw(graphics);
}
window.display();
}
//****************************
void destroy_entities(const CollisionEvent& event)
{
vt::destroy_entity(event.e1);
vt::destroy_entity(event.e2);
}
//****************************
void create_sphere(Position pos, Velocity vel)
{
auto entity = vt::create_entity();
entity.add_component<Position>(pos);
entity.add_component<Velocity>(vel);
auto& collider = entity.add_component<Collider>();
collider.radius = 5;
auto& graphics = entity.add_component<Graphics>();
graphics.setSize(5);
graphics.setFillColor(sf::Color::Red);
}
int main()
{
vt::event_bus::subscribe<CollisionEvent>(destroy_entities);
sf::RenderWindow window(sf::VideoMode(800, 600), "veritas example");
sf::Clock clock;
float duration = 0;
for (int i = 0; i < 100; ++i)
{
create_sphere({rand() % 795, rand() % 595}, {rand() % 50, rand() % 50});
}
while (window.isOpen())
{
duration += clock.restart().asSeconds();
while (duration > 1/60.f)
{
vt::update_entity_groups();
duration -= 1/60.f;
movement_system(1/60.f);
collision_system();
}
graphics_system();
}
return 0;
}