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;
|
constexpr float BULLET_RADIUS = 3.0f;
|
||||||
} // namespace Entities
|
} // 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)
|
// Game rules (lives, respawn, game over)
|
||||||
namespace Game {
|
namespace Game {
|
||||||
constexpr int STARTING_LIVES = 3; // Initial lives
|
constexpr int STARTING_LIVES = 3; // Initial lives
|
||||||
|
|||||||
@@ -20,7 +20,8 @@ Nau::Nau(SDL_Renderer* renderer)
|
|||||||
angle_(0.0f),
|
angle_(0.0f),
|
||||||
velocitat_(0.0f),
|
velocitat_(0.0f),
|
||||||
esta_tocada_(false),
|
esta_tocada_(false),
|
||||||
brightness_(Defaults::Brightness::NAU) {
|
brightness_(Defaults::Brightness::NAU),
|
||||||
|
invulnerable_timer_(0.0f) {
|
||||||
// [NUEVO] Carregar forma compartida des de fitxer
|
// [NUEVO] Carregar forma compartida des de fitxer
|
||||||
forma_ = Graphics::ShapeLoader::load("ship.shp");
|
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)
|
// Inicialització de la nau (triangle)
|
||||||
// Basat en el codi Pascal original: lines 380-384
|
// Basat en el codi Pascal original: lines 380-384
|
||||||
// Copiat de joc_asteroides.cpp línies 30-44
|
// Copiat de joc_asteroides.cpp línies 30-44
|
||||||
@@ -52,6 +53,14 @@ void Nau::inicialitzar(const Punt* spawn_point) {
|
|||||||
// Estat inicial
|
// Estat inicial
|
||||||
angle_ = 0.0f;
|
angle_ = 0.0f;
|
||||||
velocitat_ = 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;
|
esta_tocada_ = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -90,6 +99,14 @@ void Nau::actualitzar(float delta_time) {
|
|||||||
if (esta_tocada_)
|
if (esta_tocada_)
|
||||||
return;
|
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 física (moviment + fricció)
|
||||||
aplicar_fisica(delta_time);
|
aplicar_fisica(delta_time);
|
||||||
}
|
}
|
||||||
@@ -99,6 +116,19 @@ void Nau::dibuixar() const {
|
|||||||
if (esta_tocada_)
|
if (esta_tocada_)
|
||||||
return;
|
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_)
|
if (!forma_)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ class Nau {
|
|||||||
: renderer_(nullptr) {}
|
: renderer_(nullptr) {}
|
||||||
Nau(SDL_Renderer* renderer);
|
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 processar_input(float delta_time);
|
||||||
void actualitzar(float delta_time);
|
void actualitzar(float delta_time);
|
||||||
void dibuixar() const;
|
void dibuixar() const;
|
||||||
@@ -27,6 +27,7 @@ class Nau {
|
|||||||
float get_angle() const { return angle_; }
|
float get_angle() const { return angle_; }
|
||||||
bool esta_viva() const { return !esta_tocada_; }
|
bool esta_viva() const { return !esta_tocada_; }
|
||||||
bool esta_tocada() 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_; }
|
const std::shared_ptr<Graphics::Shape>& get_forma() const { return forma_; }
|
||||||
float get_brightness() const { return brightness_; }
|
float get_brightness() const { return brightness_; }
|
||||||
Punt get_velocitat_vector() const {
|
Punt get_velocitat_vector() const {
|
||||||
@@ -54,7 +55,8 @@ class Nau {
|
|||||||
float angle_; // Angle d'orientació
|
float angle_; // Angle d'orientació
|
||||||
float velocitat_; // Velocitat (px/s)
|
float velocitat_; // Velocitat (px/s)
|
||||||
bool esta_tocada_;
|
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);
|
void aplicar_fisica(float delta_time);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -214,8 +214,8 @@ void EscenaJoc::actualitzar(float delta_time) {
|
|||||||
num_vides_--;
|
num_vides_--;
|
||||||
|
|
||||||
if (num_vides_ > 0) {
|
if (num_vides_ > 0) {
|
||||||
// Respawn ship
|
// Respawn ship en posición de muerte con invulnerabilidad
|
||||||
nau_.inicialitzar(&punt_spawn_);
|
nau_.inicialitzar(&punt_mort_, true);
|
||||||
itocado_ = 0.0f;
|
itocado_ = 0.0f;
|
||||||
} else {
|
} else {
|
||||||
// Game over
|
// Game over
|
||||||
@@ -560,6 +560,9 @@ void EscenaJoc::tocado() {
|
|||||||
if (itocado_ == 0.0f) {
|
if (itocado_ == 0.0f) {
|
||||||
// *** PHASE 1: TRIGGER DEATH ***
|
// *** PHASE 1: TRIGGER DEATH ***
|
||||||
|
|
||||||
|
// Guardar posición de muerte para respawn
|
||||||
|
punt_mort_ = nau_.get_centre();
|
||||||
|
|
||||||
// Mark ship as dead (stops rendering and input)
|
// Mark ship as dead (stops rendering and input)
|
||||||
nau_.marcar_tocada();
|
nau_.marcar_tocada();
|
||||||
|
|
||||||
@@ -859,8 +862,8 @@ void EscenaJoc::detectar_col·lisions_bales_enemics() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void EscenaJoc::detectar_col·lisio_nau_enemics() {
|
void EscenaJoc::detectar_col·lisio_nau_enemics() {
|
||||||
// Only check collisions if ship is alive
|
// Skip collisions if ship is dead or invulnerable
|
||||||
if (!nau_.esta_viva()) {
|
if (!nau_.esta_viva() || nau_.es_invulnerable()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -56,6 +56,7 @@ class EscenaJoc {
|
|||||||
bool game_over_; // Game over state flag
|
bool game_over_; // Game over state flag
|
||||||
float game_over_timer_; // Countdown timer for auto-return (seconds)
|
float game_over_timer_; // Countdown timer for auto-return (seconds)
|
||||||
Punt punt_spawn_; // Configurable spawn point
|
Punt punt_spawn_; // Configurable spawn point
|
||||||
|
Punt punt_mort_; // Death position (for respawn)
|
||||||
int puntuacio_total_; // Current score
|
int puntuacio_total_; // Current score
|
||||||
|
|
||||||
// Text vectorial
|
// Text vectorial
|
||||||
|
|||||||
Reference in New Issue
Block a user