diff --git a/source/core/defaults/physics.hpp b/source/core/defaults/physics.hpp index e3fbf4e..a515610 100644 --- a/source/core/defaults/physics.hpp +++ b/source/core/defaults/physics.hpp @@ -18,6 +18,14 @@ namespace Defaults::Physics { constexpr float IMPACT_MOMENTUM_FACTOR = 3.0F; // Factor de transferència de moment bala→enemic } // namespace Bullet + // Ship → enemy: impuls explícit aplicat a l'enemic en el moment exacte + // que la nau mor per col·lisió amb ell (afegit per damunt del rebot + // natural de PhysicsWorld, que ja és present però subtil amb la + // damping de la nau). + namespace Ship { + constexpr float DEATH_IMPACT_MOMENTUM_FACTOR = 0.3F; + } // namespace Ship + // Explosions (debris physics) namespace Debris { constexpr float VELOCITAT_BASE = 80.0F; // Velocidad inicial (px/s) diff --git a/source/game/systems/collision_system.cpp b/source/game/systems/collision_system.cpp index 4d91726..c300701 100644 --- a/source/game/systems/collision_system.cpp +++ b/source/game/systems/collision_system.cpp @@ -203,24 +203,29 @@ namespace Systems::Collision { } // Comprovem si la nau toca QUALSEVOL enemic vulnerable aquest frame. - bool touching_now = false; - for (const auto& enemy : ctx.enemies) { + Enemy* touched_enemy = nullptr; + for (auto& enemy : ctx.enemies) { if (enemy.isInvulnerable()) { continue; } if (Physics::checkCollision(ctx.ships[i], enemy, AMPLIFIER)) { - touching_now = true; + touched_enemy = &enemy; break; } } + const bool TOUCHING_NOW = touched_enemy != nullptr; // Edge-trigger: només compta com a impacte la transició no-tocant → tocant. // Així el contacte continu durant el rebot frame-a-frame no dispara HURT i mort // en frames consecutius. - const bool RISING_EDGE = touching_now && !ctx.ships[i].wasTouchingEnemyPrevFrame(); + const bool RISING_EDGE = TOUCHING_NOW && !ctx.ships[i].wasTouchingEnemyPrevFrame(); if (RISING_EDGE) { if (ctx.ships[i].isHurt()) { - // Segon impacte durant HURT → mort definitiva (mateix flux que abans). + // Segon impacte durant HURT → mort. Aplica un impuls afegit + // perquè l'enemic surti disparat (feedback visible). + const Vec2 SHIP_VEL = ctx.ships[i].getVelocityVector(); + const Vec2 IMPULSE = SHIP_VEL * (Defaults::Ship::MASS * Defaults::Physics::Ship::DEATH_IMPACT_MOMENTUM_FACTOR); + touched_enemy->applyImpulse(IMPULSE); ctx.on_player_hit(i); } else { // Primer impacte → estat HURT (rebot físic ja resolt per PhysicsWorld; @@ -228,7 +233,7 @@ namespace Systems::Collision { ctx.ships[i].herir(); } } - ctx.ships[i].setTouchingEnemyPrevFrame(touching_now); + ctx.ships[i].setTouchingEnemyPrevFrame(TOUCHING_NOW); } }