magic numbers: game.cpp i player.cpp (en progres)
This commit is contained in:
@@ -473,8 +473,22 @@ void Player::updateStepCounter(float deltaTime) {
|
|||||||
// Pinta el jugador en pantalla
|
// Pinta el jugador en pantalla
|
||||||
void Player::render() {
|
void Player::render() {
|
||||||
if (power_up_ && isPlaying()) {
|
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();
|
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)
|
// Fase 2: Manejo de cooldown de disparo (time-based)
|
||||||
void Player::handleFiringCooldown(float deltaTime) {
|
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
|
// Reducir tiempo acumulado
|
||||||
cant_fire_time_accumulator_ -= deltaTime;
|
cant_fire_time_accumulator_ -= deltaTime;
|
||||||
|
|
||||||
// Transition to recoiling state at halfway point
|
// 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();
|
transitionToRecoiling();
|
||||||
|
recoiling_transition_done_ = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cant_fire_time_accumulator_ <= 0) {
|
if (cant_fire_time_accumulator_ <= 0) {
|
||||||
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)
|
// Fase 2: Manejo del estado de enfriamiento (time-based)
|
||||||
void Player::handleCoolingState(float deltaTime) {
|
void Player::handleCoolingState(float deltaTime) {
|
||||||
float coolingCompleteTime = static_cast<float>(COOLING_COMPLETE) / 60.0f;
|
float coolingCompleteTime = static_cast<float>(COOLING_COMPLETE); // 0
|
||||||
float coolingDurationTime = static_cast<float>(COOLING_DURATION) / 60.0f;
|
float coolingDurationTime = static_cast<float>(COOLING_DURATION) / 60.0f * 1000.0f; // Convert to milliseconds
|
||||||
float frameTime = 1.0f / 60.0f;
|
|
||||||
|
|
||||||
if (cooling_time_accumulator_ > coolingCompleteTime) {
|
if (cooling_time_accumulator_ > coolingCompleteTime) {
|
||||||
// Transición a cooling cuando empezamos (equivalente a == COOLING_DURATION)
|
// 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();
|
transitionToCooling();
|
||||||
|
cooling_transition_done_ = true;
|
||||||
}
|
}
|
||||||
cooling_time_accumulator_ -= deltaTime;
|
cooling_time_accumulator_ -= deltaTime;
|
||||||
}
|
}
|
||||||
@@ -731,6 +750,7 @@ void Player::handleCoolingState(float deltaTime) {
|
|||||||
if (cooling_time_accumulator_ <= coolingCompleteTime) {
|
if (cooling_time_accumulator_ <= coolingCompleteTime) {
|
||||||
cooling_time_accumulator_ = coolingCompleteTime;
|
cooling_time_accumulator_ = coolingCompleteTime;
|
||||||
completeCooling();
|
completeCooling();
|
||||||
|
cooling_transition_done_ = false; // Reset flag
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -771,12 +791,12 @@ void Player::completeCooling() {
|
|||||||
cooling_state_counter_ = -1;
|
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() {
|
void Player::update() {
|
||||||
move();
|
move();
|
||||||
setAnimation();
|
setAnimation();
|
||||||
shiftColliders();
|
shiftColliders();
|
||||||
updateCooldown();
|
updateFireSystem(16.67f); // Usar nuevo sistema con deltaTime fijo (16.67ms ≈ 1/60s)
|
||||||
updatePowerUp();
|
updatePowerUp();
|
||||||
updateInvulnerable();
|
updateInvulnerable();
|
||||||
updateScoreboard();
|
updateScoreboard();
|
||||||
@@ -790,7 +810,7 @@ void Player::update(float deltaTime) {
|
|||||||
move(deltaTime); // Sistema de movimiento time-based
|
move(deltaTime); // Sistema de movimiento time-based
|
||||||
setAnimation(deltaTime); // Animaciones time-based
|
setAnimation(deltaTime); // Animaciones time-based
|
||||||
shiftColliders(); // Sin cambios (posicional)
|
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
|
updatePowerUp(deltaTime); // Fase 3: Sistema de power-up time-based
|
||||||
updateInvulnerable(deltaTime); // Fase 3: Sistema de invulnerabilidad time-based
|
updateInvulnerable(deltaTime); // Fase 3: Sistema de invulnerabilidad time-based
|
||||||
updateScoreboard(); // Sin cambios (no temporal)
|
updateScoreboard(); // Sin cambios (no temporal)
|
||||||
@@ -1003,7 +1023,7 @@ void Player::decScoreMultiplier() {
|
|||||||
void Player::setInvulnerable(bool value) {
|
void Player::setInvulnerable(bool value) {
|
||||||
invulnerable_ = value;
|
invulnerable_ = value;
|
||||||
invulnerable_counter_ = invulnerable_ ? INVULNERABLE_COUNTER : 0;
|
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)
|
// Monitoriza el estado (frame-based)
|
||||||
@@ -1042,16 +1062,16 @@ void Player::updateInvulnerable(float deltaTime) {
|
|||||||
if (invulnerable_time_accumulator_ > 0) {
|
if (invulnerable_time_accumulator_ > 0) {
|
||||||
invulnerable_time_accumulator_ -= deltaTime;
|
invulnerable_time_accumulator_ -= deltaTime;
|
||||||
|
|
||||||
// Frecuencia fija de parpadeo adaptada a deltaTime
|
// Frecuencia fija de parpadeo adaptada a deltaTime (en milisegundos)
|
||||||
constexpr float blink_period = 8.0f / 60.0f; // 8 frames convertidos a segundos
|
constexpr float blink_period_ms = 8.0f / 60.0f * 1000.0f; // 8 frames convertidos a ms
|
||||||
|
|
||||||
// Calcula proporción decreciente basada en tiempo restante
|
// Calcula proporción decreciente basada en tiempo restante
|
||||||
float total_invulnerable_time = static_cast<float>(INVULNERABLE_COUNTER) / 60.0f;
|
float total_invulnerable_time_ms = static_cast<float>(INVULNERABLE_COUNTER) / 60.0f * 1000.0f;
|
||||||
float progress = 1.0f - (invulnerable_time_accumulator_ / total_invulnerable_time);
|
float progress = 1.0f - (invulnerable_time_accumulator_ / total_invulnerable_time_ms);
|
||||||
float white_proportion = 0.5f - progress * 0.2f; // Menos blanco hacia el final
|
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
|
// 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;
|
bool should_show_invulnerable = cycle_position < white_proportion;
|
||||||
size_t target_texture = should_show_invulnerable ? INVULNERABLE_TEXTURE : coffees_;
|
size_t target_texture = should_show_invulnerable ? INVULNERABLE_TEXTURE : coffees_;
|
||||||
|
|
||||||
@@ -1072,7 +1092,7 @@ void Player::updateInvulnerable(float deltaTime) {
|
|||||||
void Player::setPowerUp() {
|
void Player::setPowerUp() {
|
||||||
power_up_ = true;
|
power_up_ = true;
|
||||||
power_up_counter_ = POWERUP_COUNTER;
|
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)
|
// Actualiza el valor de la variable (frame-based)
|
||||||
@@ -1144,7 +1164,7 @@ void Player::updateContinueCounter() {
|
|||||||
void Player::updateContinueCounter(float deltaTime) {
|
void Player::updateContinueCounter(float deltaTime) {
|
||||||
if (playing_state_ == State::CONTINUE) {
|
if (playing_state_ == State::CONTINUE) {
|
||||||
continue_time_accumulator_ += deltaTime;
|
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) {
|
if (continue_time_accumulator_ >= CONTINUE_INTERVAL) {
|
||||||
continue_time_accumulator_ -= CONTINUE_INTERVAL;
|
continue_time_accumulator_ -= CONTINUE_INTERVAL;
|
||||||
decContinueCounter();
|
decContinueCounter();
|
||||||
@@ -1166,7 +1186,7 @@ void Player::updateEnterNameCounter() {
|
|||||||
void Player::updateEnterNameCounter(float deltaTime) {
|
void Player::updateEnterNameCounter(float deltaTime) {
|
||||||
if (playing_state_ == State::ENTERING_NAME || playing_state_ == State::ENTERING_NAME_GAME_COMPLETED) {
|
if (playing_state_ == State::ENTERING_NAME || playing_state_ == State::ENTERING_NAME_GAME_COMPLETED) {
|
||||||
name_entry_time_accumulator_ += deltaTime;
|
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) {
|
if (name_entry_time_accumulator_ >= NAME_ENTRY_INTERVAL) {
|
||||||
name_entry_time_accumulator_ -= NAME_ENTRY_INTERVAL;
|
name_entry_time_accumulator_ -= NAME_ENTRY_INTERVAL;
|
||||||
decNameEntryCounter();
|
decNameEntryCounter();
|
||||||
@@ -1269,3 +1289,144 @@ void Player::addCredit() {
|
|||||||
++credits_used_;
|
++credits_used_;
|
||||||
playSound("credit.wav");
|
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();
|
||||||
|
}
|
||||||
100
source/player.h
100
source/player.h
@@ -17,7 +17,21 @@
|
|||||||
|
|
||||||
class Texture;
|
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 {
|
class Player {
|
||||||
public:
|
public:
|
||||||
// --- Constantes ---
|
// --- Constantes ---
|
||||||
@@ -150,7 +164,8 @@ class Player {
|
|||||||
[[nodiscard]] auto isTitleHidden() const -> bool { return playing_state_ == State::TITLE_HIDDEN; }
|
[[nodiscard]] auto isTitleHidden() const -> bool { return playing_state_ == State::TITLE_HIDDEN; }
|
||||||
|
|
||||||
// Getters
|
// 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 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 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; }
|
[[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
|
// Setters inline
|
||||||
void setController(int index) { controller_index_ = index; }
|
void setController(int index) { controller_index_ = index; }
|
||||||
void setCantFireCounter(int counter) {
|
void startFiringNewSystem(int cooldown_frames); // Método público para iniciar disparo en nuevo sistema
|
||||||
recoiling_state_duration_ = cant_fire_counter_ = counter;
|
|
||||||
cant_fire_time_accumulator_ = static_cast<float>(counter) / 60.0f * 1000.0f; // Convert frames to milliseconds
|
|
||||||
}
|
|
||||||
void setFiringState(State state) { firing_state_ = state; }
|
void setFiringState(State state) { firing_state_ = state; }
|
||||||
void setInvulnerableCounter(int value) { invulnerable_counter_ = value; }
|
void setInvulnerableCounter(int value) { invulnerable_counter_ = value; }
|
||||||
void setName(const std::string &name) { name_ = name; }
|
void setName(const std::string &name) { name_ = name; }
|
||||||
@@ -201,15 +213,27 @@ class Player {
|
|||||||
[[nodiscard]] auto getUsesKeyboard() const -> bool { return uses_keyboard_; }
|
[[nodiscard]] auto getUsesKeyboard() const -> bool { return uses_keyboard_; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// --- Constantes ---
|
// --- Constantes de física y movimiento ---
|
||||||
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
|
|
||||||
static constexpr float BASE_SPEED = 1.5F; // Velocidad base del jugador
|
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_DURATION = 50; // Duración del enfriamiento tras disparar
|
||||||
static constexpr int COOLING_COMPLETE = 0; // Valor que indica enfriamiento completado
|
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
|
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 ---
|
// --- Objetos y punteros ---
|
||||||
std::unique_ptr<AnimatedSprite> player_sprite_; // Sprite para dibujar el jugador
|
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
|
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 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 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)
|
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 invulnerable_counter_ = INVULNERABLE_COUNTER; // Contador para la invulnerabilidad
|
||||||
int score_ = 0; // Puntos del jugador
|
int score_ = 0; // Puntos del jugador
|
||||||
int coffees_ = 0; // Indica cuántos cafés lleva acumulados
|
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
|
void playSound(const std::string &name) const; // Hace sonar un sonido
|
||||||
[[nodiscard]] auto isRenderable() const -> bool; // Indica si se puede dibujar el objeto
|
[[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 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)
|
// --- Métodos del sistema de disparo de dos líneas ---
|
||||||
void handleRecoilAndCooling(); // Procesa simultáneamente el retroceso del arma y la transición al estado de enfriamiento si aplica (frame-based)
|
void updateFireSystem(float deltaTime); // Método principal del nuevo sistema de disparo
|
||||||
void handleRecoilAndCooling(float deltaTime); // Procesa simultáneamente el retroceso del arma y la transición al estado de enfriamiento si aplica (time-based)
|
void updateFunctionalLine(float deltaTime); // Actualiza la línea funcional (CanFire)
|
||||||
void handleCoolingState(); // Actualiza la lógica interna mientras el sistema está en estado de enfriamiento (frame-based)
|
void updateVisualLine(float deltaTime); // Actualiza la línea visual (Animaciones)
|
||||||
void handleCoolingState(float deltaTime); // Actualiza la lógica interna mientras el sistema está en estado de enfriamiento (time-based)
|
void startFiring(int cooldown_frames); // Inicia un nuevo disparo en ambas líneas
|
||||||
void transitionToRecoiling(); // Cambia el estado actual al de retroceso después de disparar
|
void updateFiringStateFromVisual(); // Sincroniza firing_state_ con visual_fire_state_
|
||||||
void transitionToCooling(); // Cambia el estado actual al de enfriamiento (por ejemplo, tras una ráfaga o sobrecalentamiento)
|
void transitionToRecoilingNew(); // Transición AIMING → RECOILING
|
||||||
void completeCooling(); // Finaliza el proceso de enfriamiento y restablece el estado listo para disparar
|
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(); // 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 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
|
void handleRecoverMovement(); // Comprueba si ha acabado la animación
|
||||||
|
|||||||
@@ -1354,7 +1354,7 @@ void Game::handleFireInput(const std::shared_ptr<Player> &player, BulletType bul
|
|||||||
cant_fire_counter = NORMAL_COOLDOWN;
|
cant_fire_counter = NORMAL_COOLDOWN;
|
||||||
}
|
}
|
||||||
|
|
||||||
player->setCantFireCounter(cant_fire_counter);
|
player->startFiringNewSystem(cant_fire_counter); // Usar nuevo sistema de dos líneas
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user