respawn de nau i invulnerabilitat
This commit is contained in:
@@ -105,6 +105,17 @@ constexpr float ENEMY_RADIUS = 20.0f;
|
||||
constexpr float BULLET_RADIUS = 3.0f;
|
||||
} // namespace Entities
|
||||
|
||||
// Ship (nave del jugador)
|
||||
namespace Ship {
|
||||
// Invulnerabilidad post-respawn
|
||||
constexpr float INVULNERABILITY_DURATION = 3.0f; // Segundos de invulnerabilidad
|
||||
|
||||
// Parpadeo visual durante invulnerabilidad
|
||||
constexpr float BLINK_VISIBLE_TIME = 0.1f; // Tiempo visible (segundos)
|
||||
constexpr float BLINK_INVISIBLE_TIME = 0.1f; // Tiempo invisible (segundos)
|
||||
// Frecuencia total: 0.2s/ciclo = 5 Hz (~15 parpadeos en 3s)
|
||||
} // namespace Ship
|
||||
|
||||
// Game rules (lives, respawn, game over)
|
||||
namespace Game {
|
||||
constexpr int STARTING_LIVES = 3; // Initial lives
|
||||
|
||||
@@ -20,7 +20,8 @@ Nau::Nau(SDL_Renderer* renderer)
|
||||
angle_(0.0f),
|
||||
velocitat_(0.0f),
|
||||
esta_tocada_(false),
|
||||
brightness_(Defaults::Brightness::NAU) {
|
||||
brightness_(Defaults::Brightness::NAU),
|
||||
invulnerable_timer_(0.0f) {
|
||||
// [NUEVO] Carregar forma compartida des de fitxer
|
||||
forma_ = Graphics::ShapeLoader::load("ship.shp");
|
||||
|
||||
@@ -29,7 +30,7 @@ Nau::Nau(SDL_Renderer* renderer)
|
||||
}
|
||||
}
|
||||
|
||||
void Nau::inicialitzar(const Punt* spawn_point) {
|
||||
void Nau::inicialitzar(const Punt* spawn_point, bool activar_invulnerabilitat) {
|
||||
// Inicialització de la nau (triangle)
|
||||
// Basat en el codi Pascal original: lines 380-384
|
||||
// Copiat de joc_asteroides.cpp línies 30-44
|
||||
@@ -52,6 +53,14 @@ void Nau::inicialitzar(const Punt* spawn_point) {
|
||||
// Estat inicial
|
||||
angle_ = 0.0f;
|
||||
velocitat_ = 0.0f;
|
||||
|
||||
// Activar invulnerabilidad solo si es respawn
|
||||
if (activar_invulnerabilitat) {
|
||||
invulnerable_timer_ = Defaults::Ship::INVULNERABILITY_DURATION;
|
||||
} else {
|
||||
invulnerable_timer_ = 0.0f;
|
||||
}
|
||||
|
||||
esta_tocada_ = false;
|
||||
}
|
||||
|
||||
@@ -90,6 +99,14 @@ void Nau::actualitzar(float delta_time) {
|
||||
if (esta_tocada_)
|
||||
return;
|
||||
|
||||
// Decrementar timer de invulnerabilidad
|
||||
if (invulnerable_timer_ > 0.0f) {
|
||||
invulnerable_timer_ -= delta_time;
|
||||
if (invulnerable_timer_ < 0.0f) {
|
||||
invulnerable_timer_ = 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
// Aplicar física (moviment + fricció)
|
||||
aplicar_fisica(delta_time);
|
||||
}
|
||||
@@ -99,6 +116,19 @@ void Nau::dibuixar() const {
|
||||
if (esta_tocada_)
|
||||
return;
|
||||
|
||||
// Si invulnerable, parpadear (toggle on/off)
|
||||
if (es_invulnerable()) {
|
||||
// Calcular ciclo de parpadeo
|
||||
float blink_cycle = Defaults::Ship::BLINK_VISIBLE_TIME +
|
||||
Defaults::Ship::BLINK_INVISIBLE_TIME;
|
||||
float time_in_cycle = std::fmod(invulnerable_timer_, blink_cycle);
|
||||
|
||||
// Si estamos en fase invisible, no dibujar
|
||||
if (time_in_cycle < Defaults::Ship::BLINK_INVISIBLE_TIME) {
|
||||
return; // No dibujar durante fase invisible
|
||||
}
|
||||
}
|
||||
|
||||
if (!forma_)
|
||||
return;
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ class Nau {
|
||||
: renderer_(nullptr) {}
|
||||
Nau(SDL_Renderer* renderer);
|
||||
|
||||
void inicialitzar(const Punt* spawn_point = nullptr);
|
||||
void inicialitzar(const Punt* spawn_point = nullptr, bool activar_invulnerabilitat = false);
|
||||
void processar_input(float delta_time);
|
||||
void actualitzar(float delta_time);
|
||||
void dibuixar() const;
|
||||
@@ -27,6 +27,7 @@ class Nau {
|
||||
float get_angle() const { return angle_; }
|
||||
bool esta_viva() const { return !esta_tocada_; }
|
||||
bool esta_tocada() const { return esta_tocada_; }
|
||||
bool es_invulnerable() const { return invulnerable_timer_ > 0.0f; }
|
||||
const std::shared_ptr<Graphics::Shape>& get_forma() const { return forma_; }
|
||||
float get_brightness() const { return brightness_; }
|
||||
Punt get_velocitat_vector() const {
|
||||
@@ -54,7 +55,8 @@ class Nau {
|
||||
float angle_; // Angle d'orientació
|
||||
float velocitat_; // Velocitat (px/s)
|
||||
bool esta_tocada_;
|
||||
float brightness_; // Factor de brillantor (0.0-1.0)
|
||||
float brightness_; // Factor de brillantor (0.0-1.0)
|
||||
float invulnerable_timer_; // 0.0f = vulnerable, >0.0f = invulnerable
|
||||
|
||||
void aplicar_fisica(float delta_time);
|
||||
};
|
||||
|
||||
@@ -214,8 +214,8 @@ void EscenaJoc::actualitzar(float delta_time) {
|
||||
num_vides_--;
|
||||
|
||||
if (num_vides_ > 0) {
|
||||
// Respawn ship
|
||||
nau_.inicialitzar(&punt_spawn_);
|
||||
// Respawn ship en posición de muerte con invulnerabilidad
|
||||
nau_.inicialitzar(&punt_mort_, true);
|
||||
itocado_ = 0.0f;
|
||||
} else {
|
||||
// Game over
|
||||
@@ -560,6 +560,9 @@ void EscenaJoc::tocado() {
|
||||
if (itocado_ == 0.0f) {
|
||||
// *** PHASE 1: TRIGGER DEATH ***
|
||||
|
||||
// Guardar posición de muerte para respawn
|
||||
punt_mort_ = nau_.get_centre();
|
||||
|
||||
// Mark ship as dead (stops rendering and input)
|
||||
nau_.marcar_tocada();
|
||||
|
||||
@@ -859,8 +862,8 @@ void EscenaJoc::detectar_col·lisions_bales_enemics() {
|
||||
}
|
||||
|
||||
void EscenaJoc::detectar_col·lisio_nau_enemics() {
|
||||
// Only check collisions if ship is alive
|
||||
if (!nau_.esta_viva()) {
|
||||
// Skip collisions if ship is dead or invulnerable
|
||||
if (!nau_.esta_viva() || nau_.es_invulnerable()) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -56,6 +56,7 @@ class EscenaJoc {
|
||||
bool game_over_; // Game over state flag
|
||||
float game_over_timer_; // Countdown timer for auto-return (seconds)
|
||||
Punt punt_spawn_; // Configurable spawn point
|
||||
Punt punt_mort_; // Death position (for respawn)
|
||||
int puntuacio_total_; // Current score
|
||||
|
||||
// Text vectorial
|
||||
|
||||
Reference in New Issue
Block a user