From c32b564da191041763eb17e4657de842d2e58d5a Mon Sep 17 00:00:00 2001 From: Sergio Valor Date: Fri, 22 May 2026 21:57:11 +0200 Subject: [PATCH] =?UTF-8?q?feat(firework):=20halo=20neon=20per=20part?= =?UTF-8?q?=C3=ADcula=20amb=20color=20de=20glow=20propi=20(explosi=C3=B3?= =?UTF-8?q?=20enemic:=20l=C3=ADnia=20blanca=20+=20halo=20daurat)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- source/core/defaults/effects.hpp | 16 +++++++++++ source/core/rendering/line_renderer.cpp | 22 +++++++++++++++ source/core/rendering/line_renderer.hpp | 15 +++++++++++ source/game/effects/firework.hpp | 5 ++++ source/game/effects/firework_manager.cpp | 34 +++++++++++++++++------- source/game/effects/firework_manager.hpp | 6 ++++- source/game/systems/collision_system.cpp | 10 +++++-- 7 files changed, 96 insertions(+), 12 deletions(-) diff --git a/source/core/defaults/effects.hpp b/source/core/defaults/effects.hpp index 2eda88c..83ffb14 100644 --- a/source/core/defaults/effects.hpp +++ b/source/core/defaults/effects.hpp @@ -29,6 +29,22 @@ namespace Defaults::FX::Glow { {.thickness_ratio = -1.0F, .alpha = 1.0F}, // core: línia "real" }; + // Glow per a línies "raw" (sense shape). Gruixos absoluts (px), no + // ratios — una línia individual no té bounding radius. Útil per a + // partícules de firework, sparks, etc. + namespace Line { + struct Pass { + float thickness; // px. <0 → usa el thickness passat pel caller (core) + float alpha; + }; + constexpr Pass PASSES[] = { + {.thickness = 18.0F, .alpha = 0.10F}, + {.thickness = 12.0F, .alpha = 0.20F}, + {.thickness = 6.0F, .alpha = 0.40F}, + {.thickness = -1.0F, .alpha = 1.0F}, // core: línia "real" + }; + } // namespace Line + } // namespace Defaults::FX::Glow namespace Defaults::FX::Firework { diff --git a/source/core/rendering/line_renderer.cpp b/source/core/rendering/line_renderer.cpp index 94c98d7..8710865 100644 --- a/source/core/rendering/line_renderer.cpp +++ b/source/core/rendering/line_renderer.cpp @@ -4,6 +4,7 @@ #include "core/rendering/line_renderer.hpp" #include "core/defaults.hpp" +#include "core/defaults/effects.hpp" namespace Rendering { @@ -46,6 +47,27 @@ namespace Rendering { renderer->pushLine(FX1, FY1, FX2, FY2, W, R, G, B, alpha); } + void lineaGlow(Renderer* renderer, + int x1, + int y1, + int x2, + int y2, + float brightness, + float thickness, + SDL_Color color, + SDL_Color glow_color) { + // Color dels passes de halo: si glow_color té alpha>0, l'usem; + // altrament fem servir el color de la línia. + const SDL_Color HALO_COLOR = (glow_color.a > 0) ? glow_color : color; + + for (const auto& pass : Defaults::FX::Glow::Line::PASSES) { + const bool IS_CORE = pass.thickness < 0.0F; + const float PASS_T = IS_CORE ? thickness : pass.thickness; + const SDL_Color PASS_C = IS_CORE ? color : HALO_COLOR; + linea(renderer, x1, y1, x2, y2, brightness, PASS_T, PASS_C, pass.alpha); + } + } + void setLineColor(SDL_Color color) { g_current_line_color = color; } auto getLineColor() -> SDL_Color { return g_current_line_color; } diff --git a/source/core/rendering/line_renderer.hpp b/source/core/rendering/line_renderer.hpp index 0528ca0..69af0d5 100644 --- a/source/core/rendering/line_renderer.hpp +++ b/source/core/rendering/line_renderer.hpp @@ -34,6 +34,21 @@ namespace Rendering { SDL_Color color = {0, 0, 0, 0}, float alpha = 1.0F); + // Versió amb halo neon: dibuixa la línia amb diversos passos de gruix + // creixent i alfa decreixent (config a Defaults::FX::Glow::Line::PASSES). + // El core (últim pass) usa el thickness/alpha que passa el caller. + // glow_color: si alpha>0, els passes de halo usen aquest color en lloc + // del color de la línia (p.ex. línia blanca amb halo daurat). + void lineaGlow(Renderer* renderer, + int x1, + int y1, + int x2, + int y2, + float brightness = 1.0F, + float thickness = 0.0F, + SDL_Color color = {0, 0, 0, 0}, + SDL_Color glow_color = {0, 0, 0, 0}); + // Color global de las líneas (lo actualiza ColorOscillator vía SDLManager). void setLineColor(SDL_Color color); [[nodiscard]] auto getLineColor() -> SDL_Color; diff --git a/source/game/effects/firework.hpp b/source/game/effects/firework.hpp index ed80648..cbf4816 100644 --- a/source/game/effects/firework.hpp +++ b/source/game/effects/firework.hpp @@ -35,6 +35,11 @@ namespace Effects { float brightness; // 0..1 SDL_Color color{}; // alpha==0 → oscilador global + // Halo neon (off per defecte). Si glow_color.a > 0, el halo usa + // glow_color (línia blanca + halo daurat, p.ex.); si alpha==0, el + // halo agafa el color de la línia. + bool glow{false}; + SDL_Color glow_color{}; bool active; }; diff --git a/source/game/effects/firework_manager.cpp b/source/game/effects/firework_manager.cpp index b2ebfac..5abb433 100644 --- a/source/game/effects/firework_manager.cpp +++ b/source/game/effects/firework_manager.cpp @@ -65,7 +65,9 @@ namespace Effects { SDL_Color color, float initial_speed, int n_points, - float initial_brightness) { + float initial_brightness, + bool glow, + SDL_Color glow_color) { if (n_points <= 0) { return; } @@ -105,6 +107,8 @@ namespace Effects { fw->brightness = initial_brightness; fw->color = color; + fw->glow = glow; + fw->glow_color = glow_color; fw->active = true; } } @@ -185,14 +189,26 @@ namespace Effects { .y = fw.head.y - (DIR_Y * fw.current_length), }; - Rendering::linea(renderer_, - static_cast(fw.head.x), - static_cast(fw.head.y), - static_cast(TAIL.x), - static_cast(TAIL.y), - fw.brightness, - 0.0F, - fw.color); + if (fw.glow) { + Rendering::lineaGlow(renderer_, + static_cast(fw.head.x), + static_cast(fw.head.y), + static_cast(TAIL.x), + static_cast(TAIL.y), + fw.brightness, + 0.0F, + fw.color, + fw.glow_color); + } else { + Rendering::linea(renderer_, + static_cast(fw.head.x), + static_cast(fw.head.y), + static_cast(TAIL.x), + static_cast(TAIL.y), + fw.brightness, + 0.0F, + fw.color); + } } } diff --git a/source/game/effects/firework_manager.hpp b/source/game/effects/firework_manager.hpp index 3f1d04b..9fd031b 100644 --- a/source/game/effects/firework_manager.hpp +++ b/source/game/effects/firework_manager.hpp @@ -35,11 +35,15 @@ namespace Effects { // initial_speed: velocitat radial inicial (px/s). // n_points: nombre de línies. Default Defaults::FX::Firework::N_POINTS. // initial_brightness: 0..1. + // glow: si true, cada partícula es renderitza amb halo neon. + // glow_color: color del halo. Si alpha==0, agafa el color de la línia. void spawn(const Vec2& origen, SDL_Color color = Defaults::FX::Firework::DEFAULT_COLOR, float initial_speed = Defaults::FX::Firework::SPEED, int n_points = Defaults::FX::Firework::N_POINTS, - float initial_brightness = Defaults::FX::Firework::INITIAL_BRIGHTNESS); + float initial_brightness = Defaults::FX::Firework::INITIAL_BRIGHTNESS, + bool glow = false, + SDL_Color glow_color = {0, 0, 0, 0}); void update(float delta_time); void draw() const; diff --git a/source/game/systems/collision_system.cpp b/source/game/systems/collision_system.cpp index bb02518..4d91726 100644 --- a/source/game/systems/collision_system.cpp +++ b/source/game/systems/collision_system.cpp @@ -79,8 +79,14 @@ namespace Systems::Collision { Defaults::Physics::Debris::ENEMY_SEGMENT_MULTIPLIER); // Firework burst radial des del centro de l'enemic (efecte adicional al debris). - // No heretem color: el burst usa el blanc per defecte per a un feel més lluminós. - ctx.firework_manager.spawn(ENEMY_POS); + // Línia blanca + halo daurat (WOUNDED) per a feel d'espurnes. + ctx.firework_manager.spawn(ENEMY_POS, + Defaults::FX::Firework::DEFAULT_COLOR, + Defaults::FX::Firework::SPEED, + Defaults::FX::Firework::N_POINTS, + Defaults::FX::Firework::INITIAL_BRIGHTNESS, + /*glow=*/true, + Defaults::Palette::WOUNDED); } // Trenca una bala en debris (8 fragments de l'octàgon) + so HIT + desactiva.