clang-tidy

This commit is contained in:
2025-08-17 10:20:41 +02:00
parent b359a73d50
commit 8ddc5d94f1
73 changed files with 867 additions and 833 deletions

44
linux_utils/run_clang-tidy.sh Executable file
View File

@@ -0,0 +1,44 @@
#!/bin/bash
# Script para ejecutar clang-tidy en múltiples directorios
# Uso: ./run_clang-tidy.sh
# Lista de rutas donde ejecutar clang-tidy
PATHS=(
"/home/sergio/gitea/coffee_crisis_arcade_edition/source"
"/home/sergio/gitea/coffee_crisis_arcade_edition/source/sections"
"/home/sergio/gitea/coffee_crisis_arcade_edition/source/ui"
)
# Ruta del directorio build (relativa desde donde se ejecuta el script)
BUILD_DIR="/home/sergio/gitea/coffee_crisis_arcade_edition/build/"
# Función para procesar un directorio
process_directory() {
local dir="$1"
echo "=== Procesando directorio: $dir ==="
# Verificar que el directorio existe
if [[ ! -d "$dir" ]]; then
echo "Error: El directorio $dir no existe"
return 1
fi
# Cambiar al directorio y ejecutar find con -maxdepth 1 para un solo nivel
cd "$dir" || return 1
# Buscar archivos .cpp, .h, .hpp solo en el nivel actual (no subdirectorios)
find . -maxdepth 1 \( -name '*.cpp' -o -name '*.h' -o -name '*.hpp' \) | \
xargs -P4 -I{} bash -c 'echo "Procesando: {}"; clang-tidy {} -p '"$BUILD_DIR"' --fix'
echo "=== Completado: $dir ==="
echo
}
# Procesar cada directorio en la lista
for path in "${PATHS[@]}"; do
process_directory "$path"
done
echo "¡Proceso completado para todos los directorios!"

View File

