feat(ship): la nau entra a HURT al xocar amb un enemic, mor en un segon impacte

This commit is contained in:
2026-05-22 17:30:33 +02:00
parent c6560514d8
commit 87138f9a1f
5 changed files with 81 additions and 7 deletions
+22 -3
View File
@@ -161,22 +161,41 @@ namespace Systems::Collision {
constexpr float AMPLIFIER = Defaults::Game::COLLISION_SHIP_ENEMY_AMPLIFIER;
for (uint8_t i = 0; i < 2; i++) {
// Skip si ya tocado / muerto / invulnerable
// Skip si ya tocado / muerto / invulnerable. NO actualitzem el flag de contacte:
// mentre estem inactius no hi ha "frame anterior" rellevant, i el respawn ja el resetea.
if (ctx.hit_timer_per_player[i] > 0.0F ||
!ctx.ships[i].isActive() ||
ctx.ships[i].isInvulnerable()) {
continue;
}
// Comprovem si la nau toca QUALSEVOL enemic vulnerable aquest frame.
bool touching_now = false;
for (const auto& enemy : ctx.enemies) {
if (enemy.isInvulnerable()) {
continue;
}
if (Physics::checkCollision(ctx.ships[i], enemy, AMPLIFIER)) {
ctx.on_player_hit(i);
break; // Solo una colisión por player por frame
touching_now = true;
break;
}
}
// 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();
if (RISING_EDGE) {
if (ctx.ships[i].isHurt()) {
// Segon impacte durant HURT → mort definitiva (mateix flux que abans).
ctx.on_player_hit(i);
} else {
// Primer impacte → estat HURT (rebot físic ja resolt per PhysicsWorld;
// l'enemic no rep dany per decisió de disseny).
ctx.ships[i].herir();
}
}
ctx.ships[i].setTouchingEnemyPrevFrame(touching_now);
}
}