// debris_manager.hpp - Gestor de fragments de explosions // © 2026 JailDesigner #pragma once #include "core/rendering/render_context.hpp" #include #include #include #include #include #include "core/defaults.hpp" #include "core/graphics/shape.hpp" #include "core/types.hpp" #include "debris.hpp" namespace Effects { // Gestor de fragments de explosions // Manté un pool de objectes Debris i gestiona el seu cicle de vida class DebrisManager { public: explicit DebrisManager(Rendering::Renderer* renderer); // Crear explosión a partir de una shape // - shape: shape vectorial a explode // - centro: posición del centro de l'objecte // - angle: orientació de l'objecte (radians) // - scale: scale de l'objecte (1.0 = normal) // - velocitat_base: velocity inicial dels fragments (px/s) // - brightness: factor de brightness heretat (0.0-1.0, per defecte 1.0) // - velocitat_objecte: velocity de l'objecte que explota (px/s, per defecte 0) // - velocitat_angular: velocity angular heretada (rad/s, per defecte 0) // - factor_herencia_visual: factor de herència rotación visual (0.0-1.0, per defecte 0.0) void explode(const std::shared_ptr& shape, const Vec2& centro, float angle, float scale, float velocitat_base, float brightness = 1.0F, const Vec2& velocitat_objecte = {.x = 0.0F, .y = 0.0F}, float velocitat_angular = 0.0F, float factor_herencia_visual = 0.0F, const std::string& sound = Defaults::Sound::EXPLOSION, SDL_Color color = {0, 0, 0, 0}); // alpha==0 → fragmentos usan oscilador global // Actualitzar todos los fragments active void update(float delta_time); // Dibuixar todos los fragments active void draw() const; // Reiniciar todos los fragments (clear) void reset(); // Obtenir número de fragments active [[nodiscard]] auto getActiveCount() const -> int; private: Rendering::Renderer* renderer_; // Pool de fragments (màxim concurrent) // Un pentágono té 5 línies, 15 enemigos = 75 línies // + ship (3 línies) + balas (5 línies * 3) = 93 línies màxim // Arrodonit a 100 per seguretat static constexpr int MAX_DEBRIS = 150; std::array debris_pool_; // Trobar primer slot inactiu auto findFreeSlot() -> Debris*; // Calcular direcció de explosión (radial, des del centro hacia el segment). // Estático: solo opera sobre los puntos pasados, sin estado del manager. [[nodiscard]] static auto computeExplosionDirection(const Vec2& p1, const Vec2& p2, const Vec2& centre_objecte) -> Vec2; // Sub-pasos de explode() (descomposició per reduir complexitat cognitiva). // extractSegments y los apply* son static (solo toquen el debris pasado). [[nodiscard]] static auto extractSegments(const Graphics::ShapePrimitive& primitive) -> std::vector>; // Inicialitza un debris en un slot lliure i el deixa actiu. Retorna // false si el pool está ple (la cridadora ha d'aturar el bucle). auto spawnDebris(const Vec2& world_p1, const Vec2& world_p2, const Vec2& centro, float velocitat_base, float brightness, const Vec2& velocitat_objecte, float velocitat_angular, float factor_herencia_visual, SDL_Color color) -> bool; static void applyAngularVelocity(Debris& debris, const Vec2& direccio, float velocitat_angular); static void applyVisualRotation(Debris& debris, float velocitat_angular, float factor_herencia_visual); }; } // namespace Effects