magic numbers: game.cpp i player.cpp (en progres)

This commit is contained in:
2025-09-18 13:15:43 +02:00
parent cb7b290818
commit 0c0518adac
3 changed files with 270 additions and 47 deletions

View File

@@ -473,8 +473,22 @@ void Player::updateStepCounter(float deltaTime) {
// Pinta el jugador en pantalla
void Player::render() {
if (power_up_ && isPlaying()) {
if (power_up_counter_ > (POWERUP_COUNTER / 4) || power_up_counter_ % 20 > 4) {
// Convertir lógica de parpadeo a deltaTime
float total_powerup_time_ms = static_cast<float>(POWERUP_COUNTER) / 60.0f * 1000.0f; // Total time in ms
float quarter_time_ms = total_powerup_time_ms / 4.0f; // 25% del tiempo total
if (power_up_time_accumulator_ > quarter_time_ms) {
// En los primeros 75% del tiempo, siempre visible
power_sprite_->render();
} else {
// En el último 25%, parpadea cada 20 frames (333ms aprox)
constexpr float blink_period_ms = 20.0f / 60.0f * 1000.0f; // 20 frames in ms
constexpr float visible_proportion = 4.0f / 20.0f; // 4 frames visible de 20 total
float cycle_position = fmod(power_up_time_accumulator_, blink_period_ms) / blink_period_ms;
if (cycle_position >= visible_proportion) {
power_sprite_->render();
}
}
}
@@ -662,23 +676,28 @@ void Player::handleFiringCooldown() {
// Fase 2: Manejo de cooldown de disparo (time-based)
void Player::handleFiringCooldown(float deltaTime) {
cooling_time_accumulator_ = static_cast<float>(COOLING_DURATION) / 60.0f;
// Convertir frames a tiempo en milisegundos
float halfwayTime = static_cast<float>(recoiling_state_duration_) / 2.0f / 60.0f * 1000.0f;
// Convertir frames a tiempo: 1 frame = 1/60 segundos
float frameTime = 1.0f / 60.0f;
float halfwayTime = static_cast<float>(recoiling_state_duration_) / 2.0f / 60.0f;
// Reducir tiempo acumulado
cant_fire_time_accumulator_ -= deltaTime;
// Transition to recoiling state at halfway point
if (cant_fire_time_accumulator_ <= halfwayTime && cant_fire_time_accumulator_ > halfwayTime - frameTime) {
if (cant_fire_time_accumulator_ <= halfwayTime && !recoiling_transition_done_) {
transitionToRecoiling();
recoiling_transition_done_ = true;
}
if (cant_fire_time_accumulator_ <= 0) {
cant_fire_time_accumulator_ = 0;
recoiling_time_accumulator_ = static_cast<float>(recoiling_state_duration_) / 60.0f;
recoiling_time_accumulator_ = static_cast<float>(recoiling_state_duration_) / 60.0f * 1000.0f; // Convert to milliseconds
// Solo inicializar cooling si no está ya activo (para permitir disparos consecutivos)
if (cooling_time_accumulator_ <= 0) {
cooling_time_accumulator_ = static_cast<float>(COOLING_DURATION) / 60.0f * 1000.0f; // Convert to milliseconds
}
recoiling_transition_done_ = false; // Reset flag
}
}
@@ -716,14 +735,14 @@ void Player::handleCoolingState() {
// Fase 2: Manejo del estado de enfriamiento (time-based)
void Player::handleCoolingState(float deltaTime) {
float coolingCompleteTime = static_cast<float>(COOLING_COMPLETE) / 60.0f;
float coolingDurationTime = static_cast<float>(COOLING_DURATION) / 60.0f;
float frameTime = 1.0f / 60.0f;
float coolingCompleteTime = static_cast<float>(COOLING_COMPLETE); // 0
float coolingDurationTime = static_cast<float>(COOLING_DURATION) / 60.0f * 1000.0f; // Convert to milliseconds
if (cooling_time_accumulator_ > coolingCompleteTime) {
// Transición a cooling cuando empezamos (equivalente a == COOLING_DURATION)
if (cooling_time_accumulator_ <= coolingDurationTime && cooling_time_accumulator_ > coolingDurationTime - frameTime) {
if (!cooling_transition_done_ && cooling_time_accumulator_ >= coolingDurationTime - 16.67f) { // ~1 frame tolerance in ms
transitionToCooling();
cooling_transition_done_ = true;
}
cooling_time_accumulator_ -= deltaTime;
}
@@ -731,6 +750,7 @@ void Player::handleCoolingState(float deltaTime) {
if (cooling_time_accumulator_ <= coolingCompleteTime) {
cooling_time_accumulator_ = coolingCompleteTime;
completeCooling();
cooling_transition_done_ = false; // Reset flag
}
}
@@ -771,12 +791,12 @@ void Player::completeCooling() {
cooling_state_counter_ = -1;
}
// Actualiza al jugador a su posicion, animación y controla los contadores
// Actualiza al jugador a su posicion, animación y controla los contadores (frame-based)
void Player::update() {
move();
setAnimation();
shiftColliders();
updateCooldown();
updateFireSystem(16.67f); // Usar nuevo sistema con deltaTime fijo (16.67ms ≈ 1/60s)
updatePowerUp();
updateInvulnerable();
updateScoreboard();
@@ -788,9 +808,9 @@ void Player::update() {
// Fase 1-4: Método deltaTime completo
void Player::update(float deltaTime) {
move(deltaTime); // Sistema de movimiento time-based
setAnimation(deltaTime); // Animaciones time-based
setAnimation(deltaTime); // Animaciones time-based
shiftColliders(); // Sin cambios (posicional)
updateCooldown(deltaTime); // Fase 2: Sistema de disparo time-based
updateFireSystem(deltaTime); // NUEVO: Sistema de disparo de dos líneas
updatePowerUp(deltaTime); // Fase 3: Sistema de power-up time-based
updateInvulnerable(deltaTime); // Fase 3: Sistema de invulnerabilidad time-based
updateScoreboard(); // Sin cambios (no temporal)
@@ -1003,7 +1023,7 @@ void Player::decScoreMultiplier() {
void Player::setInvulnerable(bool value) {
invulnerable_ = value;
invulnerable_counter_ = invulnerable_ ? INVULNERABLE_COUNTER : 0;
invulnerable_time_accumulator_ = invulnerable_ ? static_cast<float>(INVULNERABLE_COUNTER) / 60.0f : 0.0f; // Initialize time accumulator
invulnerable_time_accumulator_ = invulnerable_ ? static_cast<float>(INVULNERABLE_COUNTER) / 60.0f * 1000.0f : 0.0f; // Convert frames to milliseconds
}
// Monitoriza el estado (frame-based)
@@ -1042,16 +1062,16 @@ void Player::updateInvulnerable(float deltaTime) {
if (invulnerable_time_accumulator_ > 0) {
invulnerable_time_accumulator_ -= deltaTime;
// Frecuencia fija de parpadeo adaptada a deltaTime
constexpr float blink_period = 8.0f / 60.0f; // 8 frames convertidos a segundos
// Frecuencia fija de parpadeo adaptada a deltaTime (en milisegundos)
constexpr float blink_period_ms = 8.0f / 60.0f * 1000.0f; // 8 frames convertidos a ms
// Calcula proporción decreciente basada en tiempo restante
float total_invulnerable_time = static_cast<float>(INVULNERABLE_COUNTER) / 60.0f;
float progress = 1.0f - (invulnerable_time_accumulator_ / total_invulnerable_time);
float total_invulnerable_time_ms = static_cast<float>(INVULNERABLE_COUNTER) / 60.0f * 1000.0f;
float progress = 1.0f - (invulnerable_time_accumulator_ / total_invulnerable_time_ms);
float white_proportion = 0.5f - progress * 0.2f; // Menos blanco hacia el final
// Calcula si debe mostrar textura de invulnerabilidad basado en el ciclo temporal
float cycle_position = fmod(invulnerable_time_accumulator_, blink_period) / blink_period;
float cycle_position = fmod(invulnerable_time_accumulator_, blink_period_ms) / blink_period_ms;
bool should_show_invulnerable = cycle_position < white_proportion;
size_t target_texture = should_show_invulnerable ? INVULNERABLE_TEXTURE : coffees_;
@@ -1072,7 +1092,7 @@ void Player::updateInvulnerable(float deltaTime) {
void Player::setPowerUp() {
power_up_ = true;
power_up_counter_ = POWERUP_COUNTER;
power_up_time_accumulator_ = static_cast<float>(POWERUP_COUNTER) / 60.0f; // Initialize time accumulator
power_up_time_accumulator_ = static_cast<float>(POWERUP_COUNTER) / 60.0f * 1000.0f; // Convert frames to milliseconds
}
// Actualiza el valor de la variable (frame-based)
@@ -1144,7 +1164,7 @@ void Player::updateContinueCounter() {
void Player::updateContinueCounter(float deltaTime) {
if (playing_state_ == State::CONTINUE) {
continue_time_accumulator_ += deltaTime;
constexpr float CONTINUE_INTERVAL = 1.0f; // 1 segundo
constexpr float CONTINUE_INTERVAL = 1000.0f; // 1 segundo en milisegundos
if (continue_time_accumulator_ >= CONTINUE_INTERVAL) {
continue_time_accumulator_ -= CONTINUE_INTERVAL;
decContinueCounter();
@@ -1166,7 +1186,7 @@ void Player::updateEnterNameCounter() {
void Player::updateEnterNameCounter(float deltaTime) {
if (playing_state_ == State::ENTERING_NAME || playing_state_ == State::ENTERING_NAME_GAME_COMPLETED) {
name_entry_time_accumulator_ += deltaTime;
constexpr float NAME_ENTRY_INTERVAL = 1.0f; // 1 segundo
constexpr float NAME_ENTRY_INTERVAL = 1000.0f; // 1 segundo en milisegundos
if (name_entry_time_accumulator_ >= NAME_ENTRY_INTERVAL) {
name_entry_time_accumulator_ -= NAME_ENTRY_INTERVAL;
decNameEntryCounter();
@@ -1268,4 +1288,145 @@ void Player::addScoreToScoreBoard() const {
void Player::addCredit() {
++credits_used_;
playSound("credit.wav");
}
// ========================================
// IMPLEMENTACIÓN DEL NUEVO SISTEMA DE DOS LÍNEAS
// ========================================
// Método principal del nuevo sistema de disparo
void Player::updateFireSystem(float deltaTime) {
updateFunctionalLine(deltaTime); // Línea 1: CanFire
updateVisualLine(deltaTime); // Línea 2: Animaciones
}
// LÍNEA 1: Sistema Funcional (CanFire)
void Player::updateFunctionalLine(float deltaTime) {
if (fire_cooldown_timer_ > 0) {
fire_cooldown_timer_ -= deltaTime;
can_fire_new_system_ = false;
} else {
fire_cooldown_timer_ = 0; // Evitar valores negativos
can_fire_new_system_ = true;
}
}
// LÍNEA 2: Sistema Visual (Animaciones)
void Player::updateVisualLine(float deltaTime) {
if (visual_fire_state_ == VisualFireState::NORMAL) {
return; // No hay temporizador activo en estado NORMAL
}
visual_state_timer_ -= deltaTime;
switch (visual_fire_state_) {
case VisualFireState::AIMING:
if (visual_state_timer_ <= 0) {
transitionToRecoilingNew();
}
break;
case VisualFireState::RECOILING:
if (visual_state_timer_ <= 0) {
transitionToThreatPose();
}
break;
case VisualFireState::THREAT_POSE:
if (visual_state_timer_ <= 0) {
transitionToNormalNew();
}
break;
case VisualFireState::NORMAL:
// Ya manejado arriba
break;
}
}
// Inicia un nuevo disparo en ambas líneas
void Player::startFiringNewSystem(int cooldown_frames) {
// LÍNEA 1: Inicia cooldown funcional
fire_cooldown_timer_ = static_cast<float>(cooldown_frames) / 60.0f * 1000.0f; // Convertir frames a ms
can_fire_new_system_ = false;
// LÍNEA 2: Resetea completamente el estado visual
aiming_duration_ = fire_cooldown_timer_ * AIMING_DURATION_FACTOR; // 50% del cooldown
recoiling_duration_ = aiming_duration_ * RECOILING_DURATION_MULTIPLIER; // 4 veces la duración de aiming
visual_fire_state_ = VisualFireState::AIMING;
visual_state_timer_ = aiming_duration_;
updateFiringStateFromVisual(); // Sincroniza firing_state_ para animaciones
}
// Sincroniza firing_state_ con visual_fire_state_
void Player::updateFiringStateFromVisual() {
// Mantener la dirección actual del disparo
State base_state = State::FIRING_NONE;
if (firing_state_ == State::FIRING_LEFT || firing_state_ == State::RECOILING_LEFT || firing_state_ == State::COOLING_LEFT) {
base_state = State::FIRING_LEFT;
} else if (firing_state_ == State::FIRING_RIGHT || firing_state_ == State::RECOILING_RIGHT || firing_state_ == State::COOLING_RIGHT) {
base_state = State::FIRING_RIGHT;
} else if (firing_state_ == State::FIRING_UP || firing_state_ == State::RECOILING_UP || firing_state_ == State::COOLING_UP) {
base_state = State::FIRING_UP;
}
switch (visual_fire_state_) {
case VisualFireState::NORMAL:
firing_state_ = State::FIRING_NONE;
break;
case VisualFireState::AIMING:
firing_state_ = base_state; // FIRING_LEFT/RIGHT/UP
break;
case VisualFireState::RECOILING:
switch (base_state) {
case State::FIRING_LEFT: firing_state_ = State::RECOILING_LEFT; break;
case State::FIRING_RIGHT: firing_state_ = State::RECOILING_RIGHT; break;
case State::FIRING_UP: firing_state_ = State::RECOILING_UP; break;
default: firing_state_ = State::RECOILING_UP; break;
}
break;
case VisualFireState::THREAT_POSE:
switch (base_state) {
case State::FIRING_LEFT: firing_state_ = State::COOLING_LEFT; break;
case State::FIRING_RIGHT: firing_state_ = State::COOLING_RIGHT; break;
case State::FIRING_UP: firing_state_ = State::COOLING_UP; break;
default: firing_state_ = State::COOLING_UP; break;
}
break;
}
}
// Transiciones del sistema visual
void Player::transitionToRecoilingNew() {
visual_fire_state_ = VisualFireState::RECOILING;
visual_state_timer_ = recoiling_duration_;
updateFiringStateFromVisual();
}
void Player::transitionToThreatPose() {
visual_fire_state_ = VisualFireState::THREAT_POSE;
// Calcular threat_pose_duration ajustada:
// Duración original (833ms) menos el tiempo extra que ahora dura recoiling
float original_recoiling_duration = fire_cooldown_timer_; // Era 100% del cooldown
float new_recoiling_duration = aiming_duration_ * RECOILING_DURATION_MULTIPLIER; // Ahora es más del cooldown
float extra_recoiling_time = new_recoiling_duration - original_recoiling_duration;
float adjusted_threat_duration = THREAT_POSE_DURATION - extra_recoiling_time;
// Asegurar que no sea negativo
visual_state_timer_ = std::max(adjusted_threat_duration, MIN_THREAT_POSE_DURATION);
updateFiringStateFromVisual();
}
void Player::transitionToNormalNew() {
visual_fire_state_ = VisualFireState::NORMAL;
visual_state_timer_ = 0;
updateFiringStateFromVisual();
}

View File

@@ -17,7 +17,21 @@
class Texture;
// --- Clase Player ---
// --- Clase Player: jugador principal del juego ---
//
// Esta clase gestiona todos los aspectos de un jugador durante el juego,
// incluyendo movimiento, disparos, animaciones y estados especiales.
//
// Funcionalidades principales:
// • Sistema de disparo de dos líneas: funcional (cooldown) + visual (animaciones)
// • Estados de animación: normal → aiming → recoiling → threat_pose → normal
// • Movimiento time-based: compatibilidad con deltaTime para fluidez variable
// • Power-ups e invulnerabilidad: coffee machine, extra hits, parpadeos
// • Sistema de puntuación: multipliers, high scores, entrada de nombres
// • Estados de juego: playing, rolling, continue, entering_name, etc.
//
// El sistema de disparo utiliza duraciones configurables mediante constantes
// para facilitar el ajuste del gameplay y la sensación de disparo.
class Player {
public:
// --- Constantes ---
@@ -150,7 +164,8 @@ class Player {
[[nodiscard]] auto isTitleHidden() const -> bool { return playing_state_ == State::TITLE_HIDDEN; }
// Getters
[[nodiscard]] auto canFire() const -> bool { return cant_fire_time_accumulator_ <= 0; }
[[nodiscard]] auto canFire() const -> bool { return can_fire_new_system_; } // Usa nuevo sistema
[[nodiscard]] auto canFireOld() const -> bool { return cant_fire_time_accumulator_ <= 0; } // Sistema anterior
[[nodiscard]] auto hasExtraHit() const -> bool { return extra_hit_; }
[[nodiscard]] auto isCooling() const -> bool { return firing_state_ == State::COOLING_LEFT || firing_state_ == State::COOLING_UP || firing_state_ == State::COOLING_RIGHT; }
[[nodiscard]] auto isRecoiling() const -> bool { return firing_state_ == State::RECOILING_LEFT || firing_state_ == State::RECOILING_UP || firing_state_ == State::RECOILING_RIGHT; }
@@ -180,10 +195,7 @@ class Player {
// Setters inline
void setController(int index) { controller_index_ = index; }
void setCantFireCounter(int counter) {
recoiling_state_duration_ = cant_fire_counter_ = counter;
cant_fire_time_accumulator_ = static_cast<float>(counter) / 60.0f * 1000.0f; // Convert frames to milliseconds
}
void startFiringNewSystem(int cooldown_frames); // Método público para iniciar disparo en nuevo sistema
void setFiringState(State state) { firing_state_ = state; }
void setInvulnerableCounter(int value) { invulnerable_counter_ = value; }
void setName(const std::string &name) { name_ = name; }
@@ -201,15 +213,27 @@ class Player {
[[nodiscard]] auto getUsesKeyboard() const -> bool { return uses_keyboard_; }
private:
// --- Constantes ---
static constexpr int POWERUP_COUNTER = 1500; // Duración del estado PowerUp
static constexpr int INVULNERABLE_COUNTER = 200; // Duración del estado invulnerable
static constexpr size_t INVULNERABLE_TEXTURE = 3; // Textura usada durante invulnerabilidad
// --- Constantes de física y movimiento ---
static constexpr float BASE_SPEED = 1.5F; // Velocidad base del jugador
// --- Constantes de power-ups y estados especiales ---
static constexpr int POWERUP_COUNTER = 1500; // Duración del estado PowerUp (frames)
static constexpr int INVULNERABLE_COUNTER = 200; // Duración del estado invulnerable (frames)
static constexpr size_t INVULNERABLE_TEXTURE = 3; // Textura usada durante invulnerabilidad
// --- Constantes del sistema de disparo (obsoletas - usar nuevo sistema) ---
static constexpr int COOLING_DURATION = 50; // Duración del enfriamiento tras disparar
static constexpr int COOLING_COMPLETE = 0; // Valor que indica enfriamiento completado
// --- Constantes de estados de espera ---
static constexpr int WAITING_COUNTER = 1000; // Tiempo de espera en estado de espera
// --- Constantes del nuevo sistema de disparo de dos líneas ---
static constexpr float AIMING_DURATION_FACTOR = 0.5f; // 50% del cooldown funcional
static constexpr float RECOILING_DURATION_MULTIPLIER = 4.0f; // 4 veces la duración de aiming
static constexpr float THREAT_POSE_DURATION = 833.33f; // 50 frames = ~833ms (duración base)
static constexpr float MIN_THREAT_POSE_DURATION = 100.0f; // Duración mínima para threat pose
// --- Objetos y punteros ---
std::unique_ptr<AnimatedSprite> player_sprite_; // Sprite para dibujar el jugador
std::unique_ptr<AnimatedSprite> power_sprite_; // Sprite para dibujar el aura del jugador con el poder a tope
@@ -253,6 +277,32 @@ class Player {
float name_entry_time_accumulator_ = 0.0f; // Acumulador de tiempo para name entry counter (time-based)
float waiting_time_accumulator_ = 0.0f; // Acumulador de tiempo para waiting movement (time-based)
float step_time_accumulator_ = 0.0f; // Acumulador de tiempo para step counter (time-based)
// ========================================
// NUEVO SISTEMA DE DISPARO DE DOS LÍNEAS
// ========================================
// LÍNEA 1: SISTEMA FUNCIONAL (CanFire)
float fire_cooldown_timer_ = 0.0f; // Tiempo restante hasta poder disparar otra vez
bool can_fire_new_system_ = true; // true si puede disparar ahora mismo
// LÍNEA 2: SISTEMA VISUAL (Animaciones)
enum class VisualFireState {
NORMAL, // Brazo en posición neutral
AIMING, // Brazo alzado (disparando)
RECOILING, // Brazo en retroceso
THREAT_POSE // Posición amenazante
};
VisualFireState visual_fire_state_ = VisualFireState::NORMAL;
float visual_state_timer_ = 0.0f; // Tiempo en el estado visual actual
float aiming_duration_ = 0.0f; // Duración del estado AIMING
float recoiling_duration_ = 0.0f; // Duración del estado RECOILING
// Variables del sistema obsoleto (mantener para compatibilidad temporal)
bool recoiling_transition_done_ = false; // Flag sistema obsoleto
bool cooling_transition_done_ = false; // Flag sistema obsoleto
int invulnerable_counter_ = INVULNERABLE_COUNTER; // Contador para la invulnerabilidad
int score_ = 0; // Puntos del jugador
int coffees_ = 0; // Indica cuántos cafés lleva acumulados
@@ -289,15 +339,27 @@ class Player {
void playSound(const std::string &name) const; // Hace sonar un sonido
[[nodiscard]] auto isRenderable() const -> bool; // Indica si se puede dibujar el objeto
void addScoreToScoreBoard() const; // Añade una puntuación a la tabla de records
void handleFiringCooldown(); // Gestiona el tiempo de espera después de disparar antes de permitir otro disparo (frame-based)
void handleFiringCooldown(float deltaTime); // Gestiona el tiempo de espera después de disparar antes de permitir otro disparo (time-based)
void handleRecoilAndCooling(); // Procesa simultáneamente el retroceso del arma y la transición al estado de enfriamiento si aplica (frame-based)
void handleRecoilAndCooling(float deltaTime); // Procesa simultáneamente el retroceso del arma y la transición al estado de enfriamiento si aplica (time-based)
void handleCoolingState(); // Actualiza la lógica interna mientras el sistema está en estado de enfriamiento (frame-based)
void handleCoolingState(float deltaTime); // Actualiza la lógica interna mientras el sistema está en estado de enfriamiento (time-based)
void transitionToRecoiling(); // Cambia el estado actual al de retroceso después de disparar
void transitionToCooling(); // Cambia el estado actual al de enfriamiento (por ejemplo, tras una ráfaga o sobrecalentamiento)
void completeCooling(); // Finaliza el proceso de enfriamiento y restablece el estado listo para disparar
// --- Métodos del sistema de disparo de dos líneas ---
void updateFireSystem(float deltaTime); // Método principal del nuevo sistema de disparo
void updateFunctionalLine(float deltaTime); // Actualiza la línea funcional (CanFire)
void updateVisualLine(float deltaTime); // Actualiza la línea visual (Animaciones)
void startFiring(int cooldown_frames); // Inicia un nuevo disparo en ambas líneas
void updateFiringStateFromVisual(); // Sincroniza firing_state_ con visual_fire_state_
void transitionToRecoilingNew(); // Transición AIMING → RECOILING
void transitionToThreatPose(); // Transición RECOILING → THREAT_POSE
void transitionToNormalNew(); // Transición THREAT_POSE → NORMAL
// --- Métodos del sistema de disparo obsoleto ---
void handleFiringCooldown(); // Gestiona el tiempo de espera después de disparar (frame-based)
void handleFiringCooldown(float deltaTime); // Gestiona el tiempo de espera después de disparar (time-based)
void handleRecoilAndCooling(); // Procesa retroceso y enfriamiento (frame-based)
void handleRecoilAndCooling(float deltaTime); // Procesa retroceso y enfriamiento (time-based)
void handleCoolingState(); // Actualiza estado de enfriamiento (frame-based)
void handleCoolingState(float deltaTime); // Actualiza estado de enfriamiento (time-based)
void transitionToRecoiling(); // Transición a retroceso (sistema obsoleto)
void transitionToCooling(); // Transición a enfriamiento (sistema obsoleto)
void completeCooling(); // Finaliza enfriamiento (sistema obsoleto)
void handlePlayingMovement(); // Gestiona el movimiento del personaje u objeto durante el estado de juego activo (frame-based)
void handlePlayingMovement(float deltaTime); // Gestiona el movimiento del personaje u objeto durante el estado de juego activo (time-based)
void handleRecoverMovement(); // Comprueba si ha acabado la animación

View File

@@ -1354,7 +1354,7 @@ void Game::handleFireInput(const std::shared_ptr<Player> &player, BulletType bul
cant_fire_counter = NORMAL_COOLDOWN;
}
player->setCantFireCounter(cant_fire_counter);
player->startFiringNewSystem(cant_fire_counter); // Usar nuevo sistema de dos líneas
}
}