// playfield.hpp - Fons del playfield (graella + sub-graella amb animació de creació) // © 2026 JailDesigner // // La graella es construeix una sola vegada al constructor. El draw és stateless: // rep un `creation_progress` global ∈ [0, 1] i cada línia computa quina porció // li toca dibuixar segons el seu slot a la timeline. // // Reaccions disponibles: // - Ripples: deformacions circulars (ones d'aigua) que travessen la graella. // Disparades per explosions (grans) i pas de la nau (petites, cadència estil // trail). Cada vèrtex d'una línia afectada es desplaça radialment cap a fora // amb una envoltant en cos(·) que decau a les vores de l'anell i amb el temps. #pragma once #include #include #include #include "core/defaults/playfield.hpp" #include "core/rendering/render_context.hpp" #include "core/types.hpp" namespace Graphics { class Playfield { public: explicit Playfield(Rendering::Renderer* renderer); // Avança timers interns (creació + ripples). void update(float delta_time); // Pinta la graella. La porció dibuixada de cada línia depèn del timer intern, // i s'aplica deformació radial per cada ripple activa que afecti la línia. void draw() const; // Notifica que una nau ha passat per (pos) a (speed_px_s). Genera ones // petites darrere la nau a cadència regular amb jitter (estil TrailManager). void notifyShipMoving(std::uint8_t player_id, Vec2 pos, float speed_px_s, float delta_time); // Notifica una explosió a (pos): genera una ripple gran centrada al punt. void notifyExplosion(Vec2 pos); // Pública per accés des d'helpers a l'anonymous namespace del .cpp. struct Ripple { Vec2 center{}; float age_s{0.0F}; float lifetime_s{0.0F}; float speed_px_s{0.0F}; float amplitude_px{0.0F}; float thickness_px{0.0F}; bool active{false}; }; private: struct Line { Vec2 start; // top (verticals) o left (horitzontals) Vec2 end; // bottom (verticals) o right (horitzontals) float brightness; // base (GRID_BRIGHTNESS o SUBGRID_BRIGHTNESS) float spawn_time_s; // moment de naixement bool is_vertical; // direcció }; void buildLines(); void drawLine(const Line& line, const Ripple* const* active, int n_active) const; [[nodiscard]] auto computeLineProgress(const Line& line) const -> float; void spawnBig(Vec2 pos); void spawnSmall(Vec2 pos); auto findFreeRipple() -> Ripple*; Rendering::Renderer* renderer_; std::vector lines_; std::array ripples_{}; std::array ship_ripple_cooldown_{}; float elapsed_s_{0.0F}; }; } // namespace Graphics