79 lines
2.9 KiB
C++
79 lines
2.9 KiB
C++
// 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 <array>
|
|
#include <cstdint>
|
|
#include <vector>
|
|
|
|
#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<Line> lines_;
|
|
std::array<Ripple, Defaults::Playfield::Ripple::POOL_SIZE> ripples_{};
|
|
std::array<float, 2> ship_ripple_cooldown_{};
|
|
float elapsed_s_{0.0F};
|
|
};
|
|
|
|
} // namespace Graphics
|