@@ -72,9 +72,9 @@ class AnimatedSprite : public MovingSprite {
protected:
// --- Variables de estado ---
std::vector<Animation> animations_; // Vector de animaciones disponibles
std::vector<Animation> animations_; // Vector de animaciones disponibles
std::unordered_map<std::string, int> animation_indices_; // Mapa para búsqueda rápida por nombre
int current_animation_ = 0; // Índice de la animación activa
int current_animation_ = 0; // Índice de la animación activa
// --- Métodos internos ---
void animate(); // Calcula el frame correspondiente a la animación

View File

@@ -92,7 +92,7 @@ void Asset::loadFromFile(const std::string &config_file_path, const std::string
}
try {
std::string type_str = parts[0];
const std::string &type_str = parts[0];
std::string path = parts[1];
// Valores por defecto

View File

@@ -53,12 +53,12 @@ class Asset {
std::string executable_path_; // Ruta del ejecutable
// --- Métodos internos ---
[[nodiscard]] static auto checkFile(const std::string &path) -> bool; // Verifica si un archivo existe
[[nodiscard]] static auto getTypeName(Type type) -> std::string; // Obtiene el nombre del tipo
[[nodiscard]] static auto parseAssetType(const std::string &type_str) -> Type; // Convierte string a tipo
void addToMap(const std::string &file_path, Type type, bool required, bool absolute); // Añade archivo al mapa
[[nodiscard]] static auto replaceVariables(const std::string &path, const std::string &prefix, const std::string &system_folder) -> std::string; // Reemplaza variables en la ruta
static auto parseOptions(const std::string &options, bool &required, bool &absolute) -> void; // Parsea opciones
[[nodiscard]] static auto checkFile(const std::string &path) -> bool; // Verifica si un archivo existe
[[nodiscard]] static auto getTypeName(Type type) -> std::string; // Obtiene el nombre del tipo
[[nodiscard]] static auto parseAssetType(const std::string &type_str) -> Type; // Convierte string a tipo
void addToMap(const std::string &file_path, Type type, bool required, bool absolute); // Añade archivo al mapa
[[nodiscard]] static auto replaceVariables(const std::string &path, const std::string &prefix, const std::string &system_folder) -> std::string; // Reemplaza variables en la ruta
static auto parseOptions(const std::string &options, bool &required, bool &absolute) -> void; // Parsea opciones
// --- Constructores y destructor privados (singleton) ---
explicit Asset(std::string executable_path) // Constructor privado

View File

@@ -8,15 +8,15 @@ class Audio {
public:
// --- Enums ---
enum class Group : int {
ALL = -1, // Todos los grupos
GAME = 0, // Sonidos del juego
INTERFACE = 1 // Sonidos de la interfaz
ALL = -1, // Todos los grupos
GAME = 0, // Sonidos del juego
INTERFACE = 1 // Sonidos de la interfaz
};
// --- Constantes ---
static constexpr int MAX_VOLUME = 100; // Volumen máximo
static constexpr int MIN_VOLUME = 0; // Volumen mínimo
static constexpr int FREQUENCY = 48000; // Frecuencia de audio
static constexpr int MAX_VOLUME = 100; // Volumen máximo
static constexpr int MIN_VOLUME = 0; // Volumen mínimo
static constexpr int FREQUENCY = 48000; // Frecuencia de audio
// --- Métodos de singleton ---
static void init(); // Inicializa el objeto Audio
@@ -63,9 +63,9 @@ class Audio {
private:
// --- Enums privados ---
enum class MusicState {
PLAYING, // Reproduciendo música
PAUSED, // Música pausada
STOPPED, // Música detenida
PLAYING, // Reproduciendo música
PAUSED, // Música pausada
STOPPED, // Música detenida
};
// --- Estructuras privadas ---
@@ -83,10 +83,10 @@ class Audio {
};
// --- Variables de estado ---
Music music_; // Estado de la música
bool enabled_ = true; // Estado general del audio
bool sound_enabled_ = true; // Estado de los efectos de sonido
bool music_enabled_ = true; // Estado de la música
Music music_; // Estado de la música
bool enabled_ = true; // Estado general del audio
bool sound_enabled_ = true; // Estado de los efectos de sonido
bool music_enabled_ = true; // Estado de la música
// --- Métodos internos ---
void initSDLAudio(); // Inicializa SDL Audio

View File

@@ -31,8 +31,8 @@ Background::Background(float total_progress_to_complete)
sun_completion_progress_(total_progress_to_complete_ * SUN_COMPLETION_FACTOR),
rect_(SDL_FRect{0, 0, static_cast<float>(gradients_texture_->getWidth() / 2), static_cast<float>(gradients_texture_->getHeight() / 2)}),
src_rect_({0, 0, 320, 240}),
dst_rect_({0, 0, 320, 240}),
src_rect_({.x = 0, .y = 0, .w = 320, .h = 240}),
dst_rect_({.x = 0, .y = 0, .w = 320, .h = 240}),
attenuate_color_(Color(param.background.attenuate_color.r, param.background.attenuate_color.g, param.background.attenuate_color.b)),
alpha_color_texture_(param.background.attenuate_color.a),
@@ -59,17 +59,17 @@ void Background::initializePaths() {
// Inicializa los rectángulos de gradientes y nubes
void Background::initializeRects() {
gradient_rect_[0] = {0, 0, rect_.w, rect_.h};
gradient_rect_[1] = {rect_.w, 0, rect_.w, rect_.h};
gradient_rect_[2] = {0, rect_.h, rect_.w, rect_.h};
gradient_rect_[3] = {rect_.w, rect_.h, rect_.w, rect_.h};
gradient_rect_[0] = {.x = 0, .y = 0, .w = rect_.w, .h = rect_.h};
gradient_rect_[1] = {.x = rect_.w, .y = 0, .w = rect_.w, .h = rect_.h};
gradient_rect_[2] = {.x = 0, .y = rect_.h, .w = rect_.w, .h = rect_.h};
gradient_rect_[3] = {.x = rect_.w, .y = rect_.h, .w = rect_.w, .h = rect_.h};
const float TOP_CLOUDS_TEXTURE_HEIGHT = top_clouds_texture_->getHeight() / 4;
const float BOTTOM_CLOUDS_TEXTURE_HEIGHT = bottom_clouds_texture_->getHeight() / 4;
for (int i = 0; i < 4; ++i) {
top_clouds_rect_[i] = {0, i * TOP_CLOUDS_TEXTURE_HEIGHT, static_cast<float>(top_clouds_texture_->getWidth()), TOP_CLOUDS_TEXTURE_HEIGHT};
bottom_clouds_rect_[i] = {0, i * BOTTOM_CLOUDS_TEXTURE_HEIGHT, static_cast<float>(bottom_clouds_texture_->getWidth()), BOTTOM_CLOUDS_TEXTURE_HEIGHT};
top_clouds_rect_[i] = {.x = 0, .y = i * TOP_CLOUDS_TEXTURE_HEIGHT, .w = static_cast<float>(top_clouds_texture_->getWidth()), .h = TOP_CLOUDS_TEXTURE_HEIGHT};
bottom_clouds_rect_[i] = {.x = 0, .y = i * BOTTOM_CLOUDS_TEXTURE_HEIGHT, .w = static_cast<float>(bottom_clouds_texture_->getWidth()), .h = BOTTOM_CLOUDS_TEXTURE_HEIGHT};
}
}
@@ -479,7 +479,7 @@ void Background::createSunPath() {
const int NUM_STEPS = static_cast<int>((M_PI - M_PI / 2) / STEP) + 1;
for (int i = 0; i < NUM_STEPS; ++i) {
double theta = M_PI / 2 + i * STEP;
double theta = M_PI / 2 + (i * STEP);
float x = CENTER_X + (RADIUS * cos(theta));
float y = CENTER_Y - (RADIUS * sin(theta));
sun_path_.push_back({x, y});

View File

@@ -19,8 +19,8 @@ class Background {
public:
// --- Enums ---
enum class State {
NORMAL, // Progresión normal del día
COMPLETED // Reducción gradual de la actividad
NORMAL, // Progresión normal del día
COMPLETED // Reducción gradual de la actividad
};
// --- Tipos ---
@@ -28,7 +28,7 @@ class Background {
// --- Constructor y destructor ---
Background(float total_progress_to_complete = 6100.0F); // Constructor principal
~Background(); // Destructor
~Background(); // Destructor
// --- Métodos principales ---
void update(); // Actualiza la lógica del objeto
@@ -54,67 +54,67 @@ class Background {
void setProgress(float absolute_progress); // Establece la progresión absoluta
// --- Getters ---
[[nodiscard]] auto getProgress() const -> float { return progress_; } // Obtiene el progreso actual
[[nodiscard]] auto getState() const -> State { return state_; } // Obtiene el estado actual
[[nodiscard]] auto getCurrentGradient() const -> int { return static_cast<int>(gradient_number_); } // Obtiene el gradiente actual
[[nodiscard]] auto getProgress() const -> float { return progress_; } // Obtiene el progreso actual
[[nodiscard]] auto getState() const -> State { return state_; } // Obtiene el estado actual
[[nodiscard]] auto getCurrentGradient() const -> int { return static_cast<int>(gradient_number_); } // Obtiene el gradiente actual
private:
// --- Constantes ---
static constexpr size_t STAGES = 4; // Número de etapas
static constexpr float COMPLETED_REDUCTION_RATE = 25.0F; // Tasa de reducción completada
static constexpr float MINIMUM_COMPLETED_PROGRESS = 200.0F; // Progreso mínimo completado
static constexpr float SUN_COMPLETION_FACTOR = 0.5F; // Factor de completado del sol
static constexpr size_t STAGES = 4; // Número de etapas
static constexpr float COMPLETED_REDUCTION_RATE = 25.0F; // Tasa de reducción completada
static constexpr float MINIMUM_COMPLETED_PROGRESS = 200.0F; // Progreso mínimo completado
static constexpr float SUN_COMPLETION_FACTOR = 0.5F; // Factor de completado del sol
// --- Objetos y punteros ---
SDL_Renderer *renderer_; // Renderizador de la ventana
SDL_Texture *canvas_; // Textura para componer el fondo
SDL_Texture *color_texture_; // Textura para atenuar el fondo
std::shared_ptr<Texture> buildings_texture_; // Textura de edificios
std::shared_ptr<Texture> top_clouds_texture_; // Textura de nubes superiores
std::shared_ptr<Texture> bottom_clouds_texture_; // Textura de nubes inferiores
std::shared_ptr<Texture> grass_texture_; // Textura de hierba
std::shared_ptr<Texture> gradients_texture_; // Textura de gradientes
std::shared_ptr<Texture> sun_texture_; // Textura del sol
std::shared_ptr<Texture> moon_texture_; // Textura de la luna
std::unique_ptr<MovingSprite> top_clouds_sprite_a_; // Sprite de nubes superiores A
std::unique_ptr<MovingSprite> top_clouds_sprite_b_; // Sprite de nubes superiores B
std::unique_ptr<MovingSprite> bottom_clouds_sprite_a_; // Sprite de nubes inferiores A
std::unique_ptr<MovingSprite> bottom_clouds_sprite_b_; // Sprite de nubes inferiores B
std::unique_ptr<Sprite> buildings_sprite_; // Sprite de edificios
std::unique_ptr<Sprite> gradient_sprite_; // Sprite de gradiente
std::unique_ptr<Sprite> grass_sprite_; // Sprite de hierba
std::unique_ptr<Sprite> sun_sprite_; // Sprite del sol
std::unique_ptr<Sprite> moon_sprite_; // Sprite de la luna
SDL_Renderer *renderer_; // Renderizador de la ventana
SDL_Texture *canvas_; // Textura para componer el fondo
SDL_Texture *color_texture_; // Textura para atenuar el fondo
std::shared_ptr<Texture> buildings_texture_; // Textura de edificios
std::shared_ptr<Texture> top_clouds_texture_; // Textura de nubes superiores
std::shared_ptr<Texture> bottom_clouds_texture_; // Textura de nubes inferiores
std::shared_ptr<Texture> grass_texture_; // Textura de hierba
std::shared_ptr<Texture> gradients_texture_; // Textura de gradientes
std::shared_ptr<Texture> sun_texture_; // Textura del sol
std::shared_ptr<Texture> moon_texture_; // Textura de la luna
std::unique_ptr<MovingSprite> top_clouds_sprite_a_; // Sprite de nubes superiores A
std::unique_ptr<MovingSprite> top_clouds_sprite_b_; // Sprite de nubes superiores B
std::unique_ptr<MovingSprite> bottom_clouds_sprite_a_; // Sprite de nubes inferiores A
std::unique_ptr<MovingSprite> bottom_clouds_sprite_b_; // Sprite de nubes inferiores B
std::unique_ptr<Sprite> buildings_sprite_; // Sprite de edificios
std::unique_ptr<Sprite> gradient_sprite_; // Sprite de gradiente
std::unique_ptr<Sprite> grass_sprite_; // Sprite de hierba
std::unique_ptr<Sprite> sun_sprite_; // Sprite del sol
std::unique_ptr<Sprite> moon_sprite_; // Sprite de la luna
// --- Variables de configuración ---
const float total_progress_to_complete_; // Progreso total para completar
const float progress_per_stage_; // Progreso por etapa
const float sun_completion_progress_; // Progreso de completado del sol
ProgressCallback progress_callback_; // Callback para notificar cambios de progreso
const float total_progress_to_complete_; // Progreso total para completar
const float progress_per_stage_; // Progreso por etapa
const float sun_completion_progress_; // Progreso de completado del sol
ProgressCallback progress_callback_; // Callback para notificar cambios de progreso
// --- Variables de estado ---
std::vector<SDL_FPoint> sun_path_; // Recorrido del sol
std::vector<SDL_FPoint> moon_path_; // Recorrido de la luna
std::array<SDL_FRect, STAGES> gradient_rect_; // Fondos degradados
std::array<SDL_FRect, 4> top_clouds_rect_; // Nubes superiores
std::array<SDL_FRect, 4> bottom_clouds_rect_; // Nubes inferiores
SDL_FRect rect_; // Tamaño del objeto
SDL_FRect src_rect_; // Parte del objeto para copiar en pantalla
SDL_FRect dst_rect_; // Posición en pantalla donde se copia el objeto
Color attenuate_color_; // Color de atenuación
State state_ = State::NORMAL; // Estado actual
float progress_ = 0.0F; // Progresión interna
float clouds_speed_ = 0; // Velocidad de las nubes
float transition_ = 0; // Porcentaje de transición
size_t gradient_number_ = 0; // Índice de fondo degradado
size_t counter_ = 0; // Contador interno
size_t alpha_color_texture_ = 0; // Transparencia de atenuación
size_t previous_alpha_color_texture_ = 0; // Transparencia anterior
size_t sun_index_ = 0; // Índice del recorrido del sol
size_t moon_index_ = 0; // Índice del recorrido de la luna
int base_ = 0; // Posición base del fondo
Uint8 alpha_ = 0; // Transparencia entre fases
bool manual_mode_ = false; // Si está en modo manual
std::vector<SDL_FPoint> sun_path_; // Recorrido del sol
std::vector<SDL_FPoint> moon_path_; // Recorrido de la luna
std::array<SDL_FRect, STAGES> gradient_rect_; // Fondos degradados
std::array<SDL_FRect, 4> top_clouds_rect_; // Nubes superiores
std::array<SDL_FRect, 4> bottom_clouds_rect_; // Nubes inferiores
SDL_FRect rect_; // Tamaño del objeto
SDL_FRect src_rect_; // Parte del objeto para copiar en pantalla
SDL_FRect dst_rect_; // Posición en pantalla donde se copia el objeto
Color attenuate_color_; // Color de atenuación
State state_ = State::NORMAL; // Estado actual
float progress_ = 0.0F; // Progresión interna
float clouds_speed_ = 0; // Velocidad de las nubes
float transition_ = 0; // Porcentaje de transición
size_t gradient_number_ = 0; // Índice de fondo degradado
size_t counter_ = 0; // Contador interno
size_t alpha_color_texture_ = 0; // Transparencia de atenuación
size_t previous_alpha_color_texture_ = 0; // Transparencia anterior
size_t sun_index_ = 0; // Índice del recorrido del sol
size_t moon_index_ = 0; // Índice del recorrido de la luna
int base_ = 0; // Posición base del fondo
Uint8 alpha_ = 0; // Transparencia entre fases
bool manual_mode_ = false; // Si está en modo manual
// --- Métodos internos ---
void initializePaths(); // Inicializa las rutas del sol y la luna

View File

@@ -40,16 +40,16 @@ class Balloon {
// --- Enums ---
enum class Size : Uint8 {
SMALL = 0, // Tamaño pequeño
MEDIUM = 1, // Tamaño mediano
LARGE = 2, // Tamaño grande
EXTRALARGE = 3, // Tamaño extra grande
SMALL = 0, // Tamaño pequeño
MEDIUM = 1, // Tamaño mediano
LARGE = 2, // Tamaño grande
EXTRALARGE = 3, // Tamaño extra grande
};
enum class Type : Uint8 {
BALLOON = 0, // Globo normal
FLOATER = 1, // Globo flotante
POWERBALL = 2, // Globo de poder
BALLOON = 0, // Globo normal
FLOATER = 1, // Globo flotante
POWERBALL = 2, // Globo de poder
};
// --- Constructores y destructor ---

View File

@@ -134,8 +134,8 @@ void BalloonManager::deployFormation(int formation_id, int y) {
// Vacia del vector de globos los globos que ya no sirven
void BalloonManager::freeBalloons() {
auto it = std::remove_if(balloons_.begin(), balloons_.end(), [](const auto &balloon) { return !balloon->isEnabled(); });
balloons_.erase(it, balloons_.end());
auto result = std::ranges::remove_if(balloons_, [](const auto &balloon) { return !balloon->isEnabled(); });
balloons_.erase(result.begin(), balloons_.end());
}
// Actualiza la variable enemyDeployCounter
@@ -336,7 +336,7 @@ void BalloonManager::createTwoBigBalloons() {
// Crea una disposición de globos aleatoria
void BalloonManager::createRandomBalloons() {
const int NUM_BALLOONS = 2 + rand() % 4;
const int NUM_BALLOONS = 2 + (rand() % 4);
for (int i = 0; i < NUM_BALLOONS; ++i) {
const float X = param.game.game_area.rect.x + (rand() % static_cast<int>(param.game.game_area.rect.w)) - Balloon::WIDTH.at(3);
const int Y = param.game.game_area.rect.y + (rand() % 50);

View File

@@ -56,10 +56,10 @@ class BalloonManager {
// --- Manipulación de globos existentes ---
auto popBalloon(const std::shared_ptr<Balloon> &balloon) -> int; // Explosiona un globo, creando otros si aplica
auto destroyBalloon(std::shared_ptr<Balloon> &balloon) -> int; // Explosiona un globo sin crear otros
auto destroyAllBalloons() -> int; // Destruye todos los globos
void stopAllBalloons(); // Detiene el movimiento de los globos
void startAllBalloons(); // Reactiva el movimiento de los globos
auto destroyBalloon(std::shared_ptr<Balloon> &balloon) -> int; // Explosiona un globo sin crear otros
auto destroyAllBalloons() -> int; // Destruye todos los globos
void stopAllBalloons(); // Detiene el movimiento de los globos
void startAllBalloons(); // Reactiva el movimiento de los globos
// --- Cambios de apariencia ---
void reverseColorsToAllBalloons(); // Invierte los colores de los globos
@@ -86,14 +86,14 @@ class BalloonManager {
static const int DEFAULT_BALLOON_DEPLOY_COUNTER = 300;
// --- Objetos y punteros ---
Balloons balloons_; // Vector con los globos activos
std::unique_ptr<Explosions> explosions_; // Objeto para gestionar explosiones
std::unique_ptr<BalloonFormations> balloon_formations_; // Objeto para manejar formaciones enemigas
std::vector<std::shared_ptr<Texture>> balloon_textures_; // Texturas de los globos
std::vector<std::shared_ptr<Texture>> explosions_textures_; // Texturas de explosiones
Balloons balloons_; // Vector con los globos activos
std::unique_ptr<Explosions> explosions_; // Objeto para gestionar explosiones
std::unique_ptr<BalloonFormations> balloon_formations_; // Objeto para manejar formaciones enemigas
std::vector<std::shared_ptr<Texture>> balloon_textures_; // Texturas de los globos
std::vector<std::shared_ptr<Texture>> explosions_textures_; // Texturas de explosiones
std::vector<std::vector<std::string>> balloon_animations_; // Animaciones de los globos
std::vector<std::vector<std::string>> explosions_animations_; // Animaciones de las explosiones
IStageInfo *stage_info_; // Informacion de la pantalla actual
IStageInfo *stage_info_; // Informacion de la pantalla actual
// --- Variables de estado ---
SDL_FRect play_area_ = param.game.play_area.rect;

View File

@@ -9,10 +9,10 @@
// Constructor
Bullet::Bullet(float x, float y, BulletType bullet_type, bool powered, Player::Id owner)
: sprite_(std::make_unique<AnimatedSprite>(Resource::get()->getTexture("bullet.png"), Resource::get()->getAnimation("bullet.ani"))),
bullet_type_(bullet_type),
owner_(owner) ,
bullet_type_(bullet_type),
owner_(owner),
pos_x_(x),
pos_y_(y){
pos_y_(y) {
vel_x_ = calculateVelocity(bullet_type_);
sprite_->setCurrentAnimation(buildAnimationString(bullet_type_, powered));

View File

@@ -18,8 +18,8 @@ enum class BulletType : Uint8 {
};
enum class BulletMoveStatus : Uint8 {
OK = 0, // Movimiento normal
OUT = 1 // Fuera de los límites
OK = 0, // Movimiento normal
OUT = 1 // Fuera de los límites
};
// --- Clase Bullet: representa una bala del jugador ---
@@ -34,21 +34,21 @@ class Bullet {
~Bullet() = default; // Destructor
// --- Métodos principales ---
void render(); // Dibuja la bala en pantalla
auto update() -> BulletMoveStatus; // Actualiza el estado del objeto
void disable(); // Desactiva la bala
void render(); // Dibuja la bala en pantalla
auto update() -> BulletMoveStatus; // Actualiza el estado del objeto
void disable(); // Desactiva la bala
// --- Getters ---
[[nodiscard]] auto isEnabled() const -> bool; // Comprueba si está activa
[[nodiscard]] auto getOwner() const -> Player::Id; // Devuelve el identificador del dueño
auto getCollider() -> Circle &; // Devuelve el círculo de colisión
[[nodiscard]] auto isEnabled() const -> bool; // Comprueba si está activa
[[nodiscard]] auto getOwner() const -> Player::Id; // Devuelve el identificador del dueño
auto getCollider() -> Circle &; // Devuelve el círculo de colisión
private:
// --- Constantes ---
static constexpr float VEL_Y = -3.0F; // Velocidad vertical
static constexpr float VEL_X_LEFT = -2.0F; // Velocidad izquierda
static constexpr float VEL_X_RIGHT = 2.0F; // Velocidad derecha
static constexpr float VEL_X_CENTER = 0.0F; // Velocidad central
static constexpr float VEL_Y = -3.0F; // Velocidad vertical
static constexpr float VEL_X_LEFT = -2.0F; // Velocidad izquierda
static constexpr float VEL_X_RIGHT = 2.0F; // Velocidad derecha
static constexpr float VEL_X_CENTER = 0.0F; // Velocidad central
// --- Objetos y punteros ---
std::unique_ptr<AnimatedSprite> sprite_; // Sprite con los gráficos

View File

@@ -44,7 +44,7 @@ auto Color::fromHex(const std::string &hex_str) -> Color {
// Obtiene un color del vector de colores imitando al Coche Fantástico
auto getColorLikeKnightRider(const std::vector<Color> &colors, int counter) -> Color {
int cycle_length = colors.size() * 2 - 2;
int cycle_length = (colors.size() * 2) - 2;
size_t n = counter % cycle_length;
size_t index;
@@ -84,7 +84,7 @@ constexpr auto rgbToHsv(Color color) -> HSV {
float s = (max <= 0.0F) ? 0.0F : delta / max;
float v = max;
return {h, s, v};
return {.h = h, .s = s, .v = v};
}
constexpr auto hsvToRgb(HSV hsv) -> Color {
@@ -169,13 +169,13 @@ auto generateMirroredCycle(Color base, ColorCycleStyle style) -> ColorCycle {
}
HSV adjusted = {
fmodf(base_hsv.h + hue_shift + 360.0F, 360.0F),
fminf(1.0F, fmaxf(0.0F, base_hsv.s + sat_shift)),
fminf(1.0F, fmaxf(0.0F, base_hsv.v + val_shift))};
.h = fmodf(base_hsv.h + hue_shift + 360.0F, 360.0F),
.s = fminf(1.0F, fmaxf(0.0F, base_hsv.s + sat_shift)),
.v = fminf(1.0F, fmaxf(0.0F, base_hsv.v + val_shift))};
Color c = hsvToRgb(adjusted);
result[i] = c;
result[2 * COLOR_CYCLE_SIZE - 1 - i] = c; // espejo
result[(2 * COLOR_CYCLE_SIZE) - 1 - i] = c; // espejo
}
return result;

View File

@@ -19,7 +19,7 @@ DefineButtons::DefineButtons()
clearButtons();
auto gamepads = input_->getGamepads();
for (auto gamepad : gamepads) {
for (const auto &gamepad : gamepads) {
controller_names_.emplace_back(Input::getControllerName(gamepad));
}

View File

@@ -8,9 +8,9 @@ static std::vector<Info> difficulties_list;
void init() {
difficulties_list = {
{Code::EASY, "Easy"},
{Code::NORMAL, "Normal"},
{Code::HARD, "Hard"}};
{.code = Code::EASY, .name = "Easy"},
{.code = Code::NORMAL, .name = "Normal"},
{.code = Code::HARD, .name = "Hard"}};
}
auto getDifficulties() -> std::vector<Info>& {

View File

@@ -21,8 +21,8 @@ struct Info {
// --- Funciones ---
void init(); // Inicializa la lista de dificultades con sus valores por defecto
auto getDifficulties() -> std::vector<Info>&; // Devuelve una referencia al vector de todas las dificultades
auto getNameFromCode(Code code) -> std::string; // Obtiene el nombre de una dificultad a partir de su código
auto getCodeFromName(const std::string& name) -> Code; // Obtiene el código de una dificultad a partir de su nombre
auto getDifficulties() -> std::vector<Info>&; // Devuelve una referencia al vector de todas las dificultades
auto getNameFromCode(Code code) -> std::string; // Obtiene el nombre de una dificultad a partir de su código
auto getCodeFromName(const std::string& name) -> Code; // Obtiene el código de una dificultad a partir de su nombre
} // namespace Difficulty

View File

@@ -42,7 +42,7 @@ void EnterName::incPosition() {
if (position_ >= NAME_SIZE) {
position_ = NAME_SIZE; // Mantenemos en el índice máximo válido.
position_overflow_ = true; // Activamos el flag de overflow.
} else if (position_ > 0) // No es necesario verificar position_ < MAX_NAME_LENGHT
} else if (position_ > 0) // No es necesario verificar position_ < MAX_NAME_LENGTH
{
// Copiamos el índice del carácter anterior si es posible.
character_index_[position_] = character_index_[position_ - 1];
@@ -74,7 +74,7 @@ void EnterName::decPosition() {
// character_index_[position_] = 0;
}
// Si position_ es menor que NAME_LENGHT, aseguramos que el overflow esté desactivado.
// Si position_ es menor que NAME_LENGTH, aseguramos que el overflow esté desactivado.
if (position_ < NAME_SIZE) {
position_overflow_ = false;
}

View File

@@ -1,9 +1,9 @@
#pragma once
#include <memory> // Para unique_ptr, shared_ptr
#include <string> // Para string
#include <utility> // Para move
#include <vector> // Para vector
#include <memory> // Para unique_ptr, shared_ptr
#include <string> // Para string
#include <utility> // Para move
#include <vector> // Para vector
#include "animated_sprite.h" // Para AnimatedSprite
@@ -32,14 +32,14 @@ class Explosions {
// --- Configuración ---
void addTexture(int size, const std::shared_ptr<Texture> &texture, const std::vector<std::string> &animation); // Añade texturas al objeto
void add(int x, int y, int size); // Añade una explosión
void add(int x, int y, int size); // Añade una explosión
private:
// --- Variables de estado ---
std::vector<ExplosionTexture> textures_; // Vector con las texturas a utilizar
std::vector<std::unique_ptr<AnimatedSprite>> explosions_; // Lista con todas las explosiones
std::vector<ExplosionTexture> textures_; // Vector con las texturas a utilizar
std::vector<std::unique_ptr<AnimatedSprite>> explosions_; // Lista con todas las explosiones
// --- Métodos internos ---
void freeExplosions(); // Vacía el vector de elementos finalizados
auto getIndexBySize(int size) -> int; // Busca una textura a partir del tamaño
void freeExplosions(); // Vacía el vector de elementos finalizados
auto getIndexBySize(int size) -> int; // Busca una textura a partir del tamaño
};

View File

@@ -177,7 +177,7 @@ void Fade::drawRandomSquares() {
(num_squares_width_ * num_squares_height_) - 1);
for (int i = 0; i < fade_random_squares_mult_; ++i) {
const int INDEX2 = std::min(INDEX * fade_random_squares_mult_ + i,
const int INDEX2 = std::min((INDEX * fade_random_squares_mult_) + i,
static_cast<int>(square_.size()) - 1);
SDL_RenderFillRect(renderer_, &square_[INDEX2]);
}
@@ -250,14 +250,14 @@ void Fade::activate() {
}
case Type::CENTER: {
rect1_ = {0, 0, param.game.width, 0};
rect2_ = {0, 0, param.game.width, 0};
rect1_ = {.x = 0, .y = 0, .w = param.game.width, .h = 0};
rect2_ = {.x = 0, .y = 0, .w = param.game.width, .h = 0};
a_ = 64;
break;
}
case Type::RANDOM_SQUARE: {
rect1_ = {0, 0, static_cast<float>(param.game.width / num_squares_width_), static_cast<float>(param.game.height / num_squares_height_)};
rect1_ = {.x = 0, .y = 0, .w = static_cast<float>(param.game.width / num_squares_width_), .h = static_cast<float>(param.game.height / num_squares_height_)};
square_.clear();
// Añade los cuadrados al vector
@@ -297,7 +297,7 @@ void Fade::activate() {
// Añade los cuadrados al vector
square_.clear();
rect1_ = {0, 0, param.game.width, 0};
rect1_ = {.x = 0, .y = 0, .w = param.game.width, .h = 0};
const int MAX = param.game.height / param.fade.venetian_size;
for (int i = 0; i < MAX; ++i) {

View File

@@ -16,7 +16,7 @@
constexpr int ZOOM_FACTOR = 5;
constexpr int FLASH_DELAY = 3;
constexpr int FLASH_LENGHT = FLASH_DELAY + 3;
constexpr int FLASH_LENGTH = FLASH_DELAY + 3;
// Constructor
GameLogo::GameLogo(int x, int y)
@@ -34,7 +34,7 @@ GameLogo::GameLogo(int x, int y)
// Inicializa las variables
void GameLogo::init() {
const auto XP = x_ - coffee_texture_->getWidth() / 2;
const auto XP = x_ - (coffee_texture_->getWidth() / 2);
const auto DESP = getInitialVerticalDesp();
// Configura texturas
@@ -236,7 +236,7 @@ void GameLogo::finishArcadeEditionMoving() {
void GameLogo::playTitleEffects() {
Audio::get()->playSound("title.wav");
Screen::get()->flash(Color(0xFF, 0xFF, 0xFF), FLASH_LENGHT, FLASH_DELAY);
Screen::get()->flash(Color(0xFF, 0xFF, 0xFF), FLASH_LENGTH, FLASH_DELAY);
Screen::get()->shake();
}

View File

@@ -36,19 +36,19 @@ class GameLogo {
struct Shake {
int desp = 1; // Pixels de desplazamiento para agitar la pantalla en el eje x
int delay = 2; // Retraso entre cada desplazamiento de la pantalla al agitarse
int lenght = 8; // Cantidad de desplazamientos a realizar
int remaining = lenght; // Cantidad de desplazamientos pendientes a realizar
int length = 8; // Cantidad de desplazamientos a realizar
int remaining = length; // Cantidad de desplazamientos pendientes a realizar
int counter = delay; // Contador para el retraso
int origin = 0; // Valor inicial de la pantalla para dejarla igual tras el desplazamiento
Shake() = default;
Shake(int d, int de, int l, int o)
: desp(d), delay(de), lenght(l), remaining(l), counter(de), origin(o) {}
: desp(d), delay(de), length(l), remaining(l), counter(de), origin(o) {}
void init(int d, int de, int l, int o) {
desp = d;
delay = de;
lenght = l;
length = l;
remaining = l;
counter = de;
origin = o;
@@ -71,10 +71,10 @@ class GameLogo {
Shake shake_; // Efecto de agitación
Status coffee_crisis_status_ = Status::DISABLED; // Estado de "COFFEE CRISIS"
Status arcade_edition_status_ = Status::DISABLED; // Estado de "ARCADE EDITION"
float x_; // Posición X del logo
float y_; // Posición Y del logo
float zoom_ = 1.0F; // Zoom aplicado al texto "ARCADE EDITION"
int post_finished_counter_ = 1; // Contador final tras animaciones
float x_; // Posición X del logo
float y_; // Posición Y del logo
float zoom_ = 1.0F; // Zoom aplicado al texto "ARCADE EDITION"
int post_finished_counter_ = 1; // Contador final tras animaciones
// --- Inicialización ---
void init(); // Inicializa las variables

View File

@@ -4,6 +4,6 @@
// --- Namespace GlobalEvents: maneja eventos globales del juego ---
namespace GlobalEvents {
// --- Funciones ---
void handle(const SDL_Event &event); // Comprueba los eventos que se pueden producir en cualquier sección del juego
// --- Funciones ---
void handle(const SDL_Event &event); // Comprueba los eventos que se pueden producir en cualquier sección del juego
} // namespace GlobalEvents

View File

@@ -1,5 +1,6 @@
#include "global_inputs.h"
#include <algorithm> // Para std::ranges::any_of
#include <functional> // Para function
#include <memory> // Para allocator, shared_ptr
#include <string> // Para operator+, char_traits, string, to_string
@@ -145,11 +146,11 @@ auto checkServiceButton() -> bool {
}
// Mandos
for (const auto& gamepad : Input::get()->getGamepads()) {
if (Input::get()->checkAction(Input::Action::SERVICE, Input::DO_NOT_ALLOW_REPEAT, Input::DO_NOT_CHECK_KEYBOARD, gamepad)) {
toggleServiceMenu();
return true;
}
if (std::ranges::any_of(Input::get()->getGamepads(), [](const auto& gamepad) {
return Input::get()->checkAction(Input::Action::SERVICE, Input::DO_NOT_ALLOW_REPEAT, Input::DO_NOT_CHECK_KEYBOARD, gamepad);
})) {
toggleServiceMenu();
return true;
}
return false;
@@ -176,14 +177,13 @@ auto checkSystemInputs() -> bool {
#endif
};
for (const auto& [action, func] : ACTIONS) {
if (Input::get()->checkAction(action, Input::DO_NOT_ALLOW_REPEAT, Input::CHECK_KEYBOARD)) {
func();
return std::ranges::any_of(ACTIONS, [](const auto& pair) {
if (Input::get()->checkAction(pair.first, Input::DO_NOT_ALLOW_REPEAT, Input::CHECK_KEYBOARD)) {
pair.second();
return true;
}
}
return false;
return false;
});
}
// Comprueba el resto de entradas

View File

@@ -2,6 +2,6 @@
// --- Namespace GlobalInputs: gestiona inputs globales del juego ---
namespace GlobalInputs {
// --- Funciones ---
auto check() -> bool; // Comprueba los inputs que se pueden introducir en cualquier sección del juego
// --- Funciones ---
auto check() -> bool; // Comprueba los inputs que se pueden introducir en cualquier sección del juego
} // namespace GlobalInputs

View File

@@ -11,7 +11,7 @@
struct Hit {
public:
// --- Constructor ---
Hit() = delete; // Elimina el constructor por defecto para obligar a pasar una textura
Hit() = delete; // Elimina el constructor por defecto para obligar a pasar una textura
explicit Hit(const std::shared_ptr<Texture>& texture) // Constructor con textura obligatoria
: sprite_(std::make_unique<Sprite>(texture)) {}

View File

@@ -137,7 +137,8 @@ auto Input::gameControllerFound() const -> bool { return !gamepads_.empty(); }
// Obten el nombre de un mando de juego
auto Input::getControllerName(const std::shared_ptr<Gamepad> &gamepad) -> std::string {
return gamepad == nullptr ? std::string() : gamepad->name; }
return gamepad == nullptr ? std::string() : gamepad->name;
}
// Obtiene la lista de nombres de mandos
auto Input::getControllerNames() const -> std::vector<std::string> {
@@ -389,7 +390,7 @@ auto Input::addGamepad(int device_index) -> std::string {
}
auto Input::removeGamepad(SDL_JoystickID id) -> std::string {
auto it = std::find_if(gamepads_.begin(), gamepads_.end(), [id](const std::shared_ptr<Gamepad> &gamepad) {
auto it = std::ranges::find_if(gamepads_, [id](const std::shared_ptr<Gamepad> &gamepad) {
return gamepad->instance_id == id;
});
@@ -433,7 +434,7 @@ void Input::applyGamepadConfig(std::shared_ptr<Gamepad> gamepad) {
}
// --- Buscar configuración por RUTA (path) ---
auto config_it = std::find_if(gamepad_configs_.begin(), gamepad_configs_.end(), [&gamepad](const GamepadConfig &config) {
auto config_it = std::ranges::find_if(gamepad_configs_, [&gamepad](const GamepadConfig &config) {
return config.path == gamepad->path;
});
@@ -455,7 +456,7 @@ void Input::saveGamepadConfigFromGamepad(std::shared_ptr<Gamepad> gamepad) {
}
// --- CAMBIO CLAVE: Buscar si ya existe una configuración por RUTA (path) ---
auto config_it = std::find_if(gamepad_configs_.begin(), gamepad_configs_.end(), [&gamepad](const GamepadConfig &config) {
auto config_it = std::ranges::find_if(gamepad_configs_, [&gamepad](const GamepadConfig &config) {
return config.path == gamepad->path;
});
@@ -488,7 +489,7 @@ void Input::setGamepadConfigsFile(const std::string &filename) {
// Método para obtener configuración de un gamepad específico (opcional)
auto Input::getGamepadConfig(const std::string &gamepad_name) -> GamepadConfig * {
auto config_it = std::find_if(gamepad_configs_.begin(), gamepad_configs_.end(), [&gamepad_name](const GamepadConfig &config) {
auto config_it = std::ranges::find_if(gamepad_configs_, [&gamepad_name](const GamepadConfig &config) {
return config.name == gamepad_name;
});
@@ -497,7 +498,7 @@ auto Input::getGamepadConfig(const std::string &gamepad_name) -> GamepadConfig *
// Método para eliminar configuración de gamepad (opcional)
auto Input::removeGamepadConfig(const std::string &gamepad_name) -> bool {
auto config_it = std::find_if(gamepad_configs_.begin(), gamepad_configs_.end(), [&gamepad_name](const GamepadConfig &config) {
auto config_it = std::ranges::find_if(gamepad_configs_, [&gamepad_name](const GamepadConfig &config) {
return config.name == gamepad_name;
});

View File

@@ -15,12 +15,12 @@
class Input {
public:
// --- Constantes ---
static constexpr bool ALLOW_REPEAT = true; // Permite repetición
static constexpr bool DO_NOT_ALLOW_REPEAT = false; // No permite repetición
static constexpr bool CHECK_KEYBOARD = true; // Comprueba teclado
static constexpr bool DO_NOT_CHECK_KEYBOARD = false; // No comprueba teclado
static constexpr int TRIGGER_L2_AS_BUTTON = 100; // L2 como botón
static constexpr int TRIGGER_R2_AS_BUTTON = 101; // R2 como botón
static constexpr bool ALLOW_REPEAT = true; // Permite repetición
static constexpr bool DO_NOT_ALLOW_REPEAT = false; // No permite repetición
static constexpr bool CHECK_KEYBOARD = true; // Comprueba teclado
static constexpr bool DO_NOT_CHECK_KEYBOARD = false; // No comprueba teclado
static constexpr int TRIGGER_L2_AS_BUTTON = 100; // L2 como botón
static constexpr int TRIGGER_R2_AS_BUTTON = 101; // R2 como botón
// --- Tipos ---
using Action = InputAction; // Alias para mantener compatibilidad
@@ -36,14 +36,14 @@ class Input {
};
struct ButtonState {
int button; // GameControllerButton asociado
bool is_held; // Está pulsada ahora mismo
bool just_pressed; // Se acaba de pulsar en este fotograma
bool axis_active; // Estado del eje
bool trigger_active; // Estado del trigger como botón digital
int button; // GameControllerButton asociado
bool is_held; // Está pulsada ahora mismo
bool just_pressed; // Se acaba de pulsar en este fotograma
bool axis_active; // Estado del eje
bool trigger_active{false}; // Estado del trigger como botón digital
ButtonState(int btn = static_cast<int>(SDL_GAMEPAD_BUTTON_INVALID), bool is_held = false, bool just_pressed = false, bool axis_act = false)
: button(btn), is_held(is_held), just_pressed(just_pressed), axis_active(axis_act), trigger_active(false) {}
: button(btn), is_held(is_held), just_pressed(just_pressed), axis_active(axis_act) {}
};
struct Keyboard {

View File

@@ -181,17 +181,17 @@ auto Item::getCoffeeMachineSpawn(int player_x, int item_width, int area_width, i
// Ambos lados disponibles, elegir aleatoriamente
if (rand() % 2 == 0) {
// Lado izquierdo
return rand() % (exclude_left - LEFT_BOUND) + LEFT_BOUND;
return (rand() % (exclude_left - LEFT_BOUND)) + LEFT_BOUND;
} // Lado derecho
return rand() % (RIGHT_BOUND - exclude_right) + exclude_right;
return (rand() % (RIGHT_BOUND - exclude_right)) + exclude_right;
}
if (can_spawn_left) {
// Solo lado izquierdo disponible
return rand() % (exclude_left - LEFT_BOUND) + LEFT_BOUND;
return (rand() % (exclude_left - LEFT_BOUND)) + LEFT_BOUND;
}
if (can_spawn_right) {
// Solo lado derecho disponible
return rand() % (RIGHT_BOUND - exclude_right) + exclude_right;
return (rand() % (RIGHT_BOUND - exclude_right)) + exclude_right;
} // No hay espacio suficiente lejos del jugador
// Por ahora, intentar spawn en el extremo más lejano posible
int distance_to_left = abs(player_x - LEFT_BOUND);

View File

@@ -32,7 +32,7 @@ class Item {
// --- Constructor y destructor ---
Item(ItemType type, float x, float y, SDL_FRect &play_area, const std::shared_ptr<Texture> &texture, const std::vector<std::string> &animation); // Constructor principal
~Item() = default; // Destructor
~Item() = default; // Destructor
// --- Métodos principales ---
void alignTo(int x); // Centra el objeto en la posición X indicada
@@ -41,14 +41,14 @@ class Item {
void update(); // Actualiza la posición, animación y contadores
// --- Getters ---
[[nodiscard]] auto getPosX() const -> float { return pos_x_; } // Obtiene la posición X
[[nodiscard]] auto getPosY() const -> float { return pos_y_; } // Obtiene la posición Y
[[nodiscard]] auto getWidth() const -> int { return width_; } // Obtiene la anchura
[[nodiscard]] auto getHeight() const -> int { return height_; } // Obtiene la altura
[[nodiscard]] auto getType() const -> ItemType { return type_; } // Obtiene el tipo
[[nodiscard]] auto isEnabled() const -> bool { return enabled_; } // Verifica si está habilitado
[[nodiscard]] auto isOnFloor() const -> bool { return floor_collision_; } // Verifica si está en el suelo
auto getCollider() -> Circle & { return collider_; } // Obtiene el colisionador
[[nodiscard]] auto getPosX() const -> float { return pos_x_; } // Obtiene la posición X
[[nodiscard]] auto getPosY() const -> float { return pos_y_; } // Obtiene la posición Y
[[nodiscard]] auto getWidth() const -> int { return width_; } // Obtiene la anchura
[[nodiscard]] auto getHeight() const -> int { return height_; } // Obtiene la altura
[[nodiscard]] auto getType() const -> ItemType { return type_; } // Obtiene el tipo
[[nodiscard]] auto isEnabled() const -> bool { return enabled_; } // Verifica si está habilitado
[[nodiscard]] auto isOnFloor() const -> bool { return floor_collision_; } // Verifica si está en el suelo
auto getCollider() -> Circle & { return collider_; } // Obtiene el colisionador
private:
// --- Objetos y punteros ---
@@ -71,9 +71,9 @@ class Item {
bool enabled_ = true; // Indica si el objeto está habilitado
// --- Métodos internos ---
void shiftColliders(); // Alinea el círculo de colisión con la posición del objeto
void shiftSprite(); // Coloca el sprite en la posición del objeto
void move(); // Actualiza la posición y estados del objeto
void updateTimeToLive(); // Actualiza el contador de tiempo de vida
static auto getCoffeeMachineSpawn(int player_x, int item_width, int area_width, int margin = 2) -> int; // Calcula la zona de aparición de la máquina de café
void shiftColliders(); // Alinea el círculo de colisión con la posición del objeto
void shiftSprite(); // Coloca el sprite en la posición del objeto
void move(); // Actualiza la posición y estados del objeto
void updateTimeToLive(); // Actualiza el contador de tiempo de vida
static auto getCoffeeMachineSpawn(int player_x, int item_width, int area_width, int margin = 2) -> int; // Calcula la zona de aparición de la máquina de café
};

View File

@@ -1,7 +1,7 @@
#pragma once
#include <string> // Para string, basic_string
#include <utility> // Para move
#include <string> // Para string, basic_string
#include <utility> // Para move
// --- Namespace Lang: gestión de idiomas y textos ---
namespace Lang {

View File

@@ -17,5 +17,5 @@ auto main(int argc, char* argv[]) -> int {
auto director = std::make_unique<Director>(argc, std::span<char*>(argv, argc));
// Bucle principal
return director->run();
return Director::run();
}

View File

@@ -36,9 +36,9 @@ auto ManageHiScoreTable::add(const HiScoreEntry &entry) -> int {
sort();
// Encontrar la posición del nuevo elemento
auto it = std::find_if(table_.begin(), table_.end(), [&](const HiScoreEntry &e) { return e.name == entry.name &&
e.score == entry.score &&
e.one_credit_complete == entry.one_credit_complete; });
auto it = std::ranges::find_if(table_, [&](const HiScoreEntry &e) {
return e.name == entry.name && e.score == entry.score && e.one_credit_complete == entry.one_credit_complete;
});
int position = -1;
if (it != table_.end()) {
@@ -66,7 +66,7 @@ void ManageHiScoreTable::sort() {
auto operator()(const HiScoreEntry &a, const HiScoreEntry &b) const -> bool { return a.score > b.score; }
} score_descending_comparator;
std::sort(table_.begin(), table_.end(), score_descending_comparator);
std::ranges::sort(table_, score_descending_comparator);
}
// Carga la tabla desde un fichero

View File

@@ -26,7 +26,7 @@ class ManageHiScoreTable {
// --- Constructor y destructor ---
explicit ManageHiScoreTable(Table &table) // Constructor con referencia a tabla
: table_(table) {}
~ManageHiScoreTable() = default; // Destructor
~ManageHiScoreTable() = default; // Destructor
// --- Métodos públicos ---
void clear(); // Resetea la tabla a los valores por defecto

View File

@@ -14,14 +14,12 @@ class MovingSprite : public Sprite {
public:
// --- Estructuras ---
struct Rotate {
bool enabled{false}; // Indica si ha de rotar
int counter{0}; // Contador
int speed{1}; // Velocidad de giro
double angle{0.0}; // Ángulo para dibujarlo
float amount{0.0F}; // Cantidad de grados a girar en cada iteración
SDL_FPoint center; // Centro de rotación
Rotate() : center({0.0F, 0.0F}) {}
bool enabled{false}; // Indica si ha de rotar
int counter{0}; // Contador
int speed{1}; // Velocidad de giro
double angle{0.0}; // Ángulo para dibujarlo
float amount{0.0F}; // Cantidad de grados a girar en cada iteración
SDL_FPoint center{.x = 0.0F, .y = 0.0F}; // Centro de rotación
};
// --- Constructores y destructor ---
@@ -37,34 +35,34 @@ class MovingSprite : public Sprite {
void render() override; // Muestra el sprite por pantalla
// --- Configuración ---
void setPos(SDL_FRect rect); // Establece la posición y el tamaño del objeto
void setPos(float pos_x, float pos_y); // Establece la posición del objeto
void setPosX(float pos_x); // Establece la posición X
void setPosY(float pos_y); // Establece la posición Y
void setVelX(float value) { vx_ = value; } // Establece la velocidad X
void setVelY(float value) { vy_ = value; } // Establece la velocidad Y
void setAccelX(float value) { ax_ = value; } // Establece la aceleración X
void setAccelY(float value) { ay_ = value; } // Establece la aceleración Y
void setHorizontalZoom(float value) { horizontal_zoom_ = value; } // Establece el zoom horizontal
void setVerticalZoom(float value) { vertical_zoom_ = value; } // Establece el zoom vertical
void setAngle(double value) { rotate_.angle = value; } // Establece el ángulo
void setRotatingCenter(SDL_FPoint point) { rotate_.center = point; } // Establece el centro de rotación
void setRotate(bool enable); // Activa o desactiva el efecto de rotación
void setRotateSpeed(int value) { rotate_.speed = std::max(1, value); } // Establece la velocidad de rotación
void setRotateAmount(double value) { rotate_.amount = value; } // Establece la cantidad de rotación
void switchRotate() { rotate_.amount *= -1; } // Cambia el sentido de la rotación
void setFlip(SDL_FlipMode flip) { flip_ = flip; } // Establece el flip
void setPos(SDL_FRect rect); // Establece la posición y el tamaño del objeto
void setPos(float pos_x, float pos_y); // Establece la posición del objeto
void setPosX(float pos_x); // Establece la posición X
void setPosY(float pos_y); // Establece la posición Y
void setVelX(float value) { vx_ = value; } // Establece la velocidad X
void setVelY(float value) { vy_ = value; } // Establece la velocidad Y
void setAccelX(float value) { ax_ = value; } // Establece la aceleración X
void setAccelY(float value) { ay_ = value; } // Establece la aceleración Y
void setHorizontalZoom(float value) { horizontal_zoom_ = value; } // Establece el zoom horizontal
void setVerticalZoom(float value) { vertical_zoom_ = value; } // Establece el zoom vertical
void setAngle(double value) { rotate_.angle = value; } // Establece el ángulo
void setRotatingCenter(SDL_FPoint point) { rotate_.center = point; } // Establece el centro de rotación
void setRotate(bool enable); // Activa o desactiva el efecto de rotación
void setRotateSpeed(int value) { rotate_.speed = std::max(1, value); } // Establece la velocidad de rotación
void setRotateAmount(double value) { rotate_.amount = value; } // Establece la cantidad de rotación
void switchRotate() { rotate_.amount *= -1; } // Cambia el sentido de la rotación
void setFlip(SDL_FlipMode flip) { flip_ = flip; } // Establece el flip
void flip() { flip_ = (flip_ == SDL_FLIP_HORIZONTAL) ? SDL_FLIP_NONE : SDL_FLIP_HORIZONTAL; } // Cambia el flip
// --- Getters ---
[[nodiscard]] auto getPosX() const -> float { return x_; } // Obtiene la posición X
[[nodiscard]] auto getPosY() const -> float { return y_; } // Obtiene la posición Y
[[nodiscard]] auto getVelX() const -> float { return vx_; } // Obtiene la velocidad X
[[nodiscard]] auto getVelY() const -> float { return vy_; } // Obtiene la velocidad Y
[[nodiscard]] auto getAccelX() const -> float { return ax_; } // Obtiene la aceleración X
[[nodiscard]] auto getAccelY() const -> float { return ay_; } // Obtiene la aceleración Y
[[nodiscard]] auto getPosX() const -> float { return x_; } // Obtiene la posición X
[[nodiscard]] auto getPosY() const -> float { return y_; } // Obtiene la posición Y
[[nodiscard]] auto getVelX() const -> float { return vx_; } // Obtiene la velocidad X
[[nodiscard]] auto getVelY() const -> float { return vy_; } // Obtiene la velocidad Y
[[nodiscard]] auto getAccelX() const -> float { return ax_; } // Obtiene la aceleración X
[[nodiscard]] auto getAccelY() const -> float { return ay_; } // Obtiene la aceleración Y
[[nodiscard]] auto isRotating() const -> bool { return rotate_.enabled; } // Verifica si está rotando
auto getFlip() -> SDL_FlipMode { return flip_; } // Obtiene el flip
auto getFlip() -> SDL_FlipMode { return flip_; } // Obtiene el flip
protected:
// --- Variables de estado ---

View File

@@ -7,6 +7,7 @@
#include <fstream> // Para basic_ostream, operator<<, basic_ostream::operator<<, basic_ofstream, basic_istream, basic_ifstream, ifstream, ofstream
#include <functional> // Para function
#include <map> // Para map, operator==, _Rb_tree_const_iterator
#include <ranges> // Para std::ranges::any_of
#include <stdexcept> // Para invalid_argument, out_of_range
#include <string> // Para char_traits, stoi, operator==, operator<<, allocator, string, basic_string, operator<=>, getline
#include <utility> // Para swap, pair
@@ -392,12 +393,10 @@ void GamepadManager::clearUnassignedGamepadSlots() {
auto GamepadManager::isGamepadAssigned(
const std::shared_ptr<Input::Gamepad>& physical_gamepad,
const std::vector<std::shared_ptr<Input::Gamepad>>& assigned_instances) -> bool {
for (const auto& assigned : assigned_instances) {
if (assigned == physical_gamepad) {
return true; // Encontrado, por lo tanto, ya está asignado.
}
}
return false; // No se encontró en la lista.
return std::ranges::any_of(assigned_instances,
[&physical_gamepad](const auto& assigned) {
return assigned == physical_gamepad;
});
}
// Convierte un player id a texto segun Lang

View File

@@ -223,7 +223,7 @@ class GamepadManager {
}
void addPlayer(const std::shared_ptr<Player>& player) { players_.push_back(player); } // Añade un jugador a la lista
void clearPlayers() { players_.clear(); } // Limpia la lista de jugadores
void clearPlayers() { players_.clear(); } // Limpia la lista de jugadores
// Asigna el mando a un jugador
void assignTo(const Input::Gamepad& gamepad, Player::Id player_id) {
@@ -276,7 +276,7 @@ struct Keyboard {
std::vector<std::shared_ptr<Player>> players; // Punteros a los jugadores
void addPlayer(const std::shared_ptr<Player>& player) { players.push_back(player); } // Añade un jugador a la lista
void clearPlayers() { players.clear(); } // Limpia la lista de jugadores
void clearPlayers() { players.clear(); } // Limpia la lista de jugadores
// Asigna el teclado a un jugador
void assignTo(Player::Id player_id) {

View File

@@ -2,23 +2,23 @@
#include <SDL3/SDL.h> // Para SDL_LogCategory, SDL_LogError, SDL_LogInfo
#include <fstream> // Para basic_istream, basic_ifstream, ifstream
#include <fstream> // Para basic_istream, basic_ifstream, ifstream
#include <functional>
#include <sstream> // Para basic_istringstream
#include <stdexcept> // Para runtime_error
#include <string> // Para operator==, stoi, char_traits, string, ope...
#include <sstream> // Para basic_istringstream
#include <stdexcept> // Para runtime_error
#include <string> // Para operator==, stoi, char_traits, string, ope...
#include <unordered_map>
#include "color.h"
#include "utils.h"
#include "ui/notifier.h" // Para Notifier::Position
#include "utils.h"
// Variable global - ahora se inicializa automáticamente con valores por defecto
Param param;
// Declaraciones de funciones privadas
namespace {
auto setParams(const std::string& var, const std::string& value) -> bool;
auto setParams(const std::string& var, const std::string& value) -> bool;
}
// Implementación del método privado de Param
@@ -32,7 +32,7 @@ void Param::precalculateZones() {
game.play_area.third_quarter_y = game.play_area.rect.h / 4 * 3;
// gameArea - cálculos basados en width y height actuales
game.game_area.rect = {0, 0, game.width, game.height};
game.game_area.rect = {.x = 0, .y = 0, .w = game.width, .h = game.height};
game.game_area.center_x = game.game_area.rect.w / 2;
game.game_area.first_quarter_x = game.game_area.rect.w / 4;
game.game_area.third_quarter_x = game.game_area.rect.w / 4 * 3;
@@ -82,153 +82,147 @@ void loadParamsFromFile(const std::string& file_path) {
// Implementación local de setParams
namespace {
auto setParams(const std::string& var, const std::string& value) -> bool {
// Mapas estáticos para diferentes tipos de parámetros
static const std::unordered_map<std::string, std::function<void(const std::string&)>> INT_PARAMS = {
{"game.width", [](const std::string& v) { param.game.width = std::stoi(v); }},
{"game.height", [](const std::string& v) { param.game.height = std::stoi(v); }},
{"game.item_size", [](const std::string& v) { param.game.item_size = std::stoi(v); }},
{"game.play_area.rect.x", [](const std::string& v) { param.game.play_area.rect.x = std::stoi(v); }},
{"game.play_area.rect.y", [](const std::string& v) { param.game.play_area.rect.y = std::stoi(v); }},
{"game.play_area.rect.w", [](const std::string& v) { param.game.play_area.rect.w = std::stoi(v); }},
{"game.play_area.rect.h", [](const std::string& v) { param.game.play_area.rect.h = std::stoi(v); }},
{"game.name_entry_idle_time", [](const std::string& v) { param.game.name_entry_idle_time = std::stoi(v); }},
{"game.name_entry_total_time", [](const std::string& v) { param.game.name_entry_total_time = std::stoi(v); }},
{"game.hit_stop_ms", [](const std::string& v) { param.game.hit_stop_ms = std::stoi(v); }},
{"fade.num_squares_width", [](const std::string& v) { param.fade.num_squares_width = std::stoi(v); }},
{"fade.num_squares_height", [](const std::string& v) { param.fade.num_squares_height = std::stoi(v); }},
{"fade.random_squares_delay", [](const std::string& v) { param.fade.random_squares_delay = std::stoi(v); }},
{"fade.random_squares_mult", [](const std::string& v) { param.fade.random_squares_mult = std::stoi(v); }},
{"fade.post_duration", [](const std::string& v) { param.fade.post_duration = std::stoi(v); }},
{"fade.venetian_size", [](const std::string& v) { param.fade.venetian_size = std::stoi(v); }},
{"scoreboard.rect.x", [](const std::string& v) { param.scoreboard.rect.x = std::stoi(v); }},
{"scoreboard.rect.y", [](const std::string& v) { param.scoreboard.rect.y = std::stoi(v); }},
{"scoreboard.rect.w", [](const std::string& v) { param.scoreboard.rect.w = std::stoi(v); }},
{"scoreboard.rect.h", [](const std::string& v) { param.scoreboard.rect.h = std::stoi(v); }},
{"scoreboard.skip_countdown_value", [](const std::string& v) { param.scoreboard.skip_countdown_value = std::stoi(v); }},
{"title.press_start_position", [](const std::string& v) { param.title.press_start_position = std::stoi(v); }},
{"title.title_duration", [](const std::string& v) { param.title.title_duration = std::stoi(v); }},
{"title.arcade_edition_position", [](const std::string& v) { param.title.arcade_edition_position = std::stoi(v); }},
{"title.title_c_c_position", [](const std::string& v) { param.title.title_c_c_position = std::stoi(v); }},
{"intro.text_distance_from_bottom", [](const std::string& v) { param.intro.text_distance_from_bottom = std::stoi(v); }}
};
auto setParams(const std::string& var, const std::string& value) -> bool {
// Mapas estáticos para diferentes tipos de parámetros
static const std::unordered_map<std::string, std::function<void(const std::string&)>> INT_PARAMS = {
{"game.width", [](const std::string& v) { param.game.width = std::stoi(v); }},
{"game.height", [](const std::string& v) { param.game.height = std::stoi(v); }},
{"game.item_size", [](const std::string& v) { param.game.item_size = std::stoi(v); }},
{"game.play_area.rect.x", [](const std::string& v) { param.game.play_area.rect.x = std::stoi(v); }},
{"game.play_area.rect.y", [](const std::string& v) { param.game.play_area.rect.y = std::stoi(v); }},
{"game.play_area.rect.w", [](const std::string& v) { param.game.play_area.rect.w = std::stoi(v); }},
{"game.play_area.rect.h", [](const std::string& v) { param.game.play_area.rect.h = std::stoi(v); }},
{"game.name_entry_idle_time", [](const std::string& v) { param.game.name_entry_idle_time = std::stoi(v); }},
{"game.name_entry_total_time", [](const std::string& v) { param.game.name_entry_total_time = std::stoi(v); }},
{"game.hit_stop_ms", [](const std::string& v) { param.game.hit_stop_ms = std::stoi(v); }},
{"fade.num_squares_width", [](const std::string& v) { param.fade.num_squares_width = std::stoi(v); }},
{"fade.num_squares_height", [](const std::string& v) { param.fade.num_squares_height = std::stoi(v); }},
{"fade.random_squares_delay", [](const std::string& v) { param.fade.random_squares_delay = std::stoi(v); }},
{"fade.random_squares_mult", [](const std::string& v) { param.fade.random_squares_mult = std::stoi(v); }},
{"fade.post_duration", [](const std::string& v) { param.fade.post_duration = std::stoi(v); }},
{"fade.venetian_size", [](const std::string& v) { param.fade.venetian_size = std::stoi(v); }},
{"scoreboard.rect.x", [](const std::string& v) { param.scoreboard.rect.x = std::stoi(v); }},
{"scoreboard.rect.y", [](const std::string& v) { param.scoreboard.rect.y = std::stoi(v); }},
{"scoreboard.rect.w", [](const std::string& v) { param.scoreboard.rect.w = std::stoi(v); }},
{"scoreboard.rect.h", [](const std::string& v) { param.scoreboard.rect.h = std::stoi(v); }},
{"scoreboard.skip_countdown_value", [](const std::string& v) { param.scoreboard.skip_countdown_value = std::stoi(v); }},
{"title.press_start_position", [](const std::string& v) { param.title.press_start_position = std::stoi(v); }},
{"title.title_duration", [](const std::string& v) { param.title.title_duration = std::stoi(v); }},
{"title.arcade_edition_position", [](const std::string& v) { param.title.arcade_edition_position = std::stoi(v); }},
{"title.title_c_c_position", [](const std::string& v) { param.title.title_c_c_position = std::stoi(v); }},
{"intro.text_distance_from_bottom", [](const std::string& v) { param.intro.text_distance_from_bottom = std::stoi(v); }}};
static const std::unordered_map<std::string, std::function<void(const std::string&)>> COLOR_PARAMS = {
{"fade.color", [](const std::string& v) { param.fade.color = Color::fromHex(v); }},
{"scoreboard.separator_color", [](const std::string& v) { param.scoreboard.separator_color = Color::fromHex(v); }},
{"scoreboard.easy_color", [](const std::string& v) { param.scoreboard.easy_color = Color::fromHex(v); }},
{"scoreboard.normal_color", [](const std::string& v) { param.scoreboard.normal_color = Color::fromHex(v); }},
{"scoreboard.hard_color", [](const std::string& v) { param.scoreboard.hard_color = Color::fromHex(v); }},
{"scoreboard.text_color1", [](const std::string& v) { param.scoreboard.text_color1 = Color::fromHex(v); }},
{"scoreboard.text_color2", [](const std::string& v) { param.scoreboard.text_color2 = Color::fromHex(v); }},
{"title.bg_color", [](const std::string& v) { param.title.bg_color = Color::fromHex(v); }},
{"background.attenuate_color", [](const std::string& v) { param.background.attenuate_color = Color::fromHex(v); }},
{"notification.color", [](const std::string& v) { param.notification.color = Color::fromHex(v); }},
{"service_menu.title_color", [](const std::string& v) { param.service_menu.title_color = Color::fromHex(v); }},
{"service_menu.text_color", [](const std::string& v) { param.service_menu.text_color = Color::fromHex(v); }},
{"service_menu.selected_color", [](const std::string& v) { param.service_menu.selected_color = Color::fromHex(v); }},
{"service_menu.bg_color", [](const std::string& v) { param.service_menu.bg_color = Color::fromHex(v); }},
{"service_menu.window_message.bg_color", [](const std::string& v) { param.service_menu.window_message.bg_color = Color::fromHex(v); }},
{"service_menu.window_message.border_color", [](const std::string& v) { param.service_menu.window_message.border_color = Color::fromHex(v); }},
{"service_menu.window_message.title_color", [](const std::string& v) { param.service_menu.window_message.title_color = Color::fromHex(v); }},
{"service_menu.window_message.text_color", [](const std::string& v) { param.service_menu.window_message.text_color = Color::fromHex(v); }},
{"intro.bg_color", [](const std::string& v) { param.intro.bg_color = Color::fromHex(v); }},
{"intro.card_color", [](const std::string& v) { param.intro.card_color = Color::fromHex(v); }},
{"intro.shadow_color", [](const std::string& v) { param.intro.shadow_color = Color::fromHex(v); }},
{"debug.color", [](const std::string& v) { param.debug.color = Color::fromHex(v); }},
{"resource.color", [](const std::string& v) { param.resource.color = Color::fromHex(v); }},
{"player.one_coffee_shirt[0].darkest", [](const std::string& v) { param.player.one_coffee_shirt[0].darkest = Color::fromHex(v); }},
{"player.one_coffee_shirt[0].dark", [](const std::string& v) { param.player.one_coffee_shirt[0].dark = Color::fromHex(v); }},
{"player.one_coffee_shirt[0].base", [](const std::string& v) { param.player.one_coffee_shirt[0].base = Color::fromHex(v); }},
{"player.one_coffee_shirt[0].light", [](const std::string& v) { param.player.one_coffee_shirt[0].light = Color::fromHex(v); }},
{"player.one_coffee_shirt[1].darkest", [](const std::string& v) { param.player.one_coffee_shirt[1].darkest = Color::fromHex(v); }},
{"player.one_coffee_shirt[1].dark", [](const std::string& v) { param.player.one_coffee_shirt[1].dark = Color::fromHex(v); }},
{"player.one_coffee_shirt[1].base", [](const std::string& v) { param.player.one_coffee_shirt[1].base = Color::fromHex(v); }},
{"player.one_coffee_shirt[1].light", [](const std::string& v) { param.player.one_coffee_shirt[1].light = Color::fromHex(v); }},
{"player.two_coffee_shirt[0].darkest", [](const std::string& v) { param.player.two_coffee_shirt[0].darkest = Color::fromHex(v); }},
{"player.two_coffee_shirt[0].dark", [](const std::string& v) { param.player.two_coffee_shirt[0].dark = Color::fromHex(v); }},
{"player.two_coffee_shirt[0].base", [](const std::string& v) { param.player.two_coffee_shirt[0].base = Color::fromHex(v); }},
{"player.two_coffee_shirt[0].light", [](const std::string& v) { param.player.two_coffee_shirt[0].light = Color::fromHex(v); }},
{"player.two_coffee_shirt[1].darkest", [](const std::string& v) { param.player.two_coffee_shirt[1].darkest = Color::fromHex(v); }},
{"player.two_coffee_shirt[1].dark", [](const std::string& v) { param.player.two_coffee_shirt[1].dark = Color::fromHex(v); }},
{"player.two_coffee_shirt[1].base", [](const std::string& v) { param.player.two_coffee_shirt[1].base = Color::fromHex(v); }},
{"player.two_coffee_shirt[1].light", [](const std::string& v) { param.player.two_coffee_shirt[1].light = Color::fromHex(v); }}
};
static const std::unordered_map<std::string, std::function<void(const std::string&)>> COLOR_PARAMS = {
{"fade.color", [](const std::string& v) { param.fade.color = Color::fromHex(v); }},
{"scoreboard.separator_color", [](const std::string& v) { param.scoreboard.separator_color = Color::fromHex(v); }},
{"scoreboard.easy_color", [](const std::string& v) { param.scoreboard.easy_color = Color::fromHex(v); }},
{"scoreboard.normal_color", [](const std::string& v) { param.scoreboard.normal_color = Color::fromHex(v); }},
{"scoreboard.hard_color", [](const std::string& v) { param.scoreboard.hard_color = Color::fromHex(v); }},
{"scoreboard.text_color1", [](const std::string& v) { param.scoreboard.text_color1 = Color::fromHex(v); }},
{"scoreboard.text_color2", [](const std::string& v) { param.scoreboard.text_color2 = Color::fromHex(v); }},
{"title.bg_color", [](const std::string& v) { param.title.bg_color = Color::fromHex(v); }},
{"background.attenuate_color", [](const std::string& v) { param.background.attenuate_color = Color::fromHex(v); }},
{"notification.color", [](const std::string& v) { param.notification.color = Color::fromHex(v); }},
{"service_menu.title_color", [](const std::string& v) { param.service_menu.title_color = Color::fromHex(v); }},
{"service_menu.text_color", [](const std::string& v) { param.service_menu.text_color = Color::fromHex(v); }},
{"service_menu.selected_color", [](const std::string& v) { param.service_menu.selected_color = Color::fromHex(v); }},
{"service_menu.bg_color", [](const std::string& v) { param.service_menu.bg_color = Color::fromHex(v); }},
{"service_menu.window_message.bg_color", [](const std::string& v) { param.service_menu.window_message.bg_color = Color::fromHex(v); }},
{"service_menu.window_message.border_color", [](const std::string& v) { param.service_menu.window_message.border_color = Color::fromHex(v); }},
{"service_menu.window_message.title_color", [](const std::string& v) { param.service_menu.window_message.title_color = Color::fromHex(v); }},
{"service_menu.window_message.text_color", [](const std::string& v) { param.service_menu.window_message.text_color = Color::fromHex(v); }},
{"intro.bg_color", [](const std::string& v) { param.intro.bg_color = Color::fromHex(v); }},
{"intro.card_color", [](const std::string& v) { param.intro.card_color = Color::fromHex(v); }},
{"intro.shadow_color", [](const std::string& v) { param.intro.shadow_color = Color::fromHex(v); }},
{"debug.color", [](const std::string& v) { param.debug.color = Color::fromHex(v); }},
{"resource.color", [](const std::string& v) { param.resource.color = Color::fromHex(v); }},
{"player.one_coffee_shirt[0].darkest", [](const std::string& v) { param.player.one_coffee_shirt[0].darkest = Color::fromHex(v); }},
{"player.one_coffee_shirt[0].dark", [](const std::string& v) { param.player.one_coffee_shirt[0].dark = Color::fromHex(v); }},
{"player.one_coffee_shirt[0].base", [](const std::string& v) { param.player.one_coffee_shirt[0].base = Color::fromHex(v); }},
{"player.one_coffee_shirt[0].light", [](const std::string& v) { param.player.one_coffee_shirt[0].light = Color::fromHex(v); }},
{"player.one_coffee_shirt[1].darkest", [](const std::string& v) { param.player.one_coffee_shirt[1].darkest = Color::fromHex(v); }},
{"player.one_coffee_shirt[1].dark", [](const std::string& v) { param.player.one_coffee_shirt[1].dark = Color::fromHex(v); }},
{"player.one_coffee_shirt[1].base", [](const std::string& v) { param.player.one_coffee_shirt[1].base = Color::fromHex(v); }},
{"player.one_coffee_shirt[1].light", [](const std::string& v) { param.player.one_coffee_shirt[1].light = Color::fromHex(v); }},
{"player.two_coffee_shirt[0].darkest", [](const std::string& v) { param.player.two_coffee_shirt[0].darkest = Color::fromHex(v); }},
{"player.two_coffee_shirt[0].dark", [](const std::string& v) { param.player.two_coffee_shirt[0].dark = Color::fromHex(v); }},
{"player.two_coffee_shirt[0].base", [](const std::string& v) { param.player.two_coffee_shirt[0].base = Color::fromHex(v); }},
{"player.two_coffee_shirt[0].light", [](const std::string& v) { param.player.two_coffee_shirt[0].light = Color::fromHex(v); }},
{"player.two_coffee_shirt[1].darkest", [](const std::string& v) { param.player.two_coffee_shirt[1].darkest = Color::fromHex(v); }},
{"player.two_coffee_shirt[1].dark", [](const std::string& v) { param.player.two_coffee_shirt[1].dark = Color::fromHex(v); }},
{"player.two_coffee_shirt[1].base", [](const std::string& v) { param.player.two_coffee_shirt[1].base = Color::fromHex(v); }},
{"player.two_coffee_shirt[1].light", [](const std::string& v) { param.player.two_coffee_shirt[1].light = Color::fromHex(v); }}};
static const std::unordered_map<std::string, std::function<void(const std::string&)>> BOOL_PARAMS = {
{"game.hit_stop", [](const std::string& v) { param.game.hit_stop = stringToBool(v); }},
{"scoreboard.separator_autocolor", [](const std::string& v) { param.scoreboard.separator_autocolor = stringToBool(v); }},
{"scoreboard.text_autocolor", [](const std::string& v) { param.scoreboard.text_autocolor = stringToBool(v); }},
{"balloon.bouncing_sound", [](const std::string& v) { param.balloon.bouncing_sound = stringToBool(v); }},
{"notification.sound", [](const std::string& v) { param.notification.sound = stringToBool(v); }},
{"service_menu.drop_shadow", [](const std::string& v) { param.service_menu.drop_shadow = stringToBool(v); }}
};
static const std::unordered_map<std::string, std::function<void(const std::string&)>> BOOL_PARAMS = {
{"game.hit_stop", [](const std::string& v) { param.game.hit_stop = stringToBool(v); }},
{"scoreboard.separator_autocolor", [](const std::string& v) { param.scoreboard.separator_autocolor = stringToBool(v); }},
{"scoreboard.text_autocolor", [](const std::string& v) { param.scoreboard.text_autocolor = stringToBool(v); }},
{"balloon.bouncing_sound", [](const std::string& v) { param.balloon.bouncing_sound = stringToBool(v); }},
{"notification.sound", [](const std::string& v) { param.notification.sound = stringToBool(v); }},
{"service_menu.drop_shadow", [](const std::string& v) { param.service_menu.drop_shadow = stringToBool(v); }}};
static const std::unordered_map<std::string, std::function<void(const std::string&)>> FLOAT_PARAMS = {
{"balloon.settings[0].vel", [](const std::string& v) { param.balloon.settings.at(0).vel = std::stof(v); }},
{"balloon.settings[0].grav", [](const std::string& v) { param.balloon.settings.at(0).grav = std::stof(v); }},
{"balloon.settings[1].vel", [](const std::string& v) { param.balloon.settings.at(1).vel = std::stof(v); }},
{"balloon.settings[1].grav", [](const std::string& v) { param.balloon.settings.at(1).grav = std::stof(v); }},
{"balloon.settings[2].vel", [](const std::string& v) { param.balloon.settings.at(2).vel = std::stof(v); }},
{"balloon.settings[2].grav", [](const std::string& v) { param.balloon.settings.at(2).grav = std::stof(v); }},
{"balloon.settings[3].vel", [](const std::string& v) { param.balloon.settings.at(3).vel = std::stof(v); }},
{"balloon.settings[3].grav", [](const std::string& v) { param.balloon.settings.at(3).grav = std::stof(v); }},
{"tabe.min_spawn_time", [](const std::string& v) { param.tabe.min_spawn_time = std::stof(v); }},
{"tabe.max_spawn_time", [](const std::string& v) { param.tabe.max_spawn_time = std::stof(v); }},
{"service_menu.window_message.padding", [](const std::string& v) { param.service_menu.window_message.padding = std::stof(v); }},
{"service_menu.window_message.line_spacing", [](const std::string& v) { param.service_menu.window_message.line_spacing = std::stof(v); }},
{"service_menu.window_message.title_separator_spacing", [](const std::string& v) { param.service_menu.window_message.title_separator_spacing = std::stof(v); }},
{"service_menu.window_message.min_width", [](const std::string& v) { param.service_menu.window_message.min_width = std::stof(v); }},
{"service_menu.window_message.min_height", [](const std::string& v) { param.service_menu.window_message.min_height = std::stof(v); }},
{"service_menu.window_message.max_width_ratio", [](const std::string& v) { param.service_menu.window_message.max_width_ratio = std::stof(v); }},
{"service_menu.window_message.max_height_ratio", [](const std::string& v) { param.service_menu.window_message.max_height_ratio = std::stof(v); }},
{"service_menu.window_message.text_safety_margin", [](const std::string& v) { param.service_menu.window_message.text_safety_margin = std::stof(v); }},
{"service_menu.window_message.animation_duration", [](const std::string& v) { param.service_menu.window_message.animation_duration = std::stof(v); }}
};
static const std::unordered_map<std::string, std::function<void(const std::string&)>> FLOAT_PARAMS = {
{"balloon.settings[0].vel", [](const std::string& v) { param.balloon.settings.at(0).vel = std::stof(v); }},
{"balloon.settings[0].grav", [](const std::string& v) { param.balloon.settings.at(0).grav = std::stof(v); }},
{"balloon.settings[1].vel", [](const std::string& v) { param.balloon.settings.at(1).vel = std::stof(v); }},
{"balloon.settings[1].grav", [](const std::string& v) { param.balloon.settings.at(1).grav = std::stof(v); }},
{"balloon.settings[2].vel", [](const std::string& v) { param.balloon.settings.at(2).vel = std::stof(v); }},
{"balloon.settings[2].grav", [](const std::string& v) { param.balloon.settings.at(2).grav = std::stof(v); }},
{"balloon.settings[3].vel", [](const std::string& v) { param.balloon.settings.at(3).vel = std::stof(v); }},
{"balloon.settings[3].grav", [](const std::string& v) { param.balloon.settings.at(3).grav = std::stof(v); }},
{"tabe.min_spawn_time", [](const std::string& v) { param.tabe.min_spawn_time = std::stof(v); }},
{"tabe.max_spawn_time", [](const std::string& v) { param.tabe.max_spawn_time = std::stof(v); }},
{"service_menu.window_message.padding", [](const std::string& v) { param.service_menu.window_message.padding = std::stof(v); }},
{"service_menu.window_message.line_spacing", [](const std::string& v) { param.service_menu.window_message.line_spacing = std::stof(v); }},
{"service_menu.window_message.title_separator_spacing", [](const std::string& v) { param.service_menu.window_message.title_separator_spacing = std::stof(v); }},
{"service_menu.window_message.min_width", [](const std::string& v) { param.service_menu.window_message.min_width = std::stof(v); }},
{"service_menu.window_message.min_height", [](const std::string& v) { param.service_menu.window_message.min_height = std::stof(v); }},
{"service_menu.window_message.max_width_ratio", [](const std::string& v) { param.service_menu.window_message.max_width_ratio = std::stof(v); }},
{"service_menu.window_message.max_height_ratio", [](const std::string& v) { param.service_menu.window_message.max_height_ratio = std::stof(v); }},
{"service_menu.window_message.text_safety_margin", [](const std::string& v) { param.service_menu.window_message.text_safety_margin = std::stof(v); }},
{"service_menu.window_message.animation_duration", [](const std::string& v) { param.service_menu.window_message.animation_duration = std::stof(v); }}};
static const std::unordered_map<std::string, std::function<void(const std::string&)>> INT_PARAMS_EXTRA = {
};
static const std::unordered_map<std::string, std::function<void(const std::string&)>> INT_PARAMS_EXTRA = {};
static const std::unordered_map<std::string, std::function<void(const std::string&)>> STRING_PARAMS = {
{"balloon.color[0]", [](const std::string& v) { param.balloon.color.at(0) = v; }},
{"balloon.color[1]", [](const std::string& v) { param.balloon.color.at(1) = v; }},
{"balloon.color[2]", [](const std::string& v) { param.balloon.color.at(2) = v; }},
{"balloon.color[3]", [](const std::string& v) { param.balloon.color.at(3) = v; }}
};
static const std::unordered_map<std::string, std::function<void(const std::string&)>> STRING_PARAMS = {
{"balloon.color[0]", [](const std::string& v) { param.balloon.color.at(0) = v; }},
{"balloon.color[1]", [](const std::string& v) { param.balloon.color.at(1) = v; }},
{"balloon.color[2]", [](const std::string& v) { param.balloon.color.at(2) = v; }},
{"balloon.color[3]", [](const std::string& v) { param.balloon.color.at(3) = v; }}};
// Lambda para intentar cada mapa de parámetros
auto try_map = [&](const auto& param_map) -> bool {
auto it = param_map.find(var);
if (it != param_map.end()) {
it->second(value);
return true;
}
return false;
};
// Intentar con todos los mapas
if (try_map(INT_PARAMS) || try_map(COLOR_PARAMS) || try_map(BOOL_PARAMS) ||
try_map(FLOAT_PARAMS) || try_map(STRING_PARAMS)) {
// Lambda para intentar cada mapa de parámetros
auto try_map = [&](const auto& param_map) -> bool {
auto it = param_map.find(var);
if (it != param_map.end()) {
it->second(value);
return true;
}
return false;
};
// Casos especiales que necesitan lógica personalizada
if (var == "notification.pos_h") {
if (value == "LEFT") {
param.notification.pos_h = Notifier::Position::LEFT;
} else if (value == "MIDDLE") {
param.notification.pos_h = Notifier::Position::MIDDLE;
} else {
param.notification.pos_h = Notifier::Position::RIGHT;
}
return true;
}
if (var == "notification.pos_v") {
param.notification.pos_v = value == "TOP" ? Notifier::Position::TOP : Notifier::Position::BOTTOM;
return true;
}
return false; // Parámetro no encontrado
// Intentar con todos los mapas
if (try_map(INT_PARAMS) || try_map(COLOR_PARAMS) || try_map(BOOL_PARAMS) ||
try_map(FLOAT_PARAMS) || try_map(STRING_PARAMS)) {
return true;
}
// Casos especiales que necesitan lógica personalizada
if (var == "notification.pos_h") {
if (value == "LEFT") {
param.notification.pos_h = Notifier::Position::LEFT;
} else if (value == "MIDDLE") {
param.notification.pos_h = Notifier::Position::MIDDLE;
} else {
param.notification.pos_h = Notifier::Position::RIGHT;
}
return true;
}
if (var == "notification.pos_v") {
param.notification.pos_v = value == "TOP" ? Notifier::Position::TOP : Notifier::Position::BOTTOM;
return true;
}
return false; // Parámetro no encontrado
}
} // namespace

View File

@@ -207,10 +207,10 @@ struct Param {
Param() {
// Inicializar play_area usando los valores por defecto
game.play_area.rect = {
GameDefaults::Game::PLAY_AREA_X,
GameDefaults::Game::PLAY_AREA_Y,
GameDefaults::Game::PLAY_AREA_W,
GameDefaults::Game::PLAY_AREA_H};
.x = GameDefaults::Game::PLAY_AREA_X,
.y = GameDefaults::Game::PLAY_AREA_Y,
.w = GameDefaults::Game::PLAY_AREA_W,
.h = GameDefaults::Game::PLAY_AREA_H};
// Las zonas calculadas se inicializarán en precalculateZones()
precalculateZones();

View File

@@ -11,7 +11,7 @@ auto createPath(float start, float end, PathType type, float fixed_pos, int step
for (int i = 0; i < steps; ++i) {
double t = static_cast<double>(i) / (steps - 1);
double value = start + (end - start) * easing_function(t);
double value = start + ((end - start) * easing_function(t));
if ((start > 0 && end < 0) || (start < 0 && end > 0)) {
value = start + (end > 0 ? 1 : -1) * std::abs(end - start) * easing_function(t);
@@ -56,7 +56,7 @@ void PathSprite::addPath(Path path, bool centered) {
switch (path_centered) {
case PathCentered::ON_X: {
const int X = path.spots.back().x - pos_.w / 2;
const int X = path.spots.back().x - (pos_.w / 2);
for (auto &spot : path.spots) {
spot.x = X;
}
@@ -64,7 +64,7 @@ void PathSprite::addPath(Path path, bool centered) {
break;
}
case PathCentered::ON_Y: {
const int Y = path.spots.back().y - pos_.h / 2;
const int Y = path.spots.back().y - (pos_.h / 2);
for (auto &spot : path.spots) {
spot.y = Y;
}
@@ -84,7 +84,7 @@ void PathSprite::addPath(int start, int end, PathType type, int fixed_pos, int s
// Añade un recorrido
void PathSprite::addPath(const std::vector<SDL_FPoint> &spots, int waiting_counter) {
paths_.emplace_back(std::move(spots), waiting_counter);
paths_.emplace_back(spots, waiting_counter);
}
// Habilita el objeto

View File

@@ -77,16 +77,16 @@ class Player {
// --- Estructuras ---
struct Config {
Id id; // Identificador del jugador
float x; // Posición X inicial
int y; // Posición Y inicial
bool demo; // Modo demo
SDL_FRect *play_area; // Área de juego (puntero para mantener referencia)
std::vector<std::shared_ptr<Texture>> texture; // Texturas del jugador
std::vector<std::vector<std::string>> animations; // Animaciones del jugador
Table *hi_score_table; // Tabla de puntuaciones (puntero para referencia)
int *glowing_entry; // Entrada brillante (puntero para mantener referencia)
IStageInfo *stage_info; // Gestor de pantallas (puntero)
Id id; // Identificador del jugador
float x; // Posición X inicial
int y; // Posición Y inicial
bool demo; // Modo demo
SDL_FRect *play_area; // Área de juego (puntero para mantener referencia)
std::vector<std::shared_ptr<Texture>> texture; // Texturas del jugador
std::vector<std::vector<std::string>> animations; // Animaciones del jugador
Table *hi_score_table; // Tabla de puntuaciones (puntero para referencia)
int *glowing_entry; // Entrada brillante (puntero para mantener referencia)
IStageInfo *stage_info; // Gestor de pantallas (puntero)
};
// --- Constructor y destructor ---
@@ -220,7 +220,7 @@ class Player {
State firing_state_ = State::FIRING_NONE; // Estado del jugador al disparar
State playing_state_ = State::WAITING; // Estado del jugador en el juego
Uint32 continue_ticks_ = 0; // Variable para poder cambiar el contador de continue en función del tiempo
Uint32 continue_ticks_ = 0; // Variable para poder cambiar el contador de continue en función del tiempo
Uint32 name_entry_ticks_ = 0; // Variable para poder cambiar el contador de poner nombre en función del tiempo
Uint32 showing_name_ticks_ = 0; // Tiempo en el que se entra al estado SHOWING_NAME
float pos_x_ = 0.0F; // Posición en el eje X
@@ -246,7 +246,7 @@ class Player {
int step_counter_ = 0; // Cuenta los pasos para los estados en los que camina automáticamente
int credits_used_ = 0; // Indica el número de veces que ha continuado
int waiting_counter_ = 0; // Contador para el estado de espera
bool qualifies_for_high_score_ = false; // Indica si tiene una puntuación que le permite entrar en la tabla de records
bool qualifies_for_high_score_ = false; // Indica si tiene una puntuación que le permite entrar en la tabla de records
bool invulnerable_ = true; // Indica si el jugador es invulnerable
bool extra_hit_ = false; // Indica si el jugador tiene un toque extra
bool power_up_ = false; // Indica si el jugador tiene activo el modo PowerUp

View File

@@ -80,7 +80,7 @@ void Resource::loadTextFilesQuiet() {
for (const auto &l : list) {
auto name = getFileName(l);
// Buscar en nuestra lista y cargar directamente
auto it = std::find_if(text_files_.begin(), text_files_.end(), [&name](const auto &t) { return t.name == name; });
auto it = std::ranges::find_if(text_files_, [&name](const auto &t) { return t.name == name; });
if (it != text_files_.end()) {
it->text_file = Text::loadFile(l);
SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "Text file loaded: %s", name.c_str());
@@ -109,9 +109,9 @@ void Resource::loadEssentialTextures() {
for (const auto &file : texture_list) {
auto name = getFileName(file);
// Solo cargar texturas esenciales
if (std::find(ESSENTIAL_TEXTURES.begin(), ESSENTIAL_TEXTURES.end(), name) != ESSENTIAL_TEXTURES.end()) {
if (std::ranges::find(ESSENTIAL_TEXTURES, name) != ESSENTIAL_TEXTURES.end()) {
// Buscar en nuestra lista y cargar
auto it = std::find_if(textures_.begin(), textures_.end(), [&name](const auto &t) { return t.name == name; });
auto it = std::ranges::find_if(textures_, [&name](const auto &t) { return t.name == name; });
if (it != textures_.end()) {
it->texture = std::make_shared<Texture>(Screen::get()->getRenderer(), file);
}
@@ -186,7 +186,7 @@ void Resource::initResourceLists() {
// Obtiene el sonido a partir de un nombre (con carga perezosa)
auto Resource::getSound(const std::string &name) -> JA_Sound_t * {
auto it = std::find_if(sounds_.begin(), sounds_.end(), [&name](const auto &s) { return s.name == name; });
auto it = std::ranges::find_if(sounds_, [&name](const auto &s) { return s.name == name; });
if (it != sounds_.end()) {
// Si está en modo lazy y no se ha cargado aún, lo carga ahora
@@ -202,7 +202,7 @@ auto Resource::getSound(const std::string &name) -> JA_Sound_t * {
// Obtiene la música a partir de un nombre (con carga perezosa)
auto Resource::getMusic(const std::string &name) -> JA_Music_t * {
auto it = std::find_if(musics_.begin(), musics_.end(), [&name](const auto &m) { return m.name == name; });
auto it = std::ranges::find_if(musics_, [&name](const auto &m) { return m.name == name; });
if (it != musics_.end()) {
// Si está en modo lazy y no se ha cargado aún, lo carga ahora
@@ -218,7 +218,7 @@ auto Resource::getMusic(const std::string &name) -> JA_Music_t * {
// Obtiene la textura a partir de un nombre (con carga perezosa)
auto Resource::getTexture(const std::string &name) -> std::shared_ptr<Texture> {
auto it = std::find_if(textures_.begin(), textures_.end(), [&name](const auto &t) { return t.name == name; });
auto it = std::ranges::find_if(textures_, [&name](const auto &t) { return t.name == name; });
if (it != textures_.end()) {
// Si está en modo lazy y no se ha cargado aún, lo carga ahora
@@ -234,7 +234,7 @@ auto Resource::getTexture(const std::string &name) -> std::shared_ptr<Texture> {
// Obtiene el fichero de texto a partir de un nombre (con carga perezosa)
auto Resource::getTextFile(const std::string &name) -> std::shared_ptr<Text::File> {
auto it = std::find_if(text_files_.begin(), text_files_.end(), [&name](const auto &t) { return t.name == name; });
auto it = std::ranges::find_if(text_files_, [&name](const auto &t) { return t.name == name; });
if (it != text_files_.end()) {
// Si está en modo lazy y no se ha cargado aún, lo carga ahora
@@ -250,7 +250,7 @@ auto Resource::getTextFile(const std::string &name) -> std::shared_ptr<Text::Fil
// Obtiene el objeto de texto a partir de un nombre (con carga perezosa)
auto Resource::getText(const std::string &name) -> std::shared_ptr<Text> {
auto it = std::find_if(texts_.begin(), texts_.end(), [&name](const auto &t) { return t.name == name; });
auto it = std::ranges::find_if(texts_, [&name](const auto &t) { return t.name == name; });
if (it != texts_.end()) {
// Si está en modo lazy y no se ha cargado aún, lo carga ahora
@@ -266,7 +266,7 @@ auto Resource::getText(const std::string &name) -> std::shared_ptr<Text> {
// Obtiene la animación a partir de un nombre (con carga perezosa)
auto Resource::getAnimation(const std::string &name) -> AnimationsFileBuffer & {
auto it = std::find_if(animations_.begin(), animations_.end(), [&name](const auto &a) { return a.name == name; });
auto it = std::ranges::find_if(animations_, [&name](const auto &a) { return a.name == name; });
if (it != animations_.end()) {
// Si está en modo lazy y no se ha cargado aún (vector vacío), lo carga ahora
@@ -346,18 +346,18 @@ auto Resource::loadTextLazy(const std::string &name) -> std::shared_ptr<Text> {
};
const std::vector<TextMapping> TEXT_MAPPINGS = {
{"04b_25", "04b_25.png", "04b_25.txt"},
{"04b_25_2x", "04b_25_2x.png", "04b_25_2x.txt"},
{"04b_25_metal", "04b_25_metal.png", "04b_25.txt"},
{"04b_25_grey", "04b_25_grey.png", "04b_25.txt"},
{"04b_25_flat", "04b_25_flat.png", "04b_25.txt"},
{"04b_25_reversed", "04b_25_reversed.png", "04b_25.txt"},
{"04b_25_flat_2x", "04b_25_flat_2x.png", "04b_25_2x.txt"},
{"04b_25_reversed_2x", "04b_25_reversed_2x.png", "04b_25_2x.txt"},
{"8bithud", "8bithud.png", "8bithud.txt"},
{"aseprite", "aseprite.png", "aseprite.txt"},
{"smb2", "smb2.png", "smb2.txt"},
{"smb2_grad", "smb2_grad.png", "smb2.txt"}};
{.key = "04b_25", .texture_file = "04b_25.png", .text_file = "04b_25.txt"},
{.key = "04b_25_2x", .texture_file = "04b_25_2x.png", .text_file = "04b_25_2x.txt"},
{.key = "04b_25_metal", .texture_file = "04b_25_metal.png", .text_file = "04b_25.txt"},
{.key = "04b_25_grey", .texture_file = "04b_25_grey.png", .text_file = "04b_25.txt"},
{.key = "04b_25_flat", .texture_file = "04b_25_flat.png", .text_file = "04b_25.txt"},
{.key = "04b_25_reversed", .texture_file = "04b_25_reversed.png", .text_file = "04b_25.txt"},
{.key = "04b_25_flat_2x", .texture_file = "04b_25_flat_2x.png", .text_file = "04b_25_2x.txt"},
{.key = "04b_25_reversed_2x", .texture_file = "04b_25_reversed_2x.png", .text_file = "04b_25_2x.txt"},
{.key = "8bithud", .texture_file = "8bithud.png", .text_file = "8bithud.txt"},
{.key = "aseprite", .texture_file = "aseprite.png", .text_file = "aseprite.txt"},
{.key = "smb2", .texture_file = "smb2.png", .text_file = "smb2.txt"},
{.key = "smb2_grad", .texture_file = "smb2_grad.png", .text_file = "smb2.txt"}};
for (const auto &mapping : TEXT_MAPPINGS) {
if (mapping.key == name) {
@@ -531,18 +531,18 @@ void Resource::createPlayerTextures() {
// Configuración de jugadores y sus paletas
struct PlayerConfig {
std::string base_texture;
std::vector<std::string> palette_files;
std::string name_prefix;
std::string base_texture;
std::vector<std::string> palette_files;
std::string name_prefix;
};
std::vector<PlayerConfig> players = {
{"player1.gif", {"player1_coffee1.pal", "player1_coffee2.pal", "player1_invencible.pal"}, "player1"},
{"player2.gif", {"player2_coffee1.pal", "player2_coffee2.pal", "player2_invencible.pal"}, "player2"}};
{.base_texture = "player1.gif", .palette_files = {"player1_coffee1.pal", "player1_coffee2.pal", "player1_invencible.pal"}, .name_prefix = "player1"},
{.base_texture = "player2.gif", .palette_files = {"player2_coffee1.pal", "player2_coffee2.pal", "player2_invencible.pal"}, .name_prefix = "player2"}};
// Bucle principal modificado para usar un índice (player_idx)
for (size_t player_idx = 0; player_idx < players.size(); ++player_idx) {
const auto &player = players[player_idx]; // Obtenemos el jugador actual
const auto &player = players[player_idx]; // Obtenemos el jugador actual
// Encontrar el archivo original de la textura
std::string texture_file_path;
@@ -784,15 +784,15 @@ void Resource::initProgressBar() {
const float BAR_Y_POSITION = param.game.height - BAR_HEIGHT - Y_PADDING;
const float WIRED_BAR_WIDTH = param.game.width - (X_PADDING * 2);
loading_wired_rect_ = {X_PADDING, BAR_Y_POSITION, WIRED_BAR_WIDTH, BAR_HEIGHT};
loading_wired_rect_ = {.x = X_PADDING, .y = BAR_Y_POSITION, .w = WIRED_BAR_WIDTH, .h = BAR_HEIGHT};
const float FULL_BAR_WIDTH = WIRED_BAR_WIDTH * loading_count_.getPercentage();
loading_full_rect_ = {X_PADDING, BAR_Y_POSITION, FULL_BAR_WIDTH, BAR_HEIGHT};
loading_full_rect_ = {.x = X_PADDING, .y = BAR_Y_POSITION, .w = FULL_BAR_WIDTH, .h = BAR_HEIGHT};
}
// Actualiza el progreso de carga, muestra la barra y procesa eventos
void Resource::updateLoadingProgress(std::string name) {
loading_resource_name_ = name;
loading_resource_name_ = std::move(name);
loading_count_.increase();
updateProgressBar();
renderProgress();

View File

@@ -140,13 +140,13 @@ class Resource {
void loadEssentialResources(); // Carga recursos esenciales en modo lazy
void loadEssentialTextures(); // Carga solo las texturas esenciales (fuentes)
void loadTextFilesQuiet(); // Carga ficheros de texto sin mostrar progreso (para modo lazy)
void createPlayerTextures(); // Crea las texturas de jugadores con todas sus variantes de paleta
void createTextTextures(); // Crea las texturas a partir de los datos cargados
void createText(); // Crea los objetos de texto
void clear(); // Vacía todos los vectores de recursos
void load(); // Carga todos los recursos
void clearSounds(); // Vacía el vector de sonidos
void clearMusics(); // Vacía el vector de músicas
void createPlayerTextures(); // Crea las texturas de jugadores con todas sus variantes de paleta
void createTextTextures(); // Crea las texturas a partir de los datos cargados
void createText(); // Crea los objetos de texto
void clear(); // Vacía todos los vectores de recursos
void load(); // Carga todos los recursos
void clearSounds(); // Vacía el vector de sonidos
void clearMusics(); // Vacía el vector de músicas
// --- Métodos para carga perezosa ---
void initResourceLists(); // Inicializa las listas de recursos sin cargar el contenido

View File

@@ -373,14 +373,14 @@ void Scoreboard::recalculateAnchors() {
const float COL = PANEL_WIDTH / 2;
// Slots de 4
slot4_1_ = {COL, ROW1};
slot4_2_ = {COL, ROW2};
slot4_3_ = {COL, ROW3};
slot4_4_ = {COL, ROW4};
slot4_1_ = {.x = COL, .y = ROW1};
slot4_2_ = {.x = COL, .y = ROW2};
slot4_3_ = {.x = COL, .y = ROW3};
slot4_4_ = {.x = COL, .y = ROW4};
// Primer cuadrado para poner el nombre de record
const int ENTER_NAME_LENGHT = text_scoreboard_->length(std::string(NAME_SIZE, 'A'));
enter_name_pos_.x = COL - (ENTER_NAME_LENGHT / 2);
const int ENTER_NAME_LENGTH = text_scoreboard_->length(std::string(NAME_SIZE, 'A'));
enter_name_pos_.x = COL - (ENTER_NAME_LENGTH / 2);
enter_name_pos_.y = ROW4;
// Recoloca los sprites

View File

@@ -38,8 +38,8 @@ class Screen {
void initShaders(); // Inicializa los shaders
// --- Efectos visuales ---
void shake(int desp = 2, int delay = 3, int lenght = 8) { shake_effect_.enable(src_rect_, dst_rect_, desp, delay, lenght); } // Agita la pantalla
void flash(Color color, int lenght = 10, int delay = 0) { flash_effect_ = FlashEffect(true, lenght, delay, color); } // Pone la pantalla de color
void shake(int desp = 2, int delay = 3, int length = 8) { shake_effect_.enable(src_rect_, dst_rect_, desp, delay, length); } // Agita la pantalla
void flash(Color color, int length = 10, int delay = 0) { flash_effect_ = FlashEffect(true, length, delay, color); } // Pone la pantalla de color
void toggleShaders(); // Alterna entre activar y desactivar los shaders
void toggleIntegerScale(); // Alterna entre activar y desactivar el escalado entero
void toggleVSync(); // Alterna entre activar y desactivar el V-Sync
@@ -85,16 +85,16 @@ class Screen {
// Efecto de flash en pantalla: pinta la pantalla de un color durante unos frames
struct FlashEffect {
bool enabled; // Indica si el efecto está activo
int lenght; // Duración total del efecto en frames
int length; // Duración total del efecto en frames
int delay; // Retraso antes de mostrar el flash
int counter; // Contador de frames restantes
Color color; // Color del flash
explicit FlashEffect(bool enabled = false, int lenght = 0, int delay = 0, Color color = Color(0xFF, 0xFF, 0xFF))
: enabled(enabled), lenght(lenght), delay(delay), counter(lenght), color(color) {}
explicit FlashEffect(bool enabled = false, int length = 0, int delay = 0, Color color = Color(0xFF, 0xFF, 0xFF))
: enabled(enabled), length(length), delay(delay), counter(length), color(color) {}
void update() { (enabled && counter > 0) ? counter-- : static_cast<int>(enabled = false); }
[[nodiscard]] auto isRendarable() const -> bool { return enabled && counter < lenght - delay; }
[[nodiscard]] auto isRendarable() const -> bool { return enabled && counter < length - delay; }
};
// Efecto de sacudida/agitación de pantalla: mueve la imagen para simular un temblor
@@ -102,17 +102,17 @@ class Screen {
int desp; // Desplazamiento máximo de la sacudida (en píxeles)
int delay; // Frames entre cada movimiento de sacudida
int counter; // Contador de frames para el siguiente movimiento
int lenght; // Duración total del efecto en frames
int length; // Duración total del efecto en frames
int remaining; // Frames restantes de sacudida
int original_pos; // Posición original de la imagen (x)
int original_width; // Ancho original de la imagen
bool enabled; // Indica si el efecto está activo
explicit ShakeEffect(bool en = false, int dp = 2, int dl = 3, int cnt = 0, int len = 8, int rem = 0, int orig_pos = 0, int orig_width = 800)
: desp(dp), delay(dl), counter(cnt), lenght(len), remaining(rem), original_pos(orig_pos), original_width(orig_width), enabled(en) {}
: desp(dp), delay(dl), counter(cnt), length(len), remaining(rem), original_pos(orig_pos), original_width(orig_width), enabled(en) {}
// Activa el efecto de sacudida y guarda la posición y tamaño originales
void enable(SDL_FRect &src_rect, SDL_FRect &dst_rect, int new_desp = -1, int new_delay = -1, int new_lenght = -1) {
void enable(SDL_FRect &src_rect, SDL_FRect &dst_rect, int new_desp = -1, int new_delay = -1, int new_length = -1) {
if (!enabled) {
enabled = true;
original_pos = src_rect.x;
@@ -125,14 +125,14 @@ class Screen {
if (new_delay != -1) {
delay = new_delay;
}
if (new_lenght != -1) {
lenght = new_lenght;
if (new_length != -1) {
length = new_length;
}
src_rect.w -= desp;
dst_rect.w = src_rect.w;
}
remaining = lenght;
remaining = length;
counter = delay;
}
@@ -171,12 +171,12 @@ class Screen {
#endif
// --- Objetos y punteros ---
SDL_Window *window_; // Ventana de la aplicación
SDL_Renderer *renderer_; // El renderizador de la ventana
SDL_Texture *game_canvas_; // Textura donde se dibuja todo antes de volcarse al renderizador
ServiceMenu *service_menu_; // Objeto para mostrar el menú de servicio
Notifier *notifier_; // Objeto para mostrar las notificaciones por pantalla
std::shared_ptr<Text> text_; // Objeto para escribir texto en pantalla
SDL_Window *window_; // Ventana de la aplicación
SDL_Renderer *renderer_; // El renderizador de la ventana
SDL_Texture *game_canvas_; // Textura donde se dibuja todo antes de volcarse al renderizador
ServiceMenu *service_menu_; // Objeto para mostrar el menú de servicio
Notifier *notifier_; // Objeto para mostrar las notificaciones por pantalla
std::shared_ptr<Text> text_; // Objeto para escribir texto en pantalla
// --- Variables de estado ---
SDL_FRect src_rect_; // Coordenadas de origen para dibujar la textura del juego

View File

@@ -170,7 +170,7 @@ void Credits::fillTextTexture() {
const int SPACE_POST_TITLE = 3 + text->getCharacterSize();
const int SPACE_PRE_TITLE = text->getCharacterSize() * 4;
const int TEXTS_HEIGHT = 1 * text->getCharacterSize() + 8 * SPACE_POST_TITLE + 3 * SPACE_PRE_TITLE;
const int TEXTS_HEIGHT = (1 * text->getCharacterSize()) + (8 * SPACE_POST_TITLE) + (3 * SPACE_PRE_TITLE);
const int POS_X = static_cast<int>(param.game.game_area.center_x);
credits_rect_dst_.h = credits_rect_src_.h = static_cast<float>(TEXTS_HEIGHT);
auto text_style = Text::Style(Text::CENTER | Text::SHADOW, NO_TEXT_COLOR, SHADOW_TEXT_COLOR);
@@ -213,11 +213,11 @@ void Credits::fillTextTexture() {
y += SPACE_PRE_TITLE;
mini_logo_rect_src_.y = static_cast<float>(y);
auto mini_logo_sprite = std::make_unique<Sprite>(Resource::get()->getTexture("logo_jailgames_mini.png"));
mini_logo_sprite->setPosition(1 + POS_X - mini_logo_sprite->getWidth() / 2, 1 + y);
mini_logo_sprite->setPosition(1 + POS_X - (mini_logo_sprite->getWidth() / 2), 1 + y);
Resource::get()->getTexture("logo_jailgames_mini.png")->setColor(SHADOW_TEXT_COLOR.r, SHADOW_TEXT_COLOR.g, SHADOW_TEXT_COLOR.b);
mini_logo_sprite->render();
mini_logo_sprite->setPosition(POS_X - mini_logo_sprite->getWidth() / 2, y);
mini_logo_sprite->setPosition(POS_X - (mini_logo_sprite->getWidth() / 2), y);
Resource::get()->getTexture("logo_jailgames_mini.png")->setColor(255, 255, 255);
mini_logo_sprite->render();

View File

@@ -466,35 +466,35 @@ void Game::checkPlayerItemCollision(std::shared_ptr<Player> &player) {
switch (item->getType()) {
case ItemType::DISK: {
player->addScore(1000, Options::settings.hi_score_table.back().score);
const auto X = item->getPosX() + (item->getWidth() - game_text_textures_.at(0)->getWidth()) / 2;
const auto X = item->getPosX() + ((item->getWidth() - game_text_textures_.at(0)->getWidth()) / 2);
createItemText(X, game_text_textures_.at(0));
playSound("item_pickup.wav");
break;
}
case ItemType::GAVINA: {
player->addScore(2500, Options::settings.hi_score_table.back().score);
const auto X = item->getPosX() + (item->getWidth() - game_text_textures_.at(1)->getWidth()) / 2;
const auto X = item->getPosX() + ((item->getWidth() - game_text_textures_.at(1)->getWidth()) / 2);
createItemText(X, game_text_textures_.at(1));
playSound("item_pickup.wav");
break;
}
case ItemType::PACMAR: {
player->addScore(5000, Options::settings.hi_score_table.back().score);
const auto X = item->getPosX() + (item->getWidth() - game_text_textures_.at(2)->getWidth()) / 2;
const auto X = item->getPosX() + ((item->getWidth() - game_text_textures_.at(2)->getWidth()) / 2);
createItemText(X, game_text_textures_.at(2));
playSound("item_pickup.wav");
break;
}
case ItemType::DEBIAN: {
player->addScore(100000, Options::settings.hi_score_table.back().score);
const auto X = item->getPosX() + (item->getWidth() - game_text_textures_.at(6)->getWidth()) / 2;
const auto X = item->getPosX() + ((item->getWidth() - game_text_textures_.at(6)->getWidth()) / 2);
createItemText(X, game_text_textures_.at(6));
playSound("debian_pickup.wav");
break;
}
case ItemType::CLOCK: {
enableTimeStopItem();
const auto X = item->getPosX() + (item->getWidth() - game_text_textures_.at(5)->getWidth()) / 2;
const auto X = item->getPosX() + ((item->getWidth() - game_text_textures_.at(5)->getWidth()) / 2);
createItemText(X, game_text_textures_.at(5));
playSound("item_pickup.wav");
break;
@@ -502,11 +502,11 @@ void Game::checkPlayerItemCollision(std::shared_ptr<Player> &player) {
case ItemType::COFFEE: {
if (player->getCoffees() == 2) {
player->addScore(5000, Options::settings.hi_score_table.back().score);
const auto X = item->getPosX() + (item->getWidth() - game_text_textures_.at(2)->getWidth()) / 2;
const auto X = item->getPosX() + ((item->getWidth() - game_text_textures_.at(2)->getWidth()) / 2);
createItemText(X, game_text_textures_.at(2));
} else {
player->giveExtraHit();
const auto X = item->getPosX() + (item->getWidth() - game_text_textures_.at(4)->getWidth()) / 2;
const auto X = item->getPosX() + ((item->getWidth() - game_text_textures_.at(4)->getWidth()) / 2);
createItemText(X, game_text_textures_.at(4));
}
playSound("voice_coffee.wav");
@@ -515,7 +515,7 @@ void Game::checkPlayerItemCollision(std::shared_ptr<Player> &player) {
case ItemType::COFFEE_MACHINE: {
player->setPowerUp();
coffee_machine_enabled_ = false;
const auto X = item->getPosX() + (item->getWidth() - game_text_textures_.at(3)->getWidth()) / 2;
const auto X = item->getPosX() + ((item->getWidth() - game_text_textures_.at(3)->getWidth()) / 2);
createItemText(X, game_text_textures_.at(3));
playSound("voice_power_up.wav");
break;
@@ -582,19 +582,18 @@ void Game::handleTabeHitEffects() {
// Maneja la colisión entre bala y globos
auto Game::checkBulletBalloonCollision(const std::shared_ptr<Bullet> &bullet) -> bool {
for (auto &balloon : balloon_manager_->getBalloons()) {
return std::ranges::any_of(balloon_manager_->getBalloons(), [this, &bullet](auto &balloon) {
if (!balloon->isEnabled() || balloon->isInvulnerable()) {
continue;
return false;
}
if (!checkCollision(balloon->getCollider(), bullet->getCollider())) {
continue;
return false;
}
processBalloonHit(bullet, balloon);
return true;
}
return false;
});
}
// Procesa el impacto en un globo
@@ -623,9 +622,9 @@ void Game::handleItemDrop(const std::shared_ptr<Balloon> &balloon, const std::sh
}
// Maneja la destrucción del globo y puntuación
void Game::handleBalloonDestruction(std::shared_ptr<Balloon> balloon, const std::shared_ptr<Player> &player) {
void Game::handleBalloonDestruction(const std::shared_ptr<Balloon> &balloon, const std::shared_ptr<Player> &player) {
if (player->isPlaying()) {
auto const SCORE = balloon_manager_->popBalloon(std::move(balloon)) * player->getScoreMultiplier() * difficulty_score_multiplier_;
auto const SCORE = balloon_manager_->popBalloon(balloon) * player->getScoreMultiplier() * difficulty_score_multiplier_;
player->addScore(SCORE, Options::settings.hi_score_table.back().score);
player->incScoreMultiplier();
}
@@ -874,7 +873,7 @@ void Game::handlePlayerCollision(std::shared_ptr<Player> &player, std::shared_pt
if (player->hasExtraHit()) {
// Lo pierde
player->removeExtraHit();
throwCoffee(player->getPosX() + (player->getWidth() / 2), player->getPosY() + (player->getHeight() / 2));
throwCoffee(player->getPosX() + (Player::getWidth() / 2), player->getPosY() + (Player::getHeight() / 2));
playSound("coffee_out.wav");
screen_->shake();
} else {
@@ -988,7 +987,7 @@ void Game::fillCanvas() {
background_->render();
balloon_manager_->render();
renderSmartSprites(); // El cafe que sale cuando te golpean
renderSmartSprites(); // El cafe que sale cuando te golpean
renderItems();
tabe_->render();
renderBullets();
@@ -1033,7 +1032,7 @@ void Game::initPaths() {
const auto &texture = Resource::get()->getTexture("game_text_get_ready");
const auto W = texture->getWidth();
const int X0 = -W;
const int X1 = param.game.play_area.center_x - W / 2;
const int X1 = param.game.play_area.center_x - (W / 2);
const int X2 = param.game.play_area.rect.w;
const int Y = param.game.play_area.center_y;
paths_.emplace_back(createPath(X0, X1, PathType::HORIZONTAL, Y, 80, easeOutQuint), 20);
@@ -1045,7 +1044,7 @@ void Game::initPaths() {
const auto &texture = Resource::get()->getTexture("game_text_last_stage");
const auto H = texture->getHeight();
const int Y0 = param.game.play_area.rect.h - H;
const int Y1 = param.game.play_area.center_y - H / 2;
const int Y1 = param.game.play_area.center_y - (H / 2);
const int Y2 = -H;
const int X = param.game.play_area.center_x;
paths_.emplace_back(createPath(Y0, Y1, PathType::VERTICAL, X, 80, easeOutQuint), 20);
@@ -1058,9 +1057,9 @@ void Game::initPaths() {
const auto W = texture->getWidth();
const auto H = texture->getHeight();
const int X0 = -W;
const int X1 = param.game.play_area.center_x - W / 2;
const int X1 = param.game.play_area.center_x - (W / 2);
const int X2 = param.game.play_area.rect.w;
const int Y = param.game.play_area.center_y - H / 2 - 20;
const int Y = param.game.play_area.center_y - (H / 2) - 20;
paths_.emplace_back(createPath(X0, X1, PathType::HORIZONTAL, Y, 80, easeOutQuint), 400);
paths_.emplace_back(createPath(X1, X2, PathType::HORIZONTAL, Y, 80, easeInQuint), 0);
}
@@ -1071,9 +1070,9 @@ void Game::initPaths() {
const auto W = texture->getWidth();
const auto H = texture->getHeight();
const int X0 = param.game.play_area.rect.w;
const int X1 = param.game.play_area.center_x - W / 2;
const int X1 = param.game.play_area.center_x - (W / 2);
const int X2 = -W;
const int Y = param.game.play_area.center_y + H / 2 - 20;
const int Y = param.game.play_area.center_y + (H / 2) - 20;
paths_.emplace_back(createPath(X0, X1, PathType::HORIZONTAL, Y, 80, easeOutQuint), 400);
paths_.emplace_back(createPath(X1, X2, PathType::HORIZONTAL, Y, 80, easeInQuint), 0);
}
@@ -1199,7 +1198,7 @@ void Game::checkPlayersStatusPlaying() {
// Obtiene un jugador a partir de su "id"
auto Game::getPlayer(Player::Id id) -> std::shared_ptr<Player> {
auto it = std::find_if(players_.begin(), players_.end(), [id](const auto &player) { return player->getId() == id; });
auto it = std::ranges::find_if(players_, [id](const auto &player) { return player->getId() == id; });
if (it != players_.end()) {
return *it;
@@ -1304,7 +1303,7 @@ void Game::handleFireInput(const std::shared_ptr<Player> &player, BulletType bul
switch (bullet_type) {
case BulletType::UP:
player->setInput(Input::Action::FIRE_CENTER);
bullet.x = 2 + player->getPosX() + (player->getWidth() - Bullet::WIDTH) / 2;
bullet.x = 2 + player->getPosX() + (Player::getWidth() - Bullet::WIDTH) / 2;
bullet.y = player->getPosY() - (Bullet::HEIGHT / 2);
break;
case BulletType::LEFT:
@@ -1314,7 +1313,7 @@ void Game::handleFireInput(const std::shared_ptr<Player> &player, BulletType bul
break;
case BulletType::RIGHT:
player->setInput(Input::Action::FIRE_RIGHT);
bullet.x = player->getPosX() + player->getWidth() - (Bullet::WIDTH / 2);
bullet.x = player->getPosX() + Player::getWidth() - (Bullet::WIDTH / 2);
bullet.y = player->getPosY();
break;
default:
@@ -1835,9 +1834,9 @@ void Game::sortPlayersByZOrder() {
// Procesar jugadores que van al fondo (se dibujan primero)
if (!players_to_put_at_back_.empty()) {
for (auto &player : players_to_put_at_back_) {
auto it = std::find(players_.begin(), players_.end(), player);
auto it = std::ranges::find(players_, player);
if (it != players_.end() && it != players_.begin()) {
std::shared_ptr<Player> dying_player = *it;
const std::shared_ptr<Player> &dying_player = *it;
players_.erase(it);
players_.insert(players_.begin(), dying_player);
}
@@ -1848,9 +1847,9 @@ void Game::sortPlayersByZOrder() {
// Procesar jugadores que van al frente (se dibujan últimos)
if (!players_to_put_at_front_.empty()) {
for (auto &player : players_to_put_at_front_) {
auto it = std::find(players_.begin(), players_.end(), player);
auto it = std::ranges::find(players_, player);
if (it != players_.end() && it != players_.end() - 1) {
std::shared_ptr<Player> front_player = *it;
const std::shared_ptr<Player> &front_player = *it;
players_.erase(it);
players_.push_back(front_player);
}
@@ -1910,7 +1909,7 @@ void Game::handleDebugEvents(const SDL_Event &event) {
}
case SDLK_5: // 5.000
{
const int X = players_.at(0)->getPosX() + (players_.at(0)->getWidth() - game_text_textures_[3]->getWidth()) / 2;
const int X = players_.at(0)->getPosX() + ((Player::getWidth() - game_text_textures_[3]->getWidth()) / 2);
createItemText(X, game_text_textures_.at(2));
break;
}
@@ -1921,7 +1920,7 @@ void Game::handleDebugEvents(const SDL_Event &event) {
}
case SDLK_7: // 100.000
{
const int X = players_.at(0)->getPosX() + (players_.at(0)->getWidth() - game_text_textures_[3]->getWidth()) / 2;
const int X = players_.at(0)->getPosX() + ((Player::getWidth() - game_text_textures_[3]->getWidth()) / 2);
createItemText(X, game_text_textures_.at(6));
break;
}

View File

@@ -253,9 +253,9 @@ class Game {
void createMessage(const std::vector<Path> &paths, const std::shared_ptr<Texture> &texture); // Crea mensaje con animación por ruta
// --- Sistema de globos y enemigos ---
void handleBalloonDestruction(std::shared_ptr<Balloon> balloon, const std::shared_ptr<Player> &player); // Procesa destrucción de globo
void handleTabeHitEffects(); // Gestiona efectos al golpear a Tabe
void checkAndUpdateBalloonSpeed(); // Ajusta velocidad de globos según progreso
void handleBalloonDestruction(const std::shared_ptr<Balloon> &balloon, const std::shared_ptr<Player> &player); // Procesa destrucción de globo
void handleTabeHitEffects(); // Gestiona efectos al golpear a Tabe
void checkAndUpdateBalloonSpeed(); // Ajusta velocidad de globos según progreso
// --- Gestión de fases y progresión ---
void updateStage(); // Verifica y actualiza cambio de fase

View File

@@ -177,11 +177,11 @@ void HiScoreTable::createSprites() {
float backbuffer_height;
SDL_GetTextureSize(backbuffer_, &backbuffer_width, &backbuffer_height);
constexpr int ENTRY_LENGHT = 22;
constexpr int ENTRY_LENGTH = 22;
constexpr int MAX_NAMES = 10;
const int SPACE_BETWEEN_HEADER = entry_text->getCharacterSize() * 4;
const int SPACE_BETWEEN_LINES = entry_text->getCharacterSize() * 2;
const int SIZE = SPACE_BETWEEN_HEADER + SPACE_BETWEEN_LINES * (MAX_NAMES - 1) + entry_text->getCharacterSize();
const int SIZE = SPACE_BETWEEN_HEADER + (SPACE_BETWEEN_LINES * (MAX_NAMES - 1)) + entry_text->getCharacterSize();
const int FIRST_LINE = (param.game.height - SIZE) / 2;
// Crea el sprite para el texto de cabecera
@@ -190,13 +190,13 @@ void HiScoreTable::createSprites() {
// Crea los sprites para las entradas en la tabla de puntuaciones
const int ANIMATION = rand() % 4;
const std::string SAMPLE_LINE(ENTRY_LENGHT + 3, ' ');
const std::string SAMPLE_LINE(ENTRY_LENGTH + 3, ' ');
auto sample_entry = std::make_unique<Sprite>(entry_text->writeDXToTexture(Text::SHADOW, SAMPLE_LINE, 1, NO_TEXT_COLOR, 1, SHADOW_TEXT_COLOR));
const auto ENTRY_WIDTH = sample_entry->getWidth();
for (int i = 0; i < MAX_NAMES; ++i) {
const auto TABLE_POSITION = format(i + 1) + ". ";
const auto SCORE = format(Options::settings.hi_score_table.at(i).score);
const auto NUM_DOTS = ENTRY_LENGHT - Options::settings.hi_score_table.at(i).name.size() - SCORE.size();
const auto NUM_DOTS = ENTRY_LENGTH - Options::settings.hi_score_table.at(i).name.size() - SCORE.size();
const auto *const ONE_CC = Options::settings.hi_score_table.at(i).one_credit_complete ? " }" : "";
std::string dots;
for (int j = 0; j < (int)NUM_DOTS; ++j) {
@@ -322,7 +322,7 @@ void HiScoreTable::initBackground() {
// Obtiene un color del vector de colores de entradas
auto HiScoreTable::getEntryColor(int counter) -> Color {
int cycle_length = entry_colors_.size() * 2 - 2;
int cycle_length = (entry_colors_.size() * 2) - 2;
size_t n = counter % cycle_length;
size_t index;

View File

@@ -137,7 +137,7 @@ void Instructions::fillTexture() {
const int FIRST_LINE = (param.game.height - SIZE) / 2;
// Calcula cual es el texto más largo de las descripciones de los items
int lenght = 0;
int length = 0;
const std::array<std::string, 5> ITEM_DESCRIPTIONS = {
Lang::getText("[INSTRUCTIONS] 07"),
Lang::getText("[INSTRUCTIONS] 08"),
@@ -146,9 +146,9 @@ void Instructions::fillTexture() {
Lang::getText("[INSTRUCTIONS] 11")};
for (const auto &desc : ITEM_DESCRIPTIONS) {
const int L = text_->length(desc);
lenght = L > lenght ? L : lenght;
length = L > length ? L : length;
}
const int ANCHOR_ITEM = (param.game.width - (lenght + X_OFFSET)) / 2;
const int ANCHOR_ITEM = (param.game.width - (length + X_OFFSET)) / 2;
auto caption_style = Text::Style(Text::CENTER | Text::COLOR | Text::SHADOW, ORANGE_TEXT_COLOR, SHADOW_TEXT_COLOR);
auto text_style = Text::Style(Text::CENTER | Text::COLOR | Text::SHADOW, NO_TEXT_COLOR, SHADOW_TEXT_COLOR);
@@ -157,21 +157,21 @@ void Instructions::fillTexture() {
text_->writeStyle(param.game.game_area.center_x, FIRST_LINE, Lang::getText("[INSTRUCTIONS] 01"), caption_style);
const int ANCHOR1 = FIRST_LINE + SPACE_POST_HEADER;
text_->writeStyle(param.game.game_area.center_x, ANCHOR1 + SPACE_BETWEEN_LINES * 0, Lang::getText("[INSTRUCTIONS] 02"), text_style);
text_->writeStyle(param.game.game_area.center_x, ANCHOR1 + SPACE_BETWEEN_LINES * 1, Lang::getText("[INSTRUCTIONS] 03"), text_style);
text_->writeStyle(param.game.game_area.center_x, ANCHOR1 + SPACE_NEW_PARAGRAPH + SPACE_BETWEEN_LINES * 2, Lang::getText("[INSTRUCTIONS] 04"), text_style);
text_->writeStyle(param.game.game_area.center_x, ANCHOR1 + SPACE_NEW_PARAGRAPH + SPACE_BETWEEN_LINES * 3, Lang::getText("[INSTRUCTIONS] 05"), text_style);
text_->writeStyle(param.game.game_area.center_x, ANCHOR1 + (SPACE_BETWEEN_LINES * 0), Lang::getText("[INSTRUCTIONS] 02"), text_style);
text_->writeStyle(param.game.game_area.center_x, ANCHOR1 + (SPACE_BETWEEN_LINES * 1), Lang::getText("[INSTRUCTIONS] 03"), text_style);
text_->writeStyle(param.game.game_area.center_x, ANCHOR1 + SPACE_NEW_PARAGRAPH + (SPACE_BETWEEN_LINES * 2), Lang::getText("[INSTRUCTIONS] 04"), text_style);
text_->writeStyle(param.game.game_area.center_x, ANCHOR1 + SPACE_NEW_PARAGRAPH + (SPACE_BETWEEN_LINES * 3), Lang::getText("[INSTRUCTIONS] 05"), text_style);
// Escribe el texto de los objetos y sus puntos
const int ANCHOR2 = ANCHOR1 + SPACE_PRE_HEADER + SPACE_NEW_PARAGRAPH + SPACE_BETWEEN_LINES * 3;
const int ANCHOR2 = ANCHOR1 + SPACE_PRE_HEADER + SPACE_NEW_PARAGRAPH + (SPACE_BETWEEN_LINES * 3);
text_->writeStyle(param.game.game_area.center_x, ANCHOR2, Lang::getText("[INSTRUCTIONS] 06"), caption_style);
const int ANCHOR3 = ANCHOR2 + SPACE_POST_HEADER;
text_->writeShadowed(ANCHOR_ITEM + X_OFFSET, ANCHOR3 + SPACE_BETWEEN_ITEM_LINES * 0, Lang::getText("[INSTRUCTIONS] 07"), SHADOW_TEXT_COLOR);
text_->writeShadowed(ANCHOR_ITEM + X_OFFSET, ANCHOR3 + SPACE_BETWEEN_ITEM_LINES * 1, Lang::getText("[INSTRUCTIONS] 08"), SHADOW_TEXT_COLOR);
text_->writeShadowed(ANCHOR_ITEM + X_OFFSET, ANCHOR3 + SPACE_BETWEEN_ITEM_LINES * 2, Lang::getText("[INSTRUCTIONS] 09"), SHADOW_TEXT_COLOR);
text_->writeShadowed(ANCHOR_ITEM + X_OFFSET, ANCHOR3 + SPACE_BETWEEN_ITEM_LINES * 3, Lang::getText("[INSTRUCTIONS] 10"), SHADOW_TEXT_COLOR);
text_->writeShadowed(ANCHOR_ITEM + X_OFFSET, ANCHOR3 + SPACE_BETWEEN_ITEM_LINES * 4, Lang::getText("[INSTRUCTIONS] 11"), SHADOW_TEXT_COLOR);
text_->writeShadowed(ANCHOR_ITEM + X_OFFSET, ANCHOR3 + (SPACE_BETWEEN_ITEM_LINES * 0), Lang::getText("[INSTRUCTIONS] 07"), SHADOW_TEXT_COLOR);
text_->writeShadowed(ANCHOR_ITEM + X_OFFSET, ANCHOR3 + (SPACE_BETWEEN_ITEM_LINES * 1), Lang::getText("[INSTRUCTIONS] 08"), SHADOW_TEXT_COLOR);
text_->writeShadowed(ANCHOR_ITEM + X_OFFSET, ANCHOR3 + (SPACE_BETWEEN_ITEM_LINES * 2), Lang::getText("[INSTRUCTIONS] 09"), SHADOW_TEXT_COLOR);
text_->writeShadowed(ANCHOR_ITEM + X_OFFSET, ANCHOR3 + (SPACE_BETWEEN_ITEM_LINES * 3), Lang::getText("[INSTRUCTIONS] 10"), SHADOW_TEXT_COLOR);
text_->writeShadowed(ANCHOR_ITEM + X_OFFSET, ANCHOR3 + (SPACE_BETWEEN_ITEM_LINES * 4), Lang::getText("[INSTRUCTIONS] 11"), SHADOW_TEXT_COLOR);
// Deja el renderizador como estaba
SDL_SetRenderTarget(renderer_, temp);

View File

@@ -326,7 +326,7 @@ void Intro::initSprites() {
card_sprites_.push_back(std::move(sprite));
}
const float X_DEST = param.game.game_area.center_x - CARD_WIDTH / 2;
const float X_DEST = param.game.game_area.center_x - (CARD_WIDTH / 2);
const float Y_DEST = param.game.game_area.first_quarter_y - (CARD_HEIGHT / 4);
card_sprites_.at(0)->addPath(-CARD_WIDTH - 10, X_DEST, PathType::HORIZONTAL, Y_DEST, 100, easeInOutExpo, 0);

View File

@@ -47,7 +47,7 @@ Title::Title()
// Configura objetos
tiled_bg_->setColor(param.title.bg_color);
game_logo_->enable();
mini_logo_sprite_->setX(param.game.game_area.center_x - mini_logo_sprite_->getWidth() / 2);
mini_logo_sprite_->setX(param.game.game_area.center_x - (mini_logo_sprite_->getWidth() / 2));
fade_->setColor(param.fade.color);
fade_->setType(Fade::Type::RANDOM_SQUARE);
fade_->setPostDuration(param.fade.post_duration);
@@ -560,7 +560,7 @@ void Title::renderPlayers() {
// Obtiene un jugador a partir de su "id"
auto Title::getPlayer(Player::Id id) -> std::shared_ptr<Player> {
auto it = std::find_if(players_.begin(), players_.end(), [id](const auto& player) { return player->getId() == id; });
auto it = std::ranges::find_if(players_, [id](const auto& player) { return player->getId() == id; });
if (it != players_.end()) {
return *it;

View File

@@ -21,7 +21,7 @@ struct Gamepad;
// --- Constantes ---
constexpr std::string_view TEXT_COPYRIGHT = "@2020,2025 JailDesigner"; // Texto de copyright
constexpr bool ALLOW_TITLE_ANIMATION_SKIP = false; // Permite saltar la animación del título
constexpr bool ALLOW_TITLE_ANIMATION_SKIP = false; // Permite saltar la animación del título
// --- Clase Title: gestiona el estado de título/menú principal del juego ---
class Title {
@@ -63,9 +63,9 @@ class Title {
Uint64 ticks_ = 0; // Contador de ticks para ajustar la velocidad
int counter_ = 0; // Temporizador para la pantalla de título
int num_controllers_; // Número de mandos conectados
bool should_render_start_prompt_ = false; // Indica si se muestra el texto de PRESS START BUTTON TO PLAY
bool player1_start_pressed_ = false; // Indica si se ha pulsado el botón de empezar para el jugador 1
bool player2_start_pressed_ = false; // Indica si se ha pulsado el botón de empezar para el jugador 2
bool should_render_start_prompt_ = false; // Indica si se muestra el texto de PRESS START BUTTON TO PLAY
bool player1_start_pressed_ = false; // Indica si se ha pulsado el botón de empezar para el jugador 1
bool player2_start_pressed_ = false; // Indica si se ha pulsado el botón de empezar para el jugador 2
// --- Ciclo de vida del título ---
void update(); // Actualiza las variables del objeto

View File

@@ -1,24 +1,28 @@
#include "shutdown.h"
#include <array>
#include <iostream>
#include <vector>
#ifdef _WIN32
#include <windows.h>
#include <windows.h>
#else
#include <unistd.h>
#include <sys/wait.h>
#include <string>
#include <sys/wait.h>
#include <unistd.h>
#include <string>
#endif
namespace SystemShutdown {
#ifndef _WIN32
// Función auxiliar para sistemas Unix-like
auto executeUnixShutdown(const char* command, char* const args[]) -> ShutdownResult {
// Función auxiliar para sistemas Unix-like
auto executeUnixShutdown(const char* command, const std::vector<char*>& args) -> ShutdownResult {
pid_t pid = fork();
if (pid == 0) {
// Proceso hijo
execvp(command, args);
execvp(command, args.data());
// Si llegamos aquí, execvp falló
std::cerr << "Error: No se pudo ejecutar " << command << '\n';
_exit(1);
@@ -33,7 +37,7 @@ auto executeUnixShutdown(const char* command, char* const args[]) -> ShutdownRes
}
#endif
// Implementación de las funciones públicas
// Implementación de las funciones públicas
auto shutdownSystem() -> ShutdownResult {
ShutdownConfig config;
return shutdownSystem(config);
@@ -48,71 +52,70 @@ auto shutdownSystem(int delay_seconds, bool force_apps) -> ShutdownResult {
auto shutdownSystem(const ShutdownConfig& config) -> ShutdownResult {
#ifdef _WIN32
// Windows: Usar CreateProcess
STARTUPINFOA si = {0};
PROCESS_INFORMATION pi = {0};
si.cb = sizeof(si);
// Windows: Usar CreateProcess
STARTUPINFOA si = {0};
PROCESS_INFORMATION pi = {0};
si.cb = sizeof(si);
// Crear comando con el delay especificado
std::string command = "shutdown.exe /s /t " + std::to_string(config.delay_seconds);
if (config.force_close_apps) {
command += " /f";
}
// CreateProcess necesita un array de char modificable
char* cmd_buffer = new char[command.length() + 1];
strcpy(cmd_buffer, command.c_str());
bool success = CreateProcessA(
NULL, // lpApplicationName
cmd_buffer, // lpCommandLine
NULL, // lpProcessAttributes
NULL, // lpThreadAttributes
FALSE, // bInheritHandles
0, // dwCreationFlags
NULL, // lpEnvironment
NULL, // lpCurrentDirectory
&si, // lpStartupInfo
&pi // lpProcessInformation
);
delete[] cmd_buffer;
if (success) {
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
return ShutdownResult::SUCCESS;
} else {
DWORD error = GetLastError();
if (error == ERROR_ACCESS_DENIED) {
return ShutdownResult::ERROR_PERMISSION;
}
return ShutdownResult::ERROR_SYSTEM_CALL;
// Crear comando con el delay especificado
std::string command = "shutdown.exe /s /t " + std::to_string(config.delay_seconds);
if (config.force_close_apps) {
command += " /f";
}
// CreateProcess necesita un array de char modificable
char* cmd_buffer = new char[command.length() + 1];
strcpy(cmd_buffer, command.c_str());
bool success = CreateProcessA(
NULL, // lpApplicationName
cmd_buffer, // lpCommandLine
NULL, // lpProcessAttributes
NULL, // lpThreadAttributes
FALSE, // bInheritHandles
0, // dwCreationFlags
NULL, // lpEnvironment
NULL, // lpCurrentDirectory
&si, // lpStartupInfo
&pi // lpProcessInformation
);
delete[] cmd_buffer;
if (success) {
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
return ShutdownResult::SUCCESS;
} else {
DWORD error = GetLastError();
if (error == ERROR_ACCESS_DENIED) {
return ShutdownResult::ERROR_PERMISSION;
}
return ShutdownResult::ERROR_SYSTEM_CALL;
}
#elif __APPLE__
// macOS - apagado inmediato
char* args[] = {
const_cast<char*>("shutdown"),
const_cast<char*>("-h"),
const_cast<char*>("now"),
NULL
};
// macOS - apagado inmediato
std::vector<char*> args = {
const_cast<char*>("shutdown"),
const_cast<char*>("-h"),
const_cast<char*>("now"),
nullptr};
return executeUnixShutdown("shutdown", args);
return executeUnixShutdown("shutdown", args);
#elif __linux__
// Linux - apagado inmediato
char* args[] = {
const_cast<char*>("shutdown"),
const_cast<char*>("-h"),
const_cast<char*>("now"),
nullptr};
// Linux - apagado inmediato
std::vector<char*> args = {
const_cast<char*>("shutdown"),
const_cast<char*>("-h"),
const_cast<char*>("now"),
nullptr};
return executeUnixShutdown("shutdown", args);
return executeUnixShutdown("shutdown", args);
#else
return ShutdownResult::ERROR_UNSUPPORTED;
return ShutdownResult::ERROR_UNSUPPORTED;
#endif
}
@@ -135,20 +138,20 @@ auto resultToString(ShutdownResult result) -> const char* {
auto isShutdownSupported() -> bool {
#if defined(_WIN32) || defined(__APPLE__) || defined(__linux__)
return true;
return true;
#else
return false;
return false;
#endif
}
auto getRequiredPermissions() -> const char* {
#ifdef _WIN32
return "Requiere permisos de Administrador en Windows";
return "Requiere permisos de Administrador en Windows";
#elif defined(__APPLE__) || defined(__linux__)
return "Requiere permisos de root/sudo en Unix";
return "Requiere permisos de root/sudo en Unix";
#else
return "Sistema no soportado";
return "Sistema no soportado";
#endif
}
} // namespace SystemShutdown
} // namespace SystemShutdown

View File

@@ -5,11 +5,11 @@ namespace SystemShutdown {
// --- Enums ---
enum class ShutdownResult {
SUCCESS = 0, // Éxito
ERROR_PERMISSION, // Error de permisos insuficientes
ERROR_SYSTEM_CALL, // Error en la llamada al sistema
ERROR_FORK_FAILED, // Error al crear proceso hijo (Unix)
ERROR_UNSUPPORTED // Sistema operativo no soportado
SUCCESS = 0, // Éxito
ERROR_PERMISSION, // Error de permisos insuficientes
ERROR_SYSTEM_CALL, // Error en la llamada al sistema
ERROR_FORK_FAILED, // Error al crear proceso hijo (Unix)
ERROR_UNSUPPORTED // Sistema operativo no soportado
};
// --- Estructuras ---
@@ -19,9 +19,7 @@ struct ShutdownConfig {
const char* shutdown_message{"El sistema se apagará..."}; // Mensaje mostrado durante el apagado
// Constructor con valores por defecto
ShutdownConfig()
{}
ShutdownConfig() = default;
};
// --- Funciones ---
@@ -32,4 +30,4 @@ auto resultToString(ShutdownResult result) -> const char*;
auto isShutdownSupported() -> bool; // Verifica si el sistema actual soporta apagado programático
auto getRequiredPermissions() -> const char*; // Obtiene información sobre los permisos necesarios
} // namespace SystemShutdown
} // namespace SystemShutdown

View File

@@ -18,7 +18,7 @@ Sprite::Sprite(std::shared_ptr<Texture> texture, SDL_FRect rect)
Sprite::Sprite(std::shared_ptr<Texture> texture)
: textures_{std::move(texture)},
texture_index_(0),
pos_(SDL_FRect{0, 0, static_cast<float>(textures_.at(texture_index_)->getWidth()), static_cast<float>(textures_.at(texture_index_)->getHeight())}),
sprite_clip_(pos_) {}
@@ -41,8 +41,8 @@ void Sprite::setPosition(SDL_FPoint point) {
// Reinicia las variables a cero
void Sprite::clear() {
pos_ = {0, 0, 0, 0};
sprite_clip_ = {0, 0, 0, 0};
pos_ = {.x = 0, .y = 0, .w = 0, .h = 0};
sprite_clip_ = {.x = 0, .y = 0, .w = 0, .h = 0};
}
// Cambia la textura activa por índice

View File

@@ -9,14 +9,14 @@
// --- Enums ---
enum class PowerCollectionState {
ENABLED, // Recolección habilitada
DISABLED // Recolección deshabilitada
ENABLED, // Recolección habilitada
DISABLED // Recolección deshabilitada
};
enum class StageStatus {
LOCKED, // Fase bloqueada
IN_PROGRESS, // Fase en progreso
COMPLETED // Fase completada
LOCKED, // Fase bloqueada
IN_PROGRESS, // Fase en progreso
COMPLETED // Fase completada
};
// --- Clase StageData: representa los datos de una fase del juego ---
@@ -26,11 +26,11 @@ class StageData {
StageData(int power_to_complete, int min_menace, int max_menace, std::string name = ""); // Constructor de una fase
// --- Getters ---
[[nodiscard]] auto getPowerToComplete() const -> int { return power_to_complete_; } // Obtiene el poder necesario para completar
[[nodiscard]] auto getMinMenace() const -> int { return min_menace_; } // Obtiene el nivel mínimo de amenaza
[[nodiscard]] auto getMaxMenace() const -> int { return max_menace_; } // Obtiene el nivel máximo de amenaza
[[nodiscard]] auto getName() const -> const std::string& { return name_; } // Obtiene el nombre de la fase
[[nodiscard]] auto getStatus() const -> StageStatus { return status_; } // Obtiene el estado actual
[[nodiscard]] auto getPowerToComplete() const -> int { return power_to_complete_; } // Obtiene el poder necesario para completar
[[nodiscard]] auto getMinMenace() const -> int { return min_menace_; } // Obtiene el nivel mínimo de amenaza
[[nodiscard]] auto getMaxMenace() const -> int { return max_menace_; } // Obtiene el nivel máximo de amenaza
[[nodiscard]] auto getName() const -> const std::string& { return name_; } // Obtiene el nombre de la fase
[[nodiscard]] auto getStatus() const -> StageStatus { return status_; } // Obtiene el estado actual
[[nodiscard]] auto isCompleted() const -> bool { return status_ == StageStatus::COMPLETED; } // Verifica si está completada
// --- Setters ---
@@ -55,28 +55,28 @@ class StageManager : public IStageInfo {
StageManager(); // Constructor principal
// --- Métodos principales del juego ---
void initialize(); // Inicializa el gestor de fases
void initialize(const std::string& stages_file); // Inicializa con archivo personalizado
void reset(); // Reinicia el progreso del juego
auto advanceToNextStage() -> bool; // Avanza a la siguiente fase
void initialize(); // Inicializa el gestor de fases
void initialize(const std::string& stages_file); // Inicializa con archivo personalizado
void reset(); // Reinicia el progreso del juego
auto advanceToNextStage() -> bool; // Avanza a la siguiente fase
// --- Gestión de poder ---
auto subtractPower(int amount) -> bool; // Resta poder de la fase actual
void enablePowerCollection() override; // Habilita la recolección de poder
void disablePowerCollection(); // Deshabilita la recolección de poder
auto subtractPower(int amount) -> bool; // Resta poder de la fase actual
void enablePowerCollection() override; // Habilita la recolección de poder
void disablePowerCollection(); // Deshabilita la recolección de poder
// --- Navegación ---
auto jumpToStage(size_t target_stage_index) -> bool; // Salta a una fase específica
auto jumpToStage(size_t target_stage_index) -> bool; // Salta a una fase específica
// --- Consultas de estado ---
[[nodiscard]] auto getCurrentStage() const -> std::optional<StageData>; // Obtiene la fase actual
[[nodiscard]] auto getStage(size_t index) const -> std::optional<StageData>; // Obtiene una fase específica
[[nodiscard]] auto getCurrentStage() const -> std::optional<StageData>; // Obtiene la fase actual
[[nodiscard]] auto getStage(size_t index) const -> std::optional<StageData>; // Obtiene una fase específica
[[nodiscard]] auto getCurrentStageIndex() const -> size_t { return current_stage_index_; } // Obtiene el índice de la fase actual
[[nodiscard]] auto getCurrentPower() const -> int { return current_power_; } // Obtiene el poder actual
[[nodiscard]] auto getTotalPower() const -> int { return total_power_; } // Obtiene el poder total acumulado
[[nodiscard]] auto getTotalPowerNeededToCompleteGame() const -> int; // Poder total necesario para completar el juego
[[nodiscard]] auto getPowerNeededToReachStage(size_t target_stage_index) const -> int; // Poder necesario para llegar a la fase X
[[nodiscard]] auto getTotalStages() const -> size_t { return stages_.size(); } // Obtiene el número total de fases
[[nodiscard]] auto getCurrentPower() const -> int { return current_power_; } // Obtiene el poder actual
[[nodiscard]] auto getTotalPower() const -> int { return total_power_; } // Obtiene el poder total acumulado
[[nodiscard]] auto getTotalPowerNeededToCompleteGame() const -> int; // Poder total necesario para completar el juego
[[nodiscard]] auto getPowerNeededToReachStage(size_t target_stage_index) const -> int; // Poder necesario para llegar a la fase X
[[nodiscard]] auto getTotalStages() const -> size_t { return stages_.size(); } // Obtiene el número total de fases
// --- Seguimiento de progreso ---
[[nodiscard]] auto isCurrentStageCompleted() const -> bool; // Verifica si la fase actual está completada
@@ -91,22 +91,22 @@ class StageManager : public IStageInfo {
void removePowerChangeCallback(); // Elimina callback de cambios de poder
// --- Implementación de la interfaz IStageInfo ---
[[nodiscard]] auto canCollectPower() const -> bool override; // Verifica si se puede recolectar poder
void addPower(int amount) override; // Añade poder a la fase actual
[[nodiscard]] auto canCollectPower() const -> bool override; // Verifica si se puede recolectar poder
void addPower(int amount) override; // Añade poder a la fase actual
[[nodiscard]] auto getCurrentMenaceLevel() const -> int override; // Obtiene el nivel de amenaza actual
private:
// --- Variables de estado ---
std::vector<StageData> stages_; // Lista de todas las fases
PowerChangeCallback power_change_callback_; // Callback para notificar cambios de poder
PowerCollectionState power_collection_state_; // Estado de recolección de poder
size_t current_stage_index_; // Índice de la fase actual
int current_power_; // Poder actual en la fase activa
int total_power_; // Poder total acumulado en todo el juego
std::vector<StageData> stages_; // Lista de todas las fases
PowerChangeCallback power_change_callback_; // Callback para notificar cambios de poder
PowerCollectionState power_collection_state_; // Estado de recolección de poder
size_t current_stage_index_; // Índice de la fase actual
int current_power_; // Poder actual en la fase activa
int total_power_; // Poder total acumulado en todo el juego
// --- Métodos internos ---
void createDefaultStages(); // Crea las fases predeterminadas del juego
auto loadStagesFromFile(const std::string& filename) -> bool; // Carga fases desde archivo
void createDefaultStages(); // Crea las fases predeterminadas del juego
auto loadStagesFromFile(const std::string& filename) -> bool; // Carga fases desde archivo
[[nodiscard]] auto validateStageIndex(size_t index) const -> bool; // Valida que un índice de fase sea válido
void updateStageStatuses(); // Actualiza los estados de todas las fases
void updateStageStatuses(); // Actualiza los estados de todas las fases
};

View File

@@ -6,14 +6,14 @@
* sin requerir acceso a toda la funcionalidad de StageManager.
*/
class IStageInfo {
public:
virtual ~IStageInfo() = default;
public:
virtual ~IStageInfo() = default;
// Interfaz de recolección de poder
[[nodiscard]] virtual auto canCollectPower() const -> bool = 0;
virtual void enablePowerCollection() = 0;
virtual void addPower(int amount) = 0;
// Interfaz de recolección de poder
[[nodiscard]] virtual auto canCollectPower() const -> bool = 0;
virtual void enablePowerCollection() = 0;
virtual void addPower(int amount) = 0;
// Ajuste de comportamiento del gameplay
[[nodiscard]] virtual auto getCurrentMenaceLevel() const -> int = 0;
// Ajuste de comportamiento del gameplay
[[nodiscard]] virtual auto getCurrentMenaceLevel() const -> int = 0;
};

View File

@@ -1,27 +1,29 @@
#include "system_utils.h"
#include <iostream>
#include <sys/stat.h>
#include <cerrno>
#include <cstdlib>
#include <iostream>
#ifdef _WIN32
#include <windows.h>
#include <shlobj.h>
#include <direct.h>
// Evitar conflictos con macros de Windows
#ifdef ERROR_ALREADY_EXISTS
#undef ERROR_ALREADY_EXISTS
#endif
#include <direct.h>
#include <shlobj.h>
#include <windows.h>
// Evitar conflictos con macros de Windows
#ifdef ERROR_ALREADY_EXISTS
#undef ERROR_ALREADY_EXISTS
#endif
#else
#include <pwd.h>
#include <unistd.h>
#include <pwd.h>
#include <unistd.h>
#endif
namespace SystemUtils {
// Función auxiliar para crear una carpeta individual
// Función auxiliar para crear una carpeta individual
auto createSingleFolder(const std::string& path, int permissions) -> Result {
struct stat st = {0};
struct stat st = {.st_dev = 0};
// Verificar si ya existe
if (stat(path.c_str(), &st) == 0) {
@@ -31,28 +33,28 @@ auto createSingleFolder(const std::string& path, int permissions) -> Result {
// Intentar crear la carpeta
int result;
#ifdef _WIN32
result = _mkdir(path.c_str());
result = _mkdir(path.c_str());
#else
result = mkdir(path.c_str(), permissions);
result = mkdir(path.c_str(), permissions);
#endif
if (result == -1) {
switch (errno) {
case EACCES:
return Result::PERMISSION_DENIED;
case EEXIST:
return Result::ALREADY_EXISTS;
case ENAMETOOLONG:
return Result::PATH_TOO_LONG;
default:
return Result::UNKNOWN_ERROR;
}
if (result == -1) {
switch (errno) {
case EACCES:
return Result::PERMISSION_DENIED;
case EEXIST:
return Result::ALREADY_EXISTS;
case ENAMETOOLONG:
return Result::PATH_TOO_LONG;
default:
return Result::UNKNOWN_ERROR;
}
}
return Result::SUCCESS;
return Result::SUCCESS;
}
// Función auxiliar para crear carpetas padre recursivamente
// Función auxiliar para crear carpetas padre recursivamente
auto createParentFolders(const std::string& path, int permissions) -> Result {
size_t pos = 0;
@@ -108,29 +110,29 @@ auto createFolder(const std::string& path, const FolderConfig& config) -> Result
auto getApplicationDataPath(const std::string& app_name) -> std::string {
#ifdef _WIN32
char* appdata = getenv("APPDATA");
if (appdata) {
return std::string(appdata) + "/" + app_name;
}
return "C:/Users/Default/AppData/Roaming/" + app_name;
char* appdata = getenv("APPDATA");
if (appdata) {
return std::string(appdata) + "/" + app_name;
}
return "C:/Users/Default/AppData/Roaming/" + app_name;
#elif __APPLE__
std::string home = getHomeDirectory();
return home + "/Library/Application Support/" + app_name;
std::string home = getHomeDirectory();
return home + "/Library/Application Support/" + app_name;
#elif __linux__
std::string home = getHomeDirectory();
return home + "/.config/" + app_name;
std::string home = getHomeDirectory();
return home + "/.config/" + app_name;
#else
// Fallback genérico
std::string home = getHomeDirectory();
return home + "/." + app_name;
// Fallback genérico
std::string home = getHomeDirectory();
return home + "/." + app_name;
#endif
}
auto folderExists(const std::string& path) -> bool {
struct stat st = {0};
struct stat st = {.st_dev = 0};
return (stat(path.c_str(), &st) == 0 && S_ISDIR(st.st_mode));
}
@@ -155,36 +157,36 @@ auto resultToString(Result result) -> const char* {
auto getHomeDirectory() -> std::string {
#ifdef _WIN32
char* userprofile = getenv("USERPROFILE");
if (userprofile) {
return std::string(userprofile);
}
return "C:/Users/Default";
char* userprofile = getenv("USERPROFILE");
if (userprofile) {
return std::string(userprofile);
}
return "C:/Users/Default";
#else
struct passwd *pw = getpwuid(getuid());
if ((pw != nullptr) && (pw->pw_dir != nullptr)) {
return std::string(pw->pw_dir);
}
struct passwd* pw = getpwuid(getuid());
if ((pw != nullptr) && (pw->pw_dir != nullptr)) {
return {pw->pw_dir};
}
// Fallback
char* home = getenv("HOME");
if (home != nullptr) {
return std::string(home);
}
return "/tmp";
// Fallback
char* home = getenv("HOME");
if (home != nullptr) {
return {home};
}
return "/tmp";
#endif
}
auto getTempDirectory() -> std::string {
#ifdef _WIN32
char* temp = getenv("TEMP");
if (temp) {
return std::string(temp);
}
return "C:/Windows/Temp";
char* temp = getenv("TEMP");
if (temp) {
return std::string(temp);
}
return "C:/Windows/Temp";
#else
return "/tmp";
return "/tmp";
#endif
}
} // namespace SystemUtils
} // namespace SystemUtils

View File

@@ -15,15 +15,13 @@ enum class Result { // Códigos de resultado para operaciones del sistema
};
// --- Estructuras ---
struct FolderConfig { // Configuración para creación de carpetas
struct FolderConfig { // Configuración para creación de carpetas
bool create_parents{true}; // Crear carpetas padre si no existen
bool fail_if_exists{false}; // Fallar si la carpeta ya existe
int permissions{0755}; // Permisos Unix (ignorado en Windows)
// Constructor con valores por defecto
FolderConfig()
{}
FolderConfig() = default;
};
// --- Funciones ---

View File

@@ -96,7 +96,7 @@ void Tabe::move() {
? LEFT[rand() % CHOICES]
: RIGHT[rand() % CHOICES];
setRandomFlyPath(DIRECTION, 20 + rand() % 40);
setRandomFlyPath(DIRECTION, 20 + (rand() % 40));
}
}
@@ -125,9 +125,9 @@ void Tabe::enable() {
}
// Establece un vuelo aleatorio
void Tabe::setRandomFlyPath(Direction direction, int lenght) {
void Tabe::setRandomFlyPath(Direction direction, int length) {
direction_ = direction;
fly_distance_ = lenght;
fly_distance_ = length;
waiting_counter_ = 5 + rand() % 15;
Audio::get()->playSound("tabe.wav");

View File

@@ -129,7 +129,7 @@ class Tabe {
// --- Métodos internos ---
void move(); // Mueve el objeto
void shiftSprite() { sprite_->setPos(x_, y_); } // Actualiza la posición del sprite
void setRandomFlyPath(Direction direction, int lenght); // Establece un vuelo aleatorio
void setRandomFlyPath(Direction direction, int length); // Establece un vuelo aleatorio
void updateState(); // Actualiza el estado
void updateTimer(); // Actualiza el temporizador
void disable(); // Deshabilita el objeto

View File

@@ -57,18 +57,18 @@ class Text {
~Text() = default;
// --- Métodos de escritura en pantalla ---
void write(int x, int y, const std::string &text, int kerning = 1, int lenght = -1); // Escribe el texto en pantalla
void write(int x, int y, const std::string &text, int kerning = 1, int length = -1); // Escribe el texto en pantalla
void write2X(int x, int y, const std::string &text, int kerning = 1, int length = -1); // Escribe el texto al doble de tamaño
// --- Escritura en textura ---
auto writeToTexture(const std::string &text, int zoom = 1, int kerning = 1, int lenght = -1) -> std::shared_ptr<Texture>; // Escribe el texto en una textura
auto writeDXToTexture(Uint8 flags, const std::string &text, int kerning = 1, Color text_color = Color(), Uint8 shadow_distance = 1, Color shadow_color = Color(), int lenght = -1) -> std::shared_ptr<Texture>; // Escribe el texto con extras en una textura
auto writeToTexture(const std::string &text, int zoom = 1, int kerning = 1, int length = -1) -> std::shared_ptr<Texture>; // Escribe el texto en una textura
auto writeDXToTexture(Uint8 flags, const std::string &text, int kerning = 1, Color text_color = Color(), Uint8 shadow_distance = 1, Color shadow_color = Color(), int length = -1) -> std::shared_ptr<Texture>; // Escribe el texto con extras en una textura
// --- Métodos de escritura avanzada ---
void writeColored(int x, int y, const std::string &text, Color color, int kerning = 1, int lenght = -1); // Escribe el texto con colores
void writeShadowed(int x, int y, const std::string &text, Color color, Uint8 shadow_distance = 1, int kerning = 1, int lenght = -1); // Escribe el texto con sombra
void writeCentered(int x, int y, const std::string &text, int kerning = 1, int lenght = -1); // Escribe el texto centrado en un punto x
void writeDX(Uint8 flags, int x, int y, const std::string &text, int kerning = 1, Color text_color = Color(), Uint8 shadow_distance = 1, Color shadow_color = Color(), int lenght = -1); // Escribe texto con extras
void writeColored(int x, int y, const std::string &text, Color color, int kerning = 1, int length = -1); // Escribe el texto con colores
void writeShadowed(int x, int y, const std::string &text, Color color, Uint8 shadow_distance = 1, int kerning = 1, int length = -1); // Escribe el texto con sombra
void writeCentered(int x, int y, const std::string &text, int kerning = 1, int length = -1); // Escribe el texto centrado en un punto x
void writeDX(Uint8 flags, int x, int y, const std::string &text, int kerning = 1, Color text_color = Color(), Uint8 shadow_distance = 1, Color shadow_color = Color(), int length = -1); // Escribe texto con extras
void writeStyle(int x, int y, const std::string &text, const Style &style, int length = -1); // Escribe texto a partir de un TextStyle
// --- Utilidades ---

View File

@@ -38,7 +38,7 @@ class Texture {
// --- Renderizado ---
void render(int x, int y, SDL_FRect *clip = nullptr, float horizontal_zoom = 1, float vertical_zoom = 1, double angle = 0.0, SDL_FPoint *center = nullptr, SDL_FlipMode flip = SDL_FLIP_NONE); // Renderiza la textura en un punto específico
void setAsRenderTarget(SDL_Renderer *renderer); // Establece la textura como objetivo de renderizado
void setAsRenderTarget(SDL_Renderer *renderer); // Establece la textura como objetivo de renderizado
// --- Modificadores de color y blending ---
void setColor(Uint8 red, Uint8 green, Uint8 blue); // Establece el color para la modulación

View File

@@ -2,6 +2,7 @@
#include <SDL3/SDL.h> // Para SDL_SetRenderTarget, SDL_CreateTexture, SDL_DestroyTexture, SDL_FRect, SDL_GetRenderTarget, SDL_RenderTexture, SDL_PixelFormat, SDL_TextureAccess
#include <algorithm>
#include <cmath> // Para sin
#include <cstdlib> // Para rand
#include <memory> // Para allocator, unique_ptr, make_unique
@@ -25,17 +26,17 @@ TiledBG::TiledBG(SDL_FRect pos, TiledBGMode mode)
// Inicializa variables
switch (mode_) {
case TiledBGMode::STATIC:
window_ = {0, 0, pos_.w, pos_.h};
window_ = {.x = 0, .y = 0, .w = pos_.w, .h = pos_.h};
speed_ = 0.0F;
break;
case TiledBGMode::DIAGONAL:
window_ = {0, 0, pos_.w, pos_.h};
window_ = {.x = 0, .y = 0, .w = pos_.w, .h = pos_.h};
break;
case TiledBGMode::CIRCLE:
window_ = {128, 128, pos_.w, pos_.h};
window_ = {.x = 128, .y = 128, .w = pos_.w, .h = pos_.h};
break;
default:
window_ = {0, 0, pos_.w, pos_.h};
window_ = {.x = 0, .y = 0, .w = pos_.w, .h = pos_.h};
break;
}
@@ -116,9 +117,7 @@ void TiledBG::updateStop() {
speed_ /= 1.05F; // Reduce gradualmente la velocidad
// Asegura que no baje demasiado
if (speed_ < 0.1F) {
speed_ = 0.1F;
}
speed_ = std::max(speed_, 0.1F);
}
// Si estamos en 0, detener

View File

@@ -22,9 +22,7 @@ auto ActionListOption::getMaxValueWidth(Text* text) const -> int {
int max_width = 0;
for (const auto& option : options_) {
int width = text->length(option, -2);
if (width > max_width) {
max_width = width;
}
max_width = std::max(width, max_width);
}
return max_width;
}
@@ -66,7 +64,7 @@ auto ActionListOption::findCurrentIndex() const -> size_t {
}
const std::string CURRENT_VALUE = value_getter_();
auto it = std::find(options_.begin(), options_.end(), CURRENT_VALUE);
auto it = std::ranges::find(options_, CURRENT_VALUE);
if (it != options_.end()) {
return static_cast<size_t>(std::distance(options_.begin(), it));

View File

@@ -75,7 +75,7 @@ void MenuRenderer::render(const ServiceMenu *menu_state) {
if (shouldShowContent()) {
// Dibuja el título
float y = rect_.y + title_padding_;
title_text_->writeDX(Text::COLOR | Text::CENTER, rect_.x + rect_.w / 2.0F, y, menu_state->getTitle(), -4, param.service_menu.title_color);
title_text_->writeDX(Text::COLOR | Text::CENTER, rect_.x + (rect_.w / 2.0F), y, menu_state->getTitle(), -4, param.service_menu.title_color);
// Dibuja la línea separadora
y = rect_.y + upper_height_;
@@ -99,7 +99,7 @@ void MenuRenderer::render(const ServiceMenu *menu_state) {
} else {
const int AVAILABLE_WIDTH = rect_.w - (ServiceMenu::OPTIONS_HORIZONTAL_PADDING * 2);
std::string truncated_caption = getTruncatedValue(option_pairs.at(i).first, AVAILABLE_WIDTH);
element_text_->writeDX(Text::CENTER | Text::COLOR, rect_.x + rect_.w / 2.0F, y, truncated_caption, -2, current_color);
element_text_->writeDX(Text::CENTER | Text::COLOR, rect_.x + (rect_.w / 2.0F), y, truncated_caption, -2, current_color);
}
y += options_height_ + options_padding_;
}
@@ -232,7 +232,7 @@ void MenuRenderer::setSize(const ServiceMenu *menu_state) {
updatePosition();
options_y_ = rect_.y + upper_height_ + lower_padding_;
border_rect_ = {rect_.x - 1, rect_.y + 1, rect_.w + 2, rect_.h - 2};
border_rect_ = {.x = rect_.x - 1, .y = rect_.y + 1, .w = rect_.w + 2, .h = rect_.h - 2};
}
// --- Métodos de animación y posición ---
@@ -305,7 +305,7 @@ void MenuRenderer::updatePosition() {
break;
}
// Actualizar el rectángulo del borde junto con el principal
border_rect_ = {rect_.x - 1, rect_.y + 1, rect_.w + 2, rect_.h - 2};
border_rect_ = {.x = rect_.x - 1, .y = rect_.y + 1, .w = rect_.w + 2, .h = rect_.h - 2};
}
// Resto de métodos (sin cambios significativos)
@@ -349,7 +349,7 @@ auto MenuRenderer::getAnimatedSelectedColor() const -> Color {
return color_cycle_.at(color_counter_ % color_cycle_.size());
}
auto MenuRenderer::setRect(SDL_FRect rect) -> SDL_FRect {
border_rect_ = {rect.x - 1, rect.y + 1, rect.w + 2, rect.h - 2};
border_rect_ = {.x = rect.x - 1, .y = rect.y + 1, .w = rect.w + 2, .h = rect.h - 2};
return rect;
}
auto MenuRenderer::getTruncatedValueWidth(const std::string &value, int available_width) const -> int {
@@ -404,5 +404,5 @@ auto MenuRenderer::getTruncatedValue(const std::string &value, int available_wid
return truncated;
}
auto MenuRenderer::easeOut(float t) -> float { return 1.0F - (1.0F - t) * (1.0F - t); }
auto MenuRenderer::easeOut(float t) -> float { return 1.0F - ((1.0F - t) * (1.0F - t)); }
auto MenuRenderer::shouldShowContent() const -> bool { return !show_hide_animation_.active; }

View File

@@ -164,8 +164,7 @@ void Notifier::show(std::vector<std::string> texts, int icon, const std::string&
}
// Elimina las cadenas vacías
texts.erase(std::remove_if(texts.begin(), texts.end(), [](const std::string& s) { return s.empty(); }),
texts.end());
texts.erase(std::ranges::remove_if(texts, [](const std::string& s) { return s.empty(); }).begin(), texts.end());
// Encuentra la cadena más larga
std::string longest;
@@ -224,7 +223,7 @@ void Notifier::show(std::vector<std::string> texts, int icon, const std::string&
n.texts = texts;
n.shape = SHAPE;
const float POS_Y = offset + (param.notification.pos_v == Position::TOP ? -TRAVEL_DIST : TRAVEL_DIST);
n.rect = {desp_h, POS_Y, WIDTH, HEIGHT};
n.rect = {.x = desp_h, .y = POS_Y, .w = WIDTH, .h = HEIGHT};
// Crea la textura
n.texture = std::make_shared<Texture>(renderer_);
@@ -238,16 +237,16 @@ void Notifier::show(std::vector<std::string> texts, int icon, const std::string&
SDL_SetRenderDrawColor(renderer_, bg_color_.r, bg_color_.g, bg_color_.b, 255);
SDL_FRect rect;
if (SHAPE == Shape::ROUNDED) {
rect = {4, 0, WIDTH - (4 * 2), HEIGHT};
rect = {.x = 4, .y = 0, .w = WIDTH - (4 * 2), .h = HEIGHT};
SDL_RenderFillRect(renderer_, &rect);
rect = {4 / 2, 1, WIDTH - 4, HEIGHT - 2};
rect = {.x = 4 / 2, .y = 1, .w = WIDTH - 4, .h = HEIGHT - 2};
SDL_RenderFillRect(renderer_, &rect);
rect = {1, 4 / 2, WIDTH - 2, HEIGHT - 4};
rect = {.x = 1, .y = 4 / 2, .w = WIDTH - 2, .h = HEIGHT - 4};
SDL_RenderFillRect(renderer_, &rect);
rect = {0, 4, WIDTH, HEIGHT - (4 * 2)};
rect = {.x = 0, .y = 4, .w = WIDTH, .h = HEIGHT - (4 * 2)};
SDL_RenderFillRect(renderer_, &rect);
}
@@ -271,7 +270,7 @@ void Notifier::show(std::vector<std::string> texts, int icon, const std::string&
const Color COLOR{255, 255, 255};
int iterator = 0;
for (const auto& text : texts) {
text_->writeColored(PADDING_IN_H + ICON_SPACE, PADDING_IN_V + iterator * (text_->getCharacterSize() + 1), text, COLOR);
text_->writeColored(PADDING_IN_H + ICON_SPACE, PADDING_IN_V + (iterator * (text_->getCharacterSize() + 1)), text, COLOR);
++iterator;
}

View File

@@ -99,7 +99,7 @@ class Notifier {
// --- Constructores y destructor privados (singleton) ---
Notifier(const std::string &icon_file, std::shared_ptr<Text> text); // Constructor privado
~Notifier() = default; // Destructor privado
~Notifier() = default; // Destructor privado
// --- Instancia singleton ---
static Notifier *instance; // Instancia única de Notifier

View File

@@ -43,7 +43,7 @@ void WindowMessage::render() {
std::string visible_title = getTruncatedText(title_, available_width);
if (!visible_title.empty()) {
text_renderer_->writeStyle(
rect_.x + rect_.w / 2.0F,
rect_.x + (rect_.w / 2.0F),
current_y,
visible_title,
title_style_);
@@ -55,9 +55,9 @@ void WindowMessage::render() {
SDL_SetRenderDrawColor(renderer, config_.border_color.r, config_.border_color.g, config_.border_color.b, config_.border_color.a);
SDL_RenderLine(renderer,
rect_.x + config_.padding,
current_y - config_.title_separator_spacing / 2.0F,
current_y - (config_.title_separator_spacing / 2.0F),
rect_.x + rect_.w - config_.padding,
current_y - config_.title_separator_spacing / 2.0F);
current_y - (config_.title_separator_spacing / 2.0F));
}
}
@@ -66,7 +66,7 @@ void WindowMessage::render() {
std::string visible_text = getTruncatedText(text, available_width);
if (!visible_text.empty()) {
text_renderer_->writeStyle(
rect_.x + rect_.w / 2.0F,
rect_.x + (rect_.w / 2.0F),
current_y,
visible_text,
text_style_);
@@ -147,7 +147,7 @@ void WindowMessage::clearTexts() {
}
void WindowMessage::setPosition(float x, float y, PositionMode mode) {
anchor_ = {x, y};
anchor_ = {.x = x, .y = y};
position_mode_ = mode;
updatePosition();
}
@@ -373,7 +373,7 @@ auto WindowMessage::shouldShowContent() const -> bool {
auto WindowMessage::easeOut(float t) -> float {
// Función de suavizado ease-out cuadrática
return 1.0F - (1.0F - t) * (1.0F - t);
return 1.0F - ((1.0F - t) * (1.0F - t));
}
auto WindowMessage::getAvailableTextWidth() const -> float {

View File

@@ -8,8 +8,9 @@
#include <cmath> // Para pow, sin, M_PI, cos, sqrt
#include <compare> // Para operator<, __synth3way_t
#include <filesystem> // Para path
#include <stdexcept> // Para runtime_error
#include <string> // Para basic_string, allocator, string, operator==, operator+, char_traits
#include <ranges>
#include <stdexcept> // Para runtime_error
#include <string> // Para basic_string, allocator, string, operator==, operator+, char_traits
#include "lang.h" // Para getText
@@ -20,14 +21,14 @@ Overrides overrides = Overrides();
auto distanceSquared(int x1, int y1, int x2, int y2) -> double {
const int DELTA_X = x2 - x1;
const int DELTA_Y = y2 - y1;
return DELTA_X * DELTA_X + DELTA_Y * DELTA_Y;
return (DELTA_X * DELTA_X) + (DELTA_Y * DELTA_Y);
}
// Obtiene el punto de colisión entre dos circulos
auto getCollisionPoint(const Circle &a, const Circle &b) -> SDL_FPoint {
float dx = b.x - a.x;
float dy = b.y - a.y;
float dist = std::sqrt(dx * dx + dy * dy);
float dist = std::sqrt((dx * dx) + (dy * dy));
// Normaliza el vector
float nx = dx / dist;
@@ -117,7 +118,7 @@ auto boolToOnOff(bool value) -> std::string {
// Convierte una cadena a minusculas
auto toLower(const std::string &str) -> std::string {
std::string result = str;
std::transform(result.begin(), result.end(), result.begin(), [](unsigned char c) { return std::tolower(c); });
std::ranges::transform(result, result.begin(), [](unsigned char c) { return std::tolower(c); });
return result;
}
@@ -158,8 +159,8 @@ void drawCircle(SDL_Renderer *renderer, int32_t center_x, int32_t center_y, int3
// Quita los espacioes en un string
auto trim(const std::string &str) -> std::string {
auto start = std::find_if_not(str.begin(), str.end(), ::isspace);
auto end = std::find_if_not(str.rbegin(), str.rend(), ::isspace).base();
auto start = std::ranges::find_if_not(str, ::isspace);
auto end = std::ranges::find_if_not(std::ranges::reverse_view(str), ::isspace).base();
return (start < end ? std::string(start, end) : std::string());
}
@@ -175,7 +176,7 @@ auto easeInQuint(double time) -> double {
// Función de suavizado
auto easeInOutQuint(double time) -> double {
return time < 0.5 ? 16 * pow(time, 5) : 1 - pow(-2 * time + 2, 5) / 2;
return time < 0.5 ? 16 * pow(time, 5) : 1 - (pow((-2 * time) + 2, 5) / 2);
}
// Función de suavizado
@@ -185,7 +186,7 @@ auto easeInQuad(double time) -> double {
// Función de suavizado
auto easeOutQuad(double time) -> double {
return 1 - (1 - time) * (1 - time);
return 1 - ((1 - time) * (1 - time));
}
// Función de suavizado
@@ -195,7 +196,7 @@ auto easeInOutSine(double time) -> double {
// Función de suavizado
auto easeInOut(double time) -> double {
return time < 0.5 ? 2 * time * time : -1 + (4 - 2 * time) * time;
return time < 0.5 ? 2 * time * time : -1 + ((4 - 2 * time) * time);
}
// Función de suavizado (easeInOutExpo)
@@ -209,10 +210,10 @@ auto easeInOutExpo(double time) -> double {
}
if (time < 0.5) {
return pow(2, 20 * time - 10) / 2;
return pow(2, (20 * time) - 10) / 2;
}
return (2 - pow(2, -20 * time + 10)) / 2;
return (2 - pow(2, (-20 * time) + 10)) / 2;
}
// Función de suavizado (easeInElastic)
@@ -226,7 +227,7 @@ auto easeInElastic(double time) -> double {
}
const double C4 = (2 * M_PI) / 3;
return -pow(2, 10 * time - 10) * sin((time * 10 - 10.75) * C4);
return -pow(2, (10 * time) - 10) * sin((time * 10 - 10.75) * C4);
}
// Función de suavizado
@@ -236,14 +237,14 @@ auto easeOutBounce(double time) -> double {
}
if (time < 2 / 2.75) {
time -= 1.5 / 2.75;
return 7.5625 * time * time + 0.75;
return (7.5625 * time * time) + 0.75;
}
if (time < 2.5 / 2.75) {
time -= 2.25 / 2.75;
return 7.5625 * time * time + 0.9375;
return (7.5625 * time * time) + 0.9375;
}
time -= 2.625 / 2.75;
return 7.5625 * time * time + 0.984375;
return (7.5625 * time * time) + 0.984375;
}
// Función de suavizado (easeOutElastic)
@@ -257,7 +258,7 @@ auto easeOutElastic(double time) -> double {
}
const double C4 = (2 * M_PI) / 3; // Constante para controlar la elasticidad
return pow(2, -10 * time) * sin((time * 10 - 0.75) * C4) + 1;
return (pow(2, -10 * time) * sin((time * 10 - 0.75) * C4)) + 1;
}
// Ease Out Expo - Muy suave al final (más dramático)
@@ -274,7 +275,7 @@ auto easeInExpo(double time) -> double {
auto easeOutBack(double time) -> double {
const double C1 = 1.70158F;
const double C3 = C1 + 1.0F;
return 1.0F + C3 * pow(time - 1.0F, 3.0F) + C1 * pow(time - 1.0F, 2.0F);
return 1.0F + (C3 * pow(time - 1.0F, 3.0F)) + (C1 * pow(time - 1.0F, 2.0F));
}
// Ease Out Cubic - Desaceleración suave al final
@@ -289,7 +290,7 @@ auto easeInCubic(double time) -> double {
// Comprueba si una vector contiene una cadena
auto stringInVector(const std::vector<std::string> &vec, const std::string &str) -> bool {
return std::find(vec.begin(), vec.end(), str) != vec.end();
return std::ranges::find(vec, str) != vec.end();
}
// Imprime por pantalla una línea de texto de tamaño fijo rellena con puntos
@@ -389,7 +390,8 @@ auto truncateWithEllipsis(const std::string &input, size_t length) -> std::strin
return input;
}
if (length <= 3) {
return std::string(length, '.');
std::string result(length, '.');
return result;
}
return input.substr(0, length) + "...";
}

View File

@@ -14,7 +14,7 @@ void Writer::update() {
writing_counter_ = speed_;
}
if (index_ == lenght_) {
if (index_ == length_) {
completed_ = true;
}
} else {
@@ -52,7 +52,7 @@ void Writer::setKerning(int value) {
// Establece el valor de la variable
void Writer::setCaption(const std::string &text) {
caption_ = text;
lenght_ = text.length();
length_ = text.length();
}
// Establece el valor de la variable

View File

@@ -45,7 +45,7 @@ class Writer {
int speed_ = 0; // Velocidad de escritura
int writing_counter_ = 0; // Temporizador de escritura para cada caracter
int index_ = 0; // Posición del texto que se está escribiendo
int lenght_ = 0; // Longitud de la cadena a escribir
int length_ = 0; // Longitud de la cadena a escribir
int enabled_counter_ = 0; // Temporizador para deshabilitar el objeto
bool completed_ = false; // Indica si se ha escrito todo el texto
bool enabled_ = false; // Indica si el objeto está habilitado