linter: varios

This commit is contained in:
2025-10-24 13:45:56 +02:00
parent 5362c5b022
commit fd4136a882
13 changed files with 232 additions and 201 deletions

View File

@@ -4,7 +4,7 @@
#include <fstream>
#include <iostream>
bool AssetIntegrated::resource_pack_enabled_ = false;
bool AssetIntegrated::resource_pack_enabled = false;
void AssetIntegrated::initWithResourcePack(const std::string& executable_path,
const std::string& resource_pack_path) {
@@ -14,29 +14,29 @@ void AssetIntegrated::initWithResourcePack(const std::string& executable_path,
// Inicializar ResourceLoader
auto& loader = ResourceLoader::getInstance();
if (loader.initialize(resource_pack_path, true)) {
resource_pack_enabled_ = true;
resource_pack_enabled = true;
std::cout << "Asset system initialized with resource pack: " << resource_pack_path << std::endl;
} else {
resource_pack_enabled_ = false;
resource_pack_enabled = false;
std::cout << "Asset system initialized in fallback mode (filesystem)" << std::endl;
}
}
std::vector<uint8_t> AssetIntegrated::loadFile(const std::string& filename) {
if (shouldUseResourcePack(filename) && resource_pack_enabled_) {
if (shouldUseResourcePack(filename) && resource_pack_enabled) {
// Intentar cargar del pack de recursos
auto& loader = ResourceLoader::getInstance();
// Convertir ruta completa a ruta relativa para el pack
std::string relativePath = filename;
std::string relative_path = filename;
// Si la ruta contiene "data/", extraer la parte relativa
size_t dataPos = filename.find("data/");
if (dataPos != std::string::npos) {
relativePath = filename.substr(dataPos + 5); // +5 para saltar "data/"
size_t data_pos = filename.find("data/");
if (data_pos != std::string::npos) {
relative_path = filename.substr(data_pos + 5); // +5 para saltar "data/"
}
auto data = loader.loadResource(relativePath);
auto data = loader.loadResource(relative_path);
if (!data.empty()) {
return data;
}
@@ -49,11 +49,11 @@ std::vector<uint8_t> AssetIntegrated::loadFile(const std::string& filename) {
return {};
}
std::streamsize fileSize = file.tellg();
std::streamsize file_size = file.tellg();
file.seekg(0, std::ios::beg);
std::vector<uint8_t> data(fileSize);
if (!file.read(reinterpret_cast<char*>(data.data()), fileSize)) {
std::vector<uint8_t> data(file_size);
if (!file.read(reinterpret_cast<char*>(data.data()), file_size)) {
std::cerr << "Error: Could not read file: " << filename << std::endl;
return {};
}
@@ -62,14 +62,14 @@ std::vector<uint8_t> AssetIntegrated::loadFile(const std::string& filename) {
}
bool AssetIntegrated::fileExists(const std::string& filename) const {
if (shouldUseResourcePack(filename) && resource_pack_enabled_) {
if (shouldUseResourcePack(filename) && resource_pack_enabled) {
auto& loader = ResourceLoader::getInstance();
// Convertir ruta completa a ruta relativa para el pack
std::string relativePath = filename;
size_t dataPos = filename.find("data/");
if (dataPos != std::string::npos) {
relativePath = filename.substr(dataPos + 5);
size_t data_pos = filename.find("data/");
if (data_pos != std::string::npos) {
relativePath = filename.substr(data_pos + 5);
}
if (loader.resourceExists(relativePath)) {

View File

@@ -2,23 +2,23 @@
class Cooldown {
public:
Cooldown(float first_delay_s = 0.0f, float repeat_delay_s = 0.0f)
Cooldown(float first_delay_s = 0.0F, float repeat_delay_s = 0.0F)
: first_delay_s_(first_delay_s), repeat_delay_s_(repeat_delay_s),
remaining_s_(0.0f), held_before_(false) {}
remaining_s_(0.0F), held_before_(false) {}
// Llamar cada frame con delta en segundos (float)
void update(float delta_s) {
if (remaining_s_ <= 0.0f) {
remaining_s_ = 0.0f;
if (remaining_s_ <= 0.0F) {
remaining_s_ = 0.0F;
return;
}
remaining_s_ -= delta_s;
if (remaining_s_ < 0.0f) remaining_s_ = 0.0f;
if (remaining_s_ < 0.0F) remaining_s_ = 0.0F;
}
// Llamar cuando el input está activo. Devuelve true si debe ejecutarse la acción ahora.
bool tryConsumeOnHeld() {
if (remaining_s_ > 0.0f) return false;
if (remaining_s_ > 0.0F) return false;
float delay = held_before_ ? repeat_delay_s_ : first_delay_s_;
remaining_s_ = delay;
@@ -29,13 +29,13 @@ public:
// Llamar cuando el input se suelta
void onReleased() {
held_before_ = false;
remaining_s_ = 0.0f;
remaining_s_ = 0.0F;
}
bool empty() const { return remaining_s_ == 0.0f; }
bool empty() const { return remaining_s_ == 0.0F; }
// Fuerza un valor en segundos (útil para tests o resets)
void forceSet(float seconds) { remaining_s_ = seconds > 0.0f ? seconds : 0.0f; }
void forceSet(float seconds) { remaining_s_ = seconds > 0.0F ? seconds : 0.0F; }
private:
float first_delay_s_;

View File

@@ -228,14 +228,14 @@ void Fade::updateRandomSquare2Fade() {
squares_to_activate = total_squares;
}
for (int i = 0; i < squares_to_activate; ++i) {
if (square_age_[i] == -1) square_age_[i] = elapsed_time;
if (square_age_[i] == -1) {square_age_[i] = elapsed_time;}
}
} else {
squares_to_activate = total_squares;
float activation_progress = static_cast<float>(elapsed_time) / activation_time;
int squares_starting_transition = std::min(total_squares, std::max(1, static_cast<int>(activation_progress * total_squares)));
for (int i = 0; i < squares_starting_transition; ++i) {
if (square_age_[i] == -1) square_age_[i] = elapsed_time;
if (square_age_[i] == -1) {square_age_[i] = elapsed_time;}
}
}
@@ -452,8 +452,8 @@ void Fade::activate() {
// Ahora, inicializamos la modulación de alfa correctamente:
// - IN: Empieza opaco (255) y se desvanece a transparente.
// - OUT: Empieza transparente (0) y se desvanece a opaco.
const Uint8 initial_alpha = (mode_ == Mode::IN) ? 255 : 0;
SDL_SetTextureAlphaMod(backbuffer_, initial_alpha);
const Uint8 INITIAL_ALPHA = (mode_ == Mode::IN) ? 255 : 0;
SDL_SetTextureAlphaMod(backbuffer_, INITIAL_ALPHA);
break;
}

View File

@@ -124,62 +124,84 @@ void Player::setInputPlaying(Input::Action action) {
}
}
// Gestiona la adición de un carácter o la confirmación del nombre.
void Player::handleNameCharacterAddition() {
if (enter_name_->endCharSelected()) {
confirmNameEntry();
} else {
enter_name_->addCharacter();
playSound("service_menu_select.wav");
}
}
// Gestiona la eliminación del último carácter.
void Player::handleNameCharacterRemoval() {
if (!enter_name_->nameIsEmpty()) {
enter_name_->removeLastCharacter();
playSound("service_menu_back.wav");
}
}
// Gestiona el movimiento del cursor de selección de letras (izquierda/derecha).
void Player::handleNameSelectionMove(Input::Action action) {
if (isShowingName() || enter_name_->nameIsFull()) {
return; // No hacer nada si se muestra el nombre o si está lleno
}
if (cooldown_->tryConsumeOnHeld()) {
if (action == Input::Action::RIGHT) {
enter_name_->incIndex();
} else {
enter_name_->decIndex();
}
playSound("service_menu_move.wav");
}
}
// Confirma el nombre introducido y cambia el estado del jugador.
void Player::confirmNameEntry() {
last_enter_name_ = getRecordName();
setPlayingState(Player::State::SHOWING_NAME);
playSound("name_input_accept.wav");
}
// Procesa inputs para cuando está introduciendo el nombre
void Player::setInputEnteringName(Input::Action action) {
switch (action) {
case Input::Action::FIRE_LEFT: // Añade una letra
case Input::Action::FIRE_LEFT:
if (isShowingName()) {
passShowingName();
} else {
if (enter_name_->endCharSelected()) {
last_enter_name_ = getRecordName();
setPlayingState(Player::State::SHOWING_NAME);
playSound("name_input_accept.wav");
} else {
enter_name_->addCharacter();
playSound("service_menu_select.wav");
}
handleNameCharacterAddition();
}
break;
case Input::Action::FIRE_CENTER: // Borra una letra
case Input::Action::FIRE_CENTER:
if (isShowingName()) {
passShowingName();
} else {
if (!enter_name_->nameIsEmpty()) {
enter_name_->removeLastCharacter();
playSound("service_menu_back.wav");
}
}
break;
case Input::Action::RIGHT:
if (!isShowingName() && !enter_name_->nameIsFull()) {
if (cooldown_->tryConsumeOnHeld()) {
enter_name_->incIndex();
playSound("service_menu_move.wav");
}
}
break;
case Input::Action::LEFT:
if (!isShowingName() && !enter_name_->nameIsFull()) {
if (cooldown_->tryConsumeOnHeld()) {
enter_name_->decIndex();
playSound("service_menu_move.wav");
}
handleNameCharacterRemoval();
}
break;
case Input::Action::START:
if (isShowingName()) {
passShowingName();
} else {
last_enter_name_ = getRecordName();
setPlayingState(Player::State::SHOWING_NAME);
playSound("name_input_accept.wav");
confirmNameEntry();
}
break;
case Input::Action::RIGHT:
case Input::Action::LEFT:
handleNameSelectionMove(action);
break;
default:
cooldown_->onReleased();
break;
}
name_entry_idle_time_accumulator_ = 0.0F;
}

View File

@@ -394,6 +394,12 @@ class Player {
void handleWaitingMovement(float delta_time); // Animación del jugador saludando
void updateWalkingStateForCredits(); // Actualiza estado de caminata en créditos
// --- Introducción de nombre ---
void handleNameCharacterAddition();
void handleNameCharacterRemoval();
void handleNameSelectionMove(Input::Action action);
void confirmNameEntry();
// --- Utilidades de animación ---
[[nodiscard]] auto computeAnimation() const -> std::pair<std::string, SDL_FlipMode>; // Calcula animación de movimiento y disparo
};

View File

@@ -151,22 +151,22 @@ void OpenGLShader::createQuadGeometry() {
// Formato: x, y, u, v
float vertices[] = {
// Posición // TexCoords
-1.0f,
-1.0f,
0.0f,
0.0f, // Inferior izquierda
1.0f,
-1.0f,
1.0f,
0.0f, // Inferior derecha
1.0f,
1.0f,
1.0f,
1.0f, // Superior derecha
-1.0f,
1.0f,
0.0f,
1.0f // Superior izquierda
-1.0F,
-1.0F,
0.0F,
0.0F, // Inferior izquierda
1.0F,
-1.0F,
1.0F,
0.0F, // Inferior derecha
1.0F,
1.0F,
1.0F,
1.0F, // Superior derecha
-1.0F,
1.0F,
0.0F,
1.0F // Superior izquierda
};
// Índices para dibujar el quad con dos triángulos

View File

@@ -107,15 +107,15 @@ void Scoreboard::setCarouselAnimation(Id id, int selected_index, EnterName* ente
// ===== Inicialización (primera vez) =====
if (carousel_prev_index_.at(idx) == -1) {
carousel_position_.at(idx) = static_cast<float>(selected_index);
carousel_target_.at(idx) = static_cast<float>(selected_index);
carousel_position_.at(idx) = static_cast<float>(selected_index);
carousel_target_.at(idx) = static_cast<float>(selected_index);
carousel_prev_index_.at(idx) = selected_index;
return;
}
int prev_index = carousel_prev_index_.at(idx);
if (selected_index == prev_index) {
return; // nada que hacer
return; // nada que hacer
}
// ===== Bloquear si aún animando =====
@@ -126,8 +126,11 @@ void Scoreboard::setCarouselAnimation(Id id, int selected_index, EnterName* ente
// ===== Calcular salto circular =====
int delta = selected_index - prev_index;
const int LIST_SIZE = static_cast<int>(enter_name_ptr->getCharacterList().size());
if (delta > LIST_SIZE / 2) delta -= LIST_SIZE;
else if (delta < -LIST_SIZE / 2) delta += LIST_SIZE;
if (delta > LIST_SIZE / 2) {
delta -= LIST_SIZE;
} else if (delta < -LIST_SIZE / 2) {
delta += LIST_SIZE;
}
// ===== Alinear posición actual antes de moverse =====
carousel_position_.at(idx) = std::round(carousel_position_.at(idx));
@@ -141,8 +144,8 @@ void Scoreboard::setCarouselAnimation(Id id, int selected_index, EnterName* ente
} else {
// Movimiento largo → animado pero limitado en tiempo
// Normalizamos el salto para que visualmente tarde como mucho el doble
const float MAX_DURATION_FACTOR = 2.0f; // máximo 2x la duración de una letra
const float SPEED_SCALE = std::min(1.0f, MAX_DURATION_FACTOR / static_cast<float>(ABS_DELTA));
const float MAX_DURATION_FACTOR = 2.0F; // máximo 2x la duración de una letra
const float SPEED_SCALE = std::min(1.0F, MAX_DURATION_FACTOR / static_cast<float>(ABS_DELTA));
// Guardamos el destino real
float target = std::round(carousel_position_.at(idx)) + static_cast<float>(delta);
@@ -257,7 +260,7 @@ void Scoreboard::updateCarouselAnimation(float delta_time) {
} else {
// Forzar al target exacto cuando estamos muy cerca
carousel_position_.at(i) = carousel_target_.at(i);
carousel_speed_scale_.at(i) = 1.0f; // restaurar velocidad normal
carousel_speed_scale_.at(i) = 1.0F; // restaurar velocidad normal
}
}
}
@@ -302,7 +305,7 @@ void Scoreboard::updatePanelPulses(float delta_time) {
// Desactivar el pulso si ha terminado
if (pulse.elapsed_s >= pulse.duration_s) {
pulse.active = false;
pulse.elapsed_s = 0.0f;
pulse.elapsed_s = 0.0F;
}
}
}
@@ -311,7 +314,7 @@ void Scoreboard::updatePanelPulses(float delta_time) {
void Scoreboard::triggerPanelPulse(Id id, float duration_s) {
auto idx = static_cast<size_t>(id);
panel_pulse_.at(idx).active = true;
panel_pulse_.at(idx).elapsed_s = 0.0f;
panel_pulse_.at(idx).elapsed_s = 0.0F;
panel_pulse_.at(idx).duration_s = duration_s;
}
@@ -381,7 +384,7 @@ void Scoreboard::fillPanelTextures() {
// Interpolar entre color base y color aclarado
Color target_color = color_.LIGHTEN(PANEL_PULSE_LIGHTEN_AMOUNT);
//Color target_color = color_.INVERSE();
// Color target_color = color_.INVERSE();
background_color = color_.LERP(target_color, pulse_intensity);
background_color.a = 255; // Opaco durante el pulso
}
@@ -737,7 +740,7 @@ void Scoreboard::renderCarousel(size_t panel_index, int center_x, int y) {
constexpr int HALF_VISIBLE = CAROUSEL_VISIBLE_LETTERS / 2; // 4 letras a cada lado
// Posición flotante actual del carrusel (índice en la lista de caracteres)
float CAROUSEL_POS = carousel_position_.at(panel_index);
float carousel_pos = carousel_position_.at(panel_index);
const int CHAR_LIST_SIZE = static_cast<int>(char_list.size());
// Calcular ancho promedio de una letra (asumimos ancho uniforme)
@@ -745,17 +748,17 @@ void Scoreboard::renderCarousel(size_t panel_index, int center_x, int y) {
const int CHAR_STEP = AVG_CHAR_WIDTH + EXTRA_SPACING;
// --- Corrección visual de residuales flotantes (evita “baile”) ---
float frac = CAROUSEL_POS - std::floor(CAROUSEL_POS);
if (frac > 0.999f || frac < 0.001f) {
CAROUSEL_POS = std::round(CAROUSEL_POS);
frac = 0.0f;
float frac = carousel_pos - std::floor(carousel_pos);
if (frac > 0.999F || frac < 0.001F) {
carousel_pos = std::round(carousel_pos);
frac = 0.0F;
}
const float FRACTIONAL_OFFSET = frac;
const int PIXEL_OFFSET = static_cast<int>(FRACTIONAL_OFFSET * CHAR_STEP + 0.5f);
// Índice base en la lista de caracteres (posición central)
const int BASE_INDEX = static_cast<int>(std::floor(CAROUSEL_POS));
const int BASE_INDEX = static_cast<int>(std::floor(carousel_pos));
// Calcular posición X inicial (centrar las 9 letras visibles)
int start_x = center_x - (HALF_VISIBLE * CHAR_STEP) - (AVG_CHAR_WIDTH / 2) - PIXEL_OFFSET;
@@ -770,24 +773,24 @@ void Scoreboard::renderCarousel(size_t panel_index, int center_x, int y) {
}
// --- Calcular distancia circular correcta (corregido el bug de wrap) ---
float normalized_pos = std::fmod(CAROUSEL_POS, static_cast<float>(CHAR_LIST_SIZE));
if (normalized_pos < 0.0f) normalized_pos += static_cast<float>(CHAR_LIST_SIZE);
float normalized_pos = std::fmod(carousel_pos, static_cast<float>(CHAR_LIST_SIZE));
if (normalized_pos < 0.0F) normalized_pos += static_cast<float>(CHAR_LIST_SIZE);
float diff = std::abs(static_cast<float>(char_index) - normalized_pos);
if (diff > static_cast<float>(CHAR_LIST_SIZE) / 2.0f)
if (diff > static_cast<float>(CHAR_LIST_SIZE) / 2.0F)
diff = static_cast<float>(CHAR_LIST_SIZE) - diff;
const float distance_from_center = diff;
const float DISTANCE_FROM_CENTER = diff;
// --- Seleccionar color con LERP según la distancia ---
Color letter_color;
if (distance_from_center < 0.5F) {
if (DISTANCE_FROM_CENTER < 0.5F) {
// Letra central → transiciona hacia animated_color_
float lerp_to_animated = distance_from_center / 0.5F; // 0.0 a 1.0
float lerp_to_animated = DISTANCE_FROM_CENTER / 0.5F; // 0.0 a 1.0
letter_color = animated_color_.LERP(text_color1_, lerp_to_animated);
} else {
// Letras alejadas → degradan hacia color_ base
float base_lerp = (distance_from_center - 0.5F) / (HALF_VISIBLE - 0.5F);
float base_lerp = (DISTANCE_FROM_CENTER - 0.5F) / (HALF_VISIBLE - 0.5F);
base_lerp = std::min(base_lerp, 1.0F);
const float LERP_FACTOR = base_lerp * 0.85F;
letter_color = text_color1_.LERP(color_, LERP_FACTOR);

View File

@@ -51,8 +51,8 @@ class Scoreboard {
struct PanelPulse {
bool active = false; // Si el pulso está activo
float elapsed_s = 0.0f; // Tiempo transcurrido desde el inicio
float duration_s = 0.5f; // Duración total del pulso
float elapsed_s = 0.0F; // Tiempo transcurrido desde el inicio
float duration_s = 0.5F; // Duración total del pulso
};
// --- Métodos de singleton ---
@@ -80,7 +80,7 @@ class Scoreboard {
void setScore(Id id, int score) { score_.at(static_cast<size_t>(id)) = score; }
void setSelectorPos(Id id, int pos) { selector_pos_.at(static_cast<size_t>(id)) = pos; }
void setStage(int stage) { stage_ = stage; }
void triggerPanelPulse(Id id, float duration_s = 0.5f); // Activa un pulso en el panel especificado
void triggerPanelPulse(Id id, float duration_s = 0.5F); // Activa un pulso en el panel especificado
private:
// --- Objetos y punteros ---
@@ -117,8 +117,8 @@ class Scoreboard {
int time_counter_ = 0; // Contador de segundos
Uint32 name_color_index_ = 0; // Índice actual del color en el ciclo de animación del nombre
Uint64 name_color_last_update_ = 0; // Último tick de actualización del color del nombre
float power_ = 0; // Poder actual de la fase
std::array<float, static_cast<size_t>(Id::SIZE)> carousel_speed_scale_ = {1.0f, 1.0f, 1.0f};
float power_ = 0.0F; // Poder actual de la fase
std::array<float, static_cast<size_t>(Id::SIZE)> carousel_speed_scale_ = {1.0F, 1.0F, 1.0F};
// --- Constantes ---
static constexpr int CAROUSEL_VISIBLE_LETTERS = 9;

View File

@@ -409,8 +409,8 @@ void Credits::initPlayers() {
// Actualiza los rectangulos negros (time-based)
void Credits::updateBlackRects(float delta_time) {
if (!initialized_) return;
if (delta_time < 0.0f) delta_time = 0.0f;
if (!initialized_) { return; }
delta_time = std::max(delta_time, 0.0F);
// Fase vertical: hasta que ambos rects verticales estén exactos en su target
if (!vertical_done_) {
@@ -420,15 +420,15 @@ void Credits::updateBlackRects(float delta_time) {
// top
int prev_top_h = static_cast<int>(top_black_rect_.h);
top_black_rect_.h = std::min(top_black_rect_.h + 1.0f,
top_black_rect_.h = std::min(top_black_rect_.h + 1.0F,
static_cast<float>(param.game.game_area.center_y - 1));
int top_delta = static_cast<int>(top_black_rect_.h) - prev_top_h;
// bottom
int prev_bottom_h = static_cast<int>(bottom_black_rect_.h);
int prev_bottom_y = static_cast<int>(bottom_black_rect_.y);
bottom_black_rect_.h = bottom_black_rect_.h + 1.0f;
bottom_black_rect_.y = std::max(bottom_black_rect_.y - 1.0f,
bottom_black_rect_.h = bottom_black_rect_.h + 1.0F;
bottom_black_rect_.y = std::max(bottom_black_rect_.y - 1.0F,
static_cast<float>(param.game.game_area.center_y + 1));
int bottom_steps_by_h = static_cast<int>(bottom_black_rect_.h) - prev_bottom_h;
int bottom_steps_by_y = prev_bottom_y - static_cast<int>(bottom_black_rect_.y);
@@ -436,18 +436,18 @@ void Credits::updateBlackRects(float delta_time) {
int steps_done = top_delta + bottom_steps;
if (steps_done > 0) {
current_step_ = std::max(0.0f, current_step_ - static_cast<float>(steps_done));
current_step_ = std::max(0.0F, current_step_ - static_cast<float>(steps_done));
float vol_f = initial_volume_ * (current_step_ / static_cast<float>(total_steps_));
int vol_i = static_cast<int>(std::clamp(vol_f, 0.0f, static_cast<float>(initial_volume_)));
int vol_i = static_cast<int>(std::clamp(vol_f, 0.0F, static_cast<float>(initial_volume_)));
Audio::get()->setMusicVolume(vol_i); // usa tu API de audio aquí
}
// Si han alcanzado los objetivos, fijarlos exactamente y marcar done
bool top_at_target = static_cast<int>(top_black_rect_.h) == param.game.game_area.center_y - 1;
bool bottom_at_target = static_cast<int>(bottom_black_rect_.y) == param.game.game_area.center_y + 1;
bool top_at_target = static_cast<int>(top_black_rect_.h) == param.game.game_area.center_y - 1.0F;
bool bottom_at_target = static_cast<int>(bottom_black_rect_.y) == param.game.game_area.center_y + 1.0F;
if (top_at_target && bottom_at_target) {
top_black_rect_.h = static_cast<float>(param.game.game_area.center_y - 1);
bottom_black_rect_.y = static_cast<float>(param.game.game_area.center_y + 1);
top_black_rect_.h = param.game.game_area.center_y - 1.0F;
bottom_black_rect_.y = param.game.game_area.center_y + 1.0F;
vertical_done_ = true;
}
}
@@ -480,8 +480,8 @@ void Credits::updateBlackRects(float delta_time) {
bool left_at_target = static_cast<int>(left_black_rect_.w) == param.game.game_area.center_x;
bool right_at_target = static_cast<int>(right_black_rect_.x) == param.game.game_area.center_x;
if (left_at_target && right_at_target) {
left_black_rect_.w = static_cast<float>(param.game.game_area.center_x);
right_black_rect_.x = static_cast<float>(param.game.game_area.center_x);
left_black_rect_.w = param.game.game_area.center_x;
right_black_rect_.x = param.game.game_area.center_x;
horizontal_done_ = true;
}
@@ -504,13 +504,13 @@ void Credits::updateBlackRects(float delta_time) {
// Actualiza el rectangulo del borde
void Credits::updateBorderRect() {
border_rect_.x = left_black_rect_.x + left_black_rect_.w;
border_rect_.y = top_black_rect_.y + top_black_rect_.h - 1;
border_rect_.y = top_black_rect_.y + top_black_rect_.h - 1.0F;
float raw_w = right_black_rect_.x - border_rect_.x;
float raw_h = bottom_black_rect_.y - border_rect_.y + 1.0f;
float raw_h = bottom_black_rect_.y - border_rect_.y + 1.0F;
border_rect_.w = std::max(0.0f, raw_w);
border_rect_.h = std::max(0.0f, raw_h);
border_rect_.w = std::max(0.0F, raw_w);
border_rect_.h = std::max(0.0F, raw_h);
}
// Actualiza el estado de fade (time-based)
@@ -612,25 +612,25 @@ void Credits::renderPlayers() {
void Credits::initVars() {
// Inicialización segura de rects tal y como los mostraste
top_black_rect_ = {
play_area_.x,
param.game.game_area.rect.y,
play_area_.w,
black_bars_size_};
.x = play_area_.x,
.y = param.game.game_area.rect.y,
.w = play_area_.w,
.h = black_bars_size_};
bottom_black_rect_ = {
play_area_.x,
param.game.game_area.rect.h - black_bars_size_,
play_area_.w,
black_bars_size_};
.x = play_area_.x,
.y = param.game.game_area.rect.h - black_bars_size_,
.w = play_area_.w,
.h = black_bars_size_};
left_black_rect_ = {
play_area_.x,
param.game.game_area.center_y - 1,
0,
2};
.x = play_area_.x,
.y = param.game.game_area.center_y - 1.0F,
.w = 0.0F,
.h = 2.0F};
right_black_rect_ = {
play_area_.x + play_area_.w,
param.game.game_area.center_y - 1,
0,
2};
.x = play_area_.x + play_area_.w,
.y = param.game.game_area.center_y - 1.0F,
.w = 0.0F,
.h = 2.0F};
initialized_ = false;
@@ -659,10 +659,10 @@ void Credits::initVars() {
void Credits::startCredits() {
// Guardar iniciales (enteros para contar "pasos" por píxel)
init_top_h = static_cast<int>(top_black_rect_.h);
init_bottom_y = static_cast<int>(bottom_black_rect_.y);
init_left_w = static_cast<int>(left_black_rect_.w);
init_right_x = static_cast<int>(right_black_rect_.x);
init_top_h_ = static_cast<int>(top_black_rect_.h);
init_bottom_y_ = static_cast<int>(bottom_black_rect_.y);
init_left_w_ = static_cast<int>(left_black_rect_.w);
init_right_x_ = static_cast<int>(right_black_rect_.x);
// Objetivos
int top_target_h = param.game.game_area.center_y - 1;
@@ -671,12 +671,12 @@ void Credits::startCredits() {
int right_target_x = param.game.game_area.center_x;
// Pasos verticales
int pasos_top = std::max(0, top_target_h - init_top_h);
int pasos_bottom = std::max(0, init_bottom_y - bottom_target_y);
int pasos_top = std::max(0, top_target_h - init_top_h_);
int pasos_bottom = std::max(0, init_bottom_y_ - bottom_target_y);
// Pasos horizontales. right se mueve a velocidad HORIZONTAL_SPEED, contamos pasos como unidades de movimiento equivalentes
int pasos_left = std::max(0, left_target_w - init_left_w);
int dx_right = std::max(0, init_right_x - right_target_x);
int pasos_left = std::max(0, left_target_w - init_left_w_);
int dx_right = std::max(0, init_right_x_ - right_target_x);
int pasos_right = (dx_right + (HORIZONTAL_SPEED - 1)) / HORIZONTAL_SPEED; // ceil
total_steps_ = pasos_top + pasos_bottom + pasos_left + pasos_right;
@@ -685,20 +685,20 @@ void Credits::startCredits() {
current_step_ = static_cast<float>(total_steps_);
// Reiniciar contadores y estado
credits_state_.black_rect_accumulator = 0.0f;
counter_pre_fade_ = 0.0f;
credits_state_.black_rect_accumulator = 0.0F;
counter_pre_fade_ = 0.0F;
initialized_ = true;
// Asegurar volumen inicial consistente
if (steps_ <= 0) steps_ = 1;
float vol_f = initial_volume_ * (current_step_ / static_cast<float>(total_steps_));
setVolume(static_cast<int>(std::clamp(vol_f, 0.0f, static_cast<float>(initial_volume_))));
setVolume(static_cast<int>(std::clamp(vol_f, 0.0F, static_cast<float>(initial_volume_))));
}
// Dibuja el rectángulo del borde si es visible
void Credits::drawBorderRect() {
// Umbral: cualquier valor menor que 1 píxel no se considera visible
constexpr float VISIBLE_THRESHOLD = 1.0f;
constexpr float VISIBLE_THRESHOLD = 1.0F;
if (border_rect_.w < VISIBLE_THRESHOLD || border_rect_.h < VISIBLE_THRESHOLD) {
return; // no dibujar
}
@@ -709,10 +709,10 @@ void Credits::drawBorderRect() {
// Convertir a enteros de forma conservadora para evitar líneas de 1px por redondeo extraño
SDL_Rect r;
r.x = static_cast<int>(std::floor(border_rect_.x + 0.5f));
r.y = static_cast<int>(std::floor(border_rect_.y + 0.5f));
r.w = static_cast<int>(std::max(0.0f, std::floor(border_rect_.w + 0.5f)));
r.h = static_cast<int>(std::max(0.0f, std::floor(border_rect_.h + 0.5f)));
r.x = static_cast<int>(std::floor(border_rect_.x + 0.5F));
r.y = static_cast<int>(std::floor(border_rect_.y + 0.5F));
r.w = static_cast<int>(std::max(0.0f, std::floor(border_rect_.w + 0.5F)));
r.h = static_cast<int>(std::max(0.0f, std::floor(border_rect_.h + 0.5F)));
if (r.w > 0 && r.h > 0) {
SDL_RenderRect(Screen::get()->getRenderer(), &border_rect_);

View File

@@ -35,9 +35,9 @@ class Credits {
// --- Constantes de clase (time-based) ---
static constexpr int PLAY_AREA_HEIGHT = 200;
static constexpr float FAST_FORWARD_MULTIPLIER = 6.0F;
static constexpr float BLACK_RECT_INTERVAL_S = 4.0F / 60.0F; // ~0.0667s (cada 4 frames a 60fps)
static constexpr float BLACK_RECT_INTERVAL_S = 4.0F / 60.0F; // ~0.0667s (cada 4 frames a 60fps)
static constexpr int HORIZONTAL_SPEED = 2;
static constexpr float MAX_TIME_AFTER_LOGO_S = 20.0F;
static constexpr float MAX_TIME_AFTER_LOGO_S = 20.0F;
static constexpr float PRE_FADE_DELAY_S = 8.0F;
// --- Objetos principales ---
@@ -52,19 +52,19 @@ class Credits {
SDL_Texture* canvas_; // Textura donde se dibuja todo
// --- Temporización (time-based puro) ---
Uint64 last_time_ = 0; // Último tiempo registrado para deltaTime
float elapsed_time_balloons_ = 0.0F; // Tiempo acumulado para lanzamiento de globos (segundos)
float counter_pre_fade_ = 0.0F; // Tiempo antes de activar fundido final (segundos)
float time_since_logo_positioned_ = 0.0F; // Tiempo desde que el logo llegó a su posición (segundos)
Uint64 last_time_ = 0; // Último tiempo registrado para deltaTime
float elapsed_time_balloons_ = 0.0F; // Tiempo acumulado para lanzamiento de globos (segundos)
float counter_pre_fade_ = 0.0F; // Tiempo antes de activar fundido final (segundos)
float time_since_logo_positioned_ = 0.0F; // Tiempo desde que el logo llegó a su posición (segundos)
float current_step_ = 0.0F;
int total_steps_ = 1;
bool initialized_ = false;
// --- Guardar estados iniciales para cálculo de pasos ---
int init_top_h = 0;
int init_bottom_y = 0;
int init_left_w = 0;
int init_right_x = 0;
int init_top_h_ = 0;
int init_bottom_y_ = 0;
int init_left_w_ = 0;
int init_right_x_ = 0;
// --- Variables de estado ---
bool fading_ = false; // Estado del fade final

View File

@@ -370,7 +370,7 @@ void Game::updateGameStateGameOver(float delta_time) {
}
if (fade_out_->hasEnded()) {
Section::name = Section::Name::HI_SCORE_TABLE;
Section::name = Section::Name::HI_SCORE_TABLE;
Section::options = Section::Options::HI_SCORE_AFTER_PLAYING;
}
}
@@ -1961,68 +1961,68 @@ void Game::handleGameOverEvents() {
}
}
// Construye (una vez) el drawList a partir del vector principal
// drawList almacena punteros a los elementos y queda reservado
void Game::buildPlayerDrawList(const Players& elements, Players& drawList) {
drawList.clear();
drawList.reserve(elements.size());
for (const auto& e : elements) drawList.push_back(e); // copia el shared_ptr
std::stable_sort(drawList.begin(), drawList.end(), [](const std::shared_ptr<Player>& a, const std::shared_ptr<Player>& b) {
// Construye (una vez) el draw_list a partir del vector principal
// draw_list almacena punteros a los elementos y queda reservado
void Game::buildPlayerDrawList(const Players& elements, Players& draw_list) {
draw_list.clear();
draw_list.reserve(elements.size());
for (const auto& e : elements) draw_list.push_back(e); // copia el shared_ptr
std::stable_sort(draw_list.begin(), draw_list.end(), [](const std::shared_ptr<Player>& a, const std::shared_ptr<Player>& b) {
return a->getZOrder() < b->getZOrder();
});
}
// Actualiza drawList tras cambios en los z_order. Implementación simple:
// reordena drawList según los z_order actuales. Llamar cuando cambian z_order
void Game::updatePlayerDrawList(const Players& elements, Players& drawList) {
// Si drawList está vacío o su tamaño no coincide, reconstruirlo.
if (drawList.size() != elements.size()) {
buildPlayerDrawList(elements, drawList);
// Actualiza draw_list tras cambios en los z_order. Implementación simple:
// reordena draw_list según los z_order actuales. Llamar cuando cambian z_order
void Game::updatePlayerDrawList(const Players& elements, Players& draw_list) {
// Si draw_list está vacío o su tamaño no coincide, reconstruirlo.
if (draw_list.size() != elements.size()) {
buildPlayerDrawList(elements, draw_list);
return;
}
// Dado que apuntan a los mismos elementos, basta ordenar por los z_order actuales.
std::stable_sort(drawList.begin(), drawList.end(), [](const std::shared_ptr<Player>& a, const std::shared_ptr<Player>& b) {
std::stable_sort(draw_list.begin(), draw_list.end(), [](const std::shared_ptr<Player>& a, const std::shared_ptr<Player>& b) {
return a->getZOrder() < b->getZOrder();
});
}
// Dibuja en el orden definido por drawList
void Game::renderPlayerDrawList(const Players& drawList) {
for (const auto& e : drawList) e->render();
// Dibuja en el orden definido por draw_list
void Game::renderPlayerDrawList(const Players& draw_list) {
for (const auto& e : draw_list) e->render();
}
// Operaciones sobre z_order que mantienen la invariante y actualizan drawList.
// Operaciones sobre z_order que mantienen la invariante y actualizan draw_list.
auto Game::findPlayerIndex(const Players& elems, const std::shared_ptr<Player>& who) -> size_t {
for (size_t i = 0; i < elems.size(); ++i)
if (elems[i] == who) return static_cast<int>(i); // compara shared_ptr directamente
return -1;
}
void Game::sendPlayerToBack(Players& elements, const std::shared_ptr<Player>& who, Players& drawList) {
void Game::sendPlayerToBack(Players& elements, const std::shared_ptr<Player>& who, Players& draw_list) {
int idx = findPlayerIndex(elements, who);
if (idx < 0) return; // no encontrado
const int oldZ = elements[idx]->getZOrder();
if (oldZ <= 0) return;
const int OLD_Z = elements[idx]->getZOrder();
if (OLD_Z <= 0) return;
for (auto& p : elements) {
int z = p->getZOrder();
if (z < oldZ) p->setZOrder(z + 1);
if (z < OLD_Z) { p->setZOrder(z + 1); }
}
elements[idx]->setZOrder(0);
updatePlayerDrawList(elements, drawList);
updatePlayerDrawList(elements, draw_list);
}
void Game::bringPlayerToFront(Players& elements, const std::shared_ptr<Player>& who, Players& drawList) {
void Game::bringPlayerToFront(Players& elements, const std::shared_ptr<Player>& who, Players& draw_list) {
int idx = findPlayerIndex(elements, who);
if (idx < 0) return; // no encontrado
const int oldZ = elements[idx]->getZOrder();
const int OLD_Z = elements[idx]->getZOrder();
const int N = static_cast<int>(elements.size());
if (oldZ >= N - 1) return;
if (OLD_Z >= N - 1) return;
for (auto& p : elements) {
int z = p->getZOrder();
if (z > oldZ) p->setZOrder(z - 1);
if (z > OLD_Z) p->setZOrder(z - 1);
}
elements[idx]->setZOrder(N - 1);
updatePlayerDrawList(elements, drawList);
updatePlayerDrawList(elements, draw_list);
}
#ifdef _DEBUG

View File

@@ -336,12 +336,12 @@ class Game {
void playSound(const std::string& name) const; // Reproduce un efecto de sonido específico
// --- Gestion y dibujado de jugadores en z-order ---
void buildPlayerDrawList(const Players& elements, Players& drawList); // Construye el drawList a partir del vector principal
void updatePlayerDrawList(const Players& elements, Players& drawList); // Actualiza drawList tras cambios en los z_order
void renderPlayerDrawList(const Players& drawList); // Dibuja en el orden definido
void buildPlayerDrawList(const Players& elements, Players& draw_list); // Construye el draw_list a partir del vector principal
void updatePlayerDrawList(const Players& elements, Players& draw_list); // Actualiza draw_list tras cambios en los z_order
void renderPlayerDrawList(const Players& draw_list); // Dibuja en el orden definido
static auto findPlayerIndex(const Players& elems, const std::shared_ptr<Player>& who) -> size_t;
void sendPlayerToBack(Players& elements, const std::shared_ptr<Player>& who, Players& drawList); // Envia al jugador al fondo de la pantalla
void bringPlayerToFront(Players& elements, const std::shared_ptr<Player>& who, Players& drawList); // Envia al jugador al frente de la pantalla
void sendPlayerToBack(Players& elements, const std::shared_ptr<Player>& who, Players& draw_list); // Envia al jugador al fondo de la pantalla
void bringPlayerToFront(Players& elements, const std::shared_ptr<Player>& who, Players& draw_list); // Envia al jugador al frente de la pantalla
// --- Varios ---
void onPauseStateChanged(bool is_paused);

View File

@@ -51,7 +51,7 @@ void UIMessage::updateAnimation(float delta_time) {
float t = animation_timer_ / ANIMATION_DURATION_S;
// Clamp t entre 0 y 1
t = std::min(t, 1.0f);
t = std::min(t, 1.0F);
if (target_y_ > start_y_) {
// Animación de entrada (ease out cubic)