feat(border): bump del border per explosions properes a la paret

This commit is contained in:
2026-05-21 22:48:49 +02:00
parent e678f8d538
commit a44748c0c4
4 changed files with 35 additions and 0 deletions
+4
View File
@@ -22,4 +22,8 @@ namespace Defaults::Border {
constexpr float BUMP_VELOCITY_REFERENCE = 120.0F; // px/s donen strength 1.0 constexpr float BUMP_VELOCITY_REFERENCE = 120.0F; // px/s donen strength 1.0
constexpr float BUMP_MIN_VELOCITY = 20.0F; // sota d'açò no genera bump (filtrar fregaments) constexpr float BUMP_MIN_VELOCITY = 20.0F; // sota d'açò no genera bump (filtrar fregaments)
// Bump generat per explosions properes a la paret.
constexpr float EXPLOSION_FALLOFF_PX = 80.0F; // més enllà d'aquesta distància, sense bump
constexpr float EXPLOSION_BASE_STRENGTH = 0.7F; // strength màxim (a 0 px de la paret)
} // namespace Defaults::Border } // namespace Defaults::Border
+5
View File
@@ -65,6 +65,11 @@ namespace Effects {
// Reproducir sonido de explosión // Reproducir sonido de explosión
Audio::get()->playSound(sound, Audio::Group::GAME); Audio::get()->playSound(sound, Audio::Group::GAME);
// Notificar als subscriptors (border, playfield, etc.).
if (explosion_callback_) {
explosion_callback_(centro);
}
const Vec2& shape_centre = shape->getCenter(); const Vec2& shape_centre = shape->getCenter();
// Multiplier: cada segment s'emet N vegades amb direccions aleatòries // Multiplier: cada segment s'emet N vegades amb direccions aleatòries
+11
View File
@@ -6,6 +6,7 @@
#include <SDL3/SDL.h> #include <SDL3/SDL.h>
#include <array> #include <array>
#include <functional>
#include <memory> #include <memory>
#include <utility> #include <utility>
#include <vector> #include <vector>
@@ -22,8 +23,17 @@ namespace Effects {
// Manté un pool de objectes Debris i gestiona el seu cicle de vida // Manté un pool de objectes Debris i gestiona el seu cicle de vida
class DebrisManager { class DebrisManager {
public: public:
// Notificació opcional cada vegada que es genera una explosió. El
// consumidor pot usar-la per fer reaccionar elements del fons (border
// bumps, pulse del playfield, etc.).
using ExplosionCallback = std::function<void(Vec2 center)>;
explicit DebrisManager(Rendering::Renderer* renderer); explicit DebrisManager(Rendering::Renderer* renderer);
void setExplosionCallback(ExplosionCallback callback) {
explosion_callback_ = std::move(callback);
}
// Crear explosión a partir de una shape // Crear explosión a partir de una shape
// - shape: shape vectorial a explode // - shape: shape vectorial a explode
// - centro: posición del centro de l'objecte // - centro: posición del centro de l'objecte
@@ -66,6 +76,7 @@ namespace Effects {
private: private:
Rendering::Renderer* renderer_; Rendering::Renderer* renderer_;
ExplosionCallback explosion_callback_;
// Pool de fragments (màxim concurrent) // Pool de fragments (màxim concurrent)
// Pentàgon 5 línies × 15 enemics × multiplier 3 = 225 trossos només d'enemics. // Pentàgon 5 línies × 15 enemics × multiplier 3 = 225 trossos només d'enemics.
+15
View File
@@ -75,6 +75,21 @@ GameScene::GameScene(SDLManager& sdl, SceneContext& context)
border_.bumpAt(hit.contact_point, STRENGTH); border_.bumpAt(hit.contact_point, STRENGTH);
}); });
// Explosions properes a una paret també generen bump (falloff lineal amb la distància).
debris_manager_.setExplosionCallback([this](Vec2 center) {
const SDL_FRect& zona = Defaults::Zones::PLAYAREA;
const float DIST_LEFT = std::abs(center.x - zona.x);
const float DIST_RIGHT = std::abs((zona.x + zona.w) - center.x);
const float DIST_TOP = std::abs(center.y - zona.y);
const float DIST_BOTTOM = std::abs((zona.y + zona.h) - center.y);
const float MIN_DIST = std::min({DIST_LEFT, DIST_RIGHT, DIST_TOP, DIST_BOTTOM});
if (MIN_DIST > Defaults::Border::EXPLOSION_FALLOFF_PX) {
return;
}
const float FALLOFF = 1.0F - (MIN_DIST / Defaults::Border::EXPLOSION_FALLOFF_PX);
border_.bumpAt(center, Defaults::Border::EXPLOSION_BASE_STRENGTH * FALLOFF);
});
// Load stage configuration // Load stage configuration
stage_config_ = StageSystem::StageLoader::load("data/stages/stages.yaml"); stage_config_ = StageSystem::StageLoader::load("data/stages/stages.yaml");
if (!stage_config_) { if (!stage_config_) {