This commit is contained in:
2025-10-19 22:01:31 +02:00
parent 16306f2325
commit 2b4523d644
101 changed files with 2058 additions and 1564 deletions

View File

@@ -2,17 +2,16 @@
#include <SDL3/SDL.h> // Para SDL_LogWarn, SDL_LogCategory, SDL_LogError, SDL_FRect
#include <algorithm> // Para min, max
#include <algorithm> // Para min
#include <cstddef> // Para size_t
#include <fstream> // Para basic_istream, basic_ifstream, basic_ios, ifstream, stringstream
#include <sstream> // Para basic_stringstream
#include <fstream> // Para basic_istream, basic_ifstream, istream, basic_ios, ifstream, istringstream, stringstream
#include <sstream> // Para basic_istringstream, basic_stringstream
#include <stdexcept> // Para runtime_error
#include <utility> // Para pair
#include <utility> // Para move, pair
#include "resource_helper.hpp" // Para ResourceHelper
#include "resource_helper.hpp" // Para loadFile
#include "texture.hpp" // Para Texture
#include "utils.hpp" // Para printWithDots
#include "ui/logger.hpp"
#include "ui/logger.hpp" // Para dots
// Carga las animaciones en un vector(Animations) desde un fichero
auto loadAnimationsFromFile(const std::string& file_path) -> AnimationsFileBuffer {
@@ -88,13 +87,13 @@ auto AnimatedSprite::getAnimationIndex(const std::string& name) -> int {
}
// Calcula el frame correspondiente a la animación (time-based)
void AnimatedSprite::animate(float deltaTime) {
void AnimatedSprite::animate(float delta_time) {
if (animations_[current_animation_].speed == 0 || animations_[current_animation_].paused) {
return;
}
// Acumular tiempo transcurrido
animations_[current_animation_].time_accumulator += deltaTime;
animations_[current_animation_].time_accumulator += delta_time;
// Verificar si es momento de cambiar frame
if (animations_[current_animation_].time_accumulator >= animations_[current_animation_].speed) {
@@ -107,7 +106,7 @@ void AnimatedSprite::animate(float deltaTime) {
animations_[current_animation_].current_frame = animations_[current_animation_].frames.size() - 1;
animations_[current_animation_].completed = true;
} else { // Si hay loop, vuelve al frame indicado
animations_[current_animation_].time_accumulator = 0.0f;
animations_[current_animation_].time_accumulator = 0.0F;
animations_[current_animation_].current_frame = animations_[current_animation_].loop;
}
}
@@ -130,7 +129,7 @@ void AnimatedSprite::setCurrentAnimation(const std::string& name, bool reset) {
current_animation_ = NEW_ANIMATION;
if (reset) {
animations_[current_animation_].current_frame = 0;
animations_[current_animation_].time_accumulator = 0.0f;
animations_[current_animation_].time_accumulator = 0.0F;
animations_[current_animation_].completed = false;
} else {
animations_[current_animation_].current_frame = std::min(animations_[OLD_ANIMATION].current_frame, animations_[current_animation_].frames.size() - 1);
@@ -149,7 +148,7 @@ void AnimatedSprite::setCurrentAnimation(int index, bool reset) {
current_animation_ = NEW_ANIMATION;
if (reset) {
animations_[current_animation_].current_frame = 0;
animations_[current_animation_].time_accumulator = 0.0f;
animations_[current_animation_].time_accumulator = 0.0F;
animations_[current_animation_].completed = false;
} else {
animations_[current_animation_].current_frame = std::min(animations_[OLD_ANIMATION].current_frame, animations_[current_animation_].frames.size());
@@ -161,15 +160,15 @@ void AnimatedSprite::setCurrentAnimation(int index, bool reset) {
}
// Actualiza las variables del objeto (time-based)
void AnimatedSprite::update(float deltaTime) {
animate(deltaTime);
MovingSprite::update(deltaTime);
void AnimatedSprite::update(float delta_time) {
animate(delta_time);
MovingSprite::update(delta_time);
}
// Reinicia la animación
void AnimatedSprite::resetAnimation() {
animations_[current_animation_].current_frame = 0;
animations_[current_animation_].time_accumulator = 0.0f;
animations_[current_animation_].time_accumulator = 0.0F;
animations_[current_animation_].completed = false;
animations_[current_animation_].paused = false;
updateSpriteClip();

View File

@@ -2,15 +2,14 @@
#include <SDL3/SDL.h> // Para SDL_FRect
#include <algorithm> // Para max
#include <cstddef> // Para size_t
#include <memory> // Para allocator, shared_ptr
#include <string> // Para string, hash
#include <memory> // Para shared_ptr
#include <string> // Para basic_string, string, hash
#include <unordered_map> // Para unordered_map
#include <utility>
#include <vector> // Para vector
#include <utility> // Para move
#include <vector> // Para vector
#include "moving_sprite.hpp" // Para MovingSprite
#include "moving_sprite.hpp" // for MovingSprite
// Declaración adelantada
class Texture;
@@ -25,7 +24,7 @@ struct Animation {
int loop{0}; // Frame de vuelta al terminar (-1 para no repetir)
bool completed{false}; // Indica si la animación ha finalizado
size_t current_frame{0}; // Frame actual en reproducción
float time_accumulator{0.0f}; // Acumulador de tiempo para animaciones time-based
float time_accumulator{0.0F}; // Acumulador de tiempo para animaciones time-based
bool paused{false}; // La animación no avanza
Animation() = default;
@@ -55,7 +54,7 @@ class AnimatedSprite : public MovingSprite {
~AnimatedSprite() override = default;
// --- Métodos principales ---
void update(float deltaTime) override; // Actualiza la animación (time-based)
void update(float delta_time) override; // Actualiza la animación (time-based)
// --- Control de animaciones ---
void setCurrentAnimation(const std::string& name = "default", bool reset = true); // Establece la animación por nombre
@@ -78,7 +77,7 @@ class AnimatedSprite : public MovingSprite {
int current_animation_ = 0; // Índice de la animación activa
// --- Métodos internos ---
void animate(float deltaTime); // Calcula el frame correspondiente a la animación (time-based)
void animate(float delta_time); // Calcula el frame correspondiente a la animación (time-based)
void loadFromAnimationsFileBuffer(const AnimationsFileBuffer& source); // Carga la animación desde un vector de cadenas
void processConfigLine(const std::string& line, AnimationConfig& config); // Procesa una línea de configuración
void updateFrameCalculations(AnimationConfig& config); // Actualiza los cálculos basados en las dimensiones del frame

View File

@@ -1,17 +1,18 @@
#include "asset.hpp"
#include <SDL3/SDL.h> // Para SDL_LogCategory, SDL_LogInfo, SDL_LogError, SDL_LogWarn
#include <SDL3/SDL.h> // Para SDL_LogWarn, SDL_LogCategory, SDL_LogError
#include <algorithm> // Para std::sort
#include <algorithm> // Para sort
#include <cstddef> // Para size_t
#include <exception> // Para exception
#include <filesystem> // Para std::filesystem
#include <fstream> // Para basic_istream, basic_ifstream, ifstream, istringstream
#include <filesystem> // Para exists, path
#include <fstream> // Para basic_ifstream, basic_istream, basic_ostream, operator<<, ifstream, istringstream, endl
#include <iostream> // Para cout
#include <sstream> // Para basic_istringstream
#include <stdexcept> // Para runtime_error
#include "resource_helper.hpp" // Para ResourceHelper
#include "ui/logger.hpp" // Pâra Logger
#include "resource_helper.hpp" // Para loadFile
#include "ui/logger.hpp" // Para info, section, CYAN
#include "utils.hpp" // Para getFileName
// Singleton
@@ -124,7 +125,7 @@ void Asset::loadFromFile(const std::string& config_file_path, const std::string&
}
}
std::cout << "Loaded " << file_list_.size() << " assets from config file" << std::endl;
std::cout << "Loaded " << file_list_.size() << " assets from config file" << '\n';
file.close();
}
@@ -204,20 +205,18 @@ auto Asset::checkFile(const std::string& path) const -> bool {
// MODO PACK: Usar ResourceHelper (igual que la carga real)
auto data = ResourceHelper::loadFile(path);
return !data.empty();
} else {
// MODO FILESYSTEM: Verificación directa (modo desarrollo)
std::ifstream file(path);
bool success = file.good();
file.close();
} // MODO FILESYSTEM: Verificación directa (modo desarrollo)
std::ifstream file(path);
bool success = file.good();
file.close();
if (!success) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
"Error: Could not open file: %s",
path.c_str());
}
return success;
if (!success) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
"Error: Could not open file: %s",
path.c_str());
}
return success;
}
// Parsea string a Type
@@ -290,7 +289,7 @@ auto Asset::getListByType(Type type) const -> std::vector<std::string> {
}
// Ordenar alfabéticamente para garantizar orden consistente
std::sort(list.begin(), list.end());
std::ranges::sort(list);
return list;
}

View File

@@ -13,17 +13,17 @@ class AssetIntegrated : public Asset {
const std::string& resource_pack_path = "resources.pack");
// Carga un archivo usando ResourceLoader como primera opción
std::vector<uint8_t> loadFile(const std::string& filename);
auto loadFile(const std::string& filename) -> std::vector<uint8_t>;
// Verifica si un archivo existe (pack o filesystem)
bool fileExists(const std::string& filename) const;
auto fileExists(const std::string& filename) const -> bool;
// Obtiene la ruta completa para archivos del sistema/config
std::string getSystemPath(const std::string& filename) const;
auto getSystemPath(const std::string& filename) const -> std::string;
private:
static bool resource_pack_enabled_;
static bool resource_pack_enabled;
// Determina si un archivo debe cargarse del pack o del filesystem
bool shouldUseResourcePack(const std::string& filepath) const;
auto shouldUseResourcePack(const std::string& filepath) const -> bool;
};

View File

@@ -7,7 +7,7 @@
#include "external/jail_audio.h" // Para JA_FadeOutMusic, JA_Init, JA_PauseM...
#include "options.hpp" // Para AudioOptions, audio, MusicOptions
#include "resource.hpp" // Para Resource
#include "ui/logger.hpp" // Para logger
#include "ui/logger.hpp" // Para logger
// Singleton
Audio* Audio::instance = nullptr;
@@ -91,7 +91,7 @@ void Audio::fadeOutMusic(int milliseconds) const {
}
// Consulta directamente el estado real de la música en jailaudio
auto Audio::getRealMusicState() const -> MusicState {
auto Audio::getRealMusicState() -> MusicState {
JA_Music_state ja_state = JA_GetMusicState();
switch (ja_state) {
case JA_MUSIC_PLAYING:

View File

@@ -67,12 +67,12 @@ class Audio {
void setMusicVolume(int volume) const; // Ajustar volumen de música
// --- Getters para debug ---
bool isEnabled() const { return enabled_; }
bool isSoundEnabled() const { return sound_enabled_; }
bool isMusicEnabled() const { return music_enabled_; }
MusicState getMusicState() const { return music_.state; }
MusicState getRealMusicState() const; // Consulta directamente a jailaudio
const std::string& getCurrentMusicName() const { return music_.name; }
[[nodiscard]] auto isEnabled() const -> bool { return enabled_; }
[[nodiscard]] auto isSoundEnabled() const -> bool { return sound_enabled_; }
[[nodiscard]] auto isMusicEnabled() const -> bool { return music_enabled_; }
[[nodiscard]] auto getMusicState() const -> MusicState { return music_.state; }
[[nodiscard]] static auto getRealMusicState() -> MusicState; // Consulta directamente a jailaudio
[[nodiscard]] auto getCurrentMusicName() const -> const std::string& { return music_.name; }
private:
// --- Estructuras privadas ---

View File

@@ -3,18 +3,19 @@
#include <SDL3/SDL.h> // Para SDL_FRect, SDL_SetRenderTarget, SDL_CreateTexture, SDL_DestroyTexture, SDL_GetRenderTarget, SDL_RenderTexture, SDL_SetTextureAlphaMod, SDL_SetTextureBlendMode, SDL_BLENDMODE_BLEND, SDL_PixelFormat, SDL_RenderClear, SDL_SetRenderDrawColor, SDL_TextureAccess, SDL_FPoint
#include <algorithm> // Para clamp, max
#include <algorithm> // Para clamp, min, max
#include <cmath> // Para M_PI, cos, sin
#include <utility>
#include <string> // Para basic_string
#include <utility> // Para move
#include "animated_sprite.hpp" // Para MovingSprite
#include "animated_sprite.hpp" // Para AnimatedSprite
#include "moving_sprite.hpp" // Para MovingSprite
#include "param.hpp" // Para Param, ParamBackground, param
#include "resource.hpp" // Para Resource
#include "screen.hpp" // Para Screen
#include "sprite.hpp" // Para Sprite
#include "texture.hpp" // Para Texture
#include "utils.hpp" // Para funciones de easing
#include "utils.hpp" // Para easeOutCubic
// Constructor
Background::Background(float total_progress_to_complete)
@@ -191,7 +192,7 @@ void Background::setState(State new_state) {
// Si entra en estado completado, inicializar variables de transición
if (new_state == State::COMPLETED && state_ != State::COMPLETED) {
completion_initial_progress_ = progress_;
completion_transition_timer_ = 0.0f;
completion_transition_timer_ = 0.0F;
}
state_ = new_state;
@@ -209,8 +210,8 @@ void Background::reset() {
moon_index_ = 0;
// Resetear variables de transición de completado
completion_transition_timer_ = 0.0f;
completion_initial_progress_ = 0.0f;
completion_transition_timer_ = 0.0F;
completion_initial_progress_ = 0.0F;
// Notifica el cambio si hay callback
if (progress_callback_ && progress_ != old_progress) {
@@ -274,9 +275,9 @@ void Background::updateProgression(float delta_time) {
completion_transition_timer_ += delta_time;
// Calcular progreso normalizado de la transición (0.0 a 1.0)
float t = std::min(completion_transition_timer_ / COMPLETION_TRANSITION_DURATION_S, 1.0f);
float t = std::min(completion_transition_timer_ / COMPLETION_TRANSITION_DURATION_S, 1.0F);
if (t < 1.0f) {
if (t < 1.0F) {
// Usar easeOutCubic para transición suave (rápido al inicio, lento al final)
float eased_t = easeOutCubic(static_cast<double>(t));
@@ -342,12 +343,12 @@ void Background::updateCloudsSpeed() {
}
// Actualiza las nubes
void Background::updateClouds(float deltaTime) {
void Background::updateClouds(float delta_time) {
// Mueve las nubes
top_clouds_sprite_a_->update(deltaTime);
top_clouds_sprite_b_->update(deltaTime);
bottom_clouds_sprite_a_->update(deltaTime);
bottom_clouds_sprite_b_->update(deltaTime);
top_clouds_sprite_a_->update(delta_time);
top_clouds_sprite_b_->update(delta_time);
bottom_clouds_sprite_a_->update(delta_time);
bottom_clouds_sprite_b_->update(delta_time);
// Calcula el offset de las nubes
if (top_clouds_sprite_a_->getPosX() < -top_clouds_sprite_a_->getWidth()) {

View File

@@ -117,8 +117,8 @@ class Background {
bool manual_mode_ = false; // Si está en modo manual
// --- Variables para transición suave de completado ---
float completion_transition_timer_ = 0.0f; // Timer para la transición de completado
float completion_initial_progress_ = 0.0f; // Progreso inicial al entrar en estado completado
float completion_transition_timer_ = 0.0F; // Timer para la transición de completado
float completion_initial_progress_ = 0.0F; // Progreso inicial al entrar en estado completado
// --- Métodos internos ---
void initializePaths(); // Inicializa las rutas del sol y la luna
@@ -133,7 +133,7 @@ class Background {
void renderBottomClouds(); // Dibuja las nubes inferiores
void fillCanvas(); // Compone todos los elementos en la textura
void updateAlphaColorTexture(); // Actualiza el alpha de la textura de atenuación
void updateClouds(float deltaTime); // Actualiza el movimiento de las nubes (time-based)
void updateClouds(float delta_time); // Actualiza el movimiento de las nubes (time-based)
void createSunPath(); // Precalcula el recorrido del sol
void createMoonPath(); // Precalcula el recorrido de la luna
};

View File

@@ -131,7 +131,7 @@ void Balloon::render() {
// Renderizado para el resto de globos
if (isBeingCreated()) {
// Renderizado con transparencia
sprite_->getTexture()->setAlpha(255 - (int)((float)creation_counter_ * (255.0F / (float)creation_counter_ini_)));
sprite_->getTexture()->setAlpha(255 - (int)(creation_counter_ * (255.0F / creation_counter_ini_)));
sprite_->render();
sprite_->getTexture()->setAlpha(255);
} else {
@@ -142,19 +142,19 @@ void Balloon::render() {
}
// Actualiza la posición y estados del globo (time-based)
void Balloon::move(float deltaTime) {
void Balloon::move(float delta_time) {
if (isStopped()) {
return;
}
handleHorizontalMovement(deltaTime);
handleVerticalMovement(deltaTime);
applyGravity(deltaTime);
handleHorizontalMovement(delta_time);
handleVerticalMovement(delta_time);
applyGravity(delta_time);
}
void Balloon::handleHorizontalMovement(float deltaTime) {
void Balloon::handleHorizontalMovement(float delta_time) {
// DeltaTime en segundos: velocidad (pixels/s) * tempo * tiempo (s)
x_ += vx_ * game_tempo_ * deltaTime;
x_ += vx_ * game_tempo_ * delta_time;
const int CLIP = 2;
const float MIN_X = play_area_.x - CLIP;
@@ -165,9 +165,9 @@ void Balloon::handleHorizontalMovement(float deltaTime) {
}
}
void Balloon::handleVerticalMovement(float deltaTime) {
void Balloon::handleVerticalMovement(float delta_time) {
// DeltaTime en segundos: velocidad (pixels/s) * tempo * tiempo (s)
y_ += vy_ * game_tempo_ * deltaTime;
y_ += vy_ * game_tempo_ * delta_time;
if (shouldCheckTopCollision()) {
handleTopCollision();
@@ -222,37 +222,37 @@ void Balloon::handleBottomCollision() {
}
}
void Balloon::applyGravity(float deltaTime) {
void Balloon::applyGravity(float delta_time) {
// DeltaTime en segundos: aceleración (pixels/s²) * tempo * tiempo (s)
vy_ += gravity_ * game_tempo_ * deltaTime;
vy_ += gravity_ * game_tempo_ * delta_time;
}
void Balloon::playBouncingSound() {
void Balloon::playBouncingSound() const {
if (sound_.enabled && sound_.bouncing_enabled) {
Audio::get()->playSound(sound_.bouncing_file);
}
}
void Balloon::playPoppingSound() {
void Balloon::playPoppingSound() const {
if (sound_.enabled && sound_.poping_enabled) {
Audio::get()->playSound(sound_.popping_file);
}
}
// Actualiza al globo a su posicion, animación y controla los contadores (time-based)
void Balloon::update(float deltaTime) {
move(deltaTime);
updateState(deltaTime);
void Balloon::update(float delta_time) {
move(delta_time);
updateState(delta_time);
updateBounceEffect();
shiftSprite();
shiftColliders();
sprite_->update(deltaTime);
sprite_->update(delta_time);
// Contador interno con deltaTime en segundos
counter_ += deltaTime;
counter_ += delta_time;
}
// Actualiza los estados del globo (time-based)
void Balloon::updateState(float deltaTime) {
void Balloon::updateState(float delta_time) {
// Si se está creando
if (isBeingCreated()) {
// Actualiza el valor de las variables
@@ -262,13 +262,13 @@ void Balloon::updateState(float deltaTime) {
if (creation_counter_ > 0) {
// Desplaza lentamente el globo hacia abajo y hacia un lado
// Cada 10/60 segundos (equivalente a 10 frames a 60fps)
movement_accumulator_ += deltaTime;
movement_accumulator_ += delta_time;
constexpr float MOVEMENT_INTERVAL_S = 10.0f / 60.0f; // 10 frames = ~0.167s
constexpr float MOVEMENT_INTERVAL_S = 10.0F / 60.0F; // 10 frames = ~0.167s
if (movement_accumulator_ >= MOVEMENT_INTERVAL_S) {
movement_accumulator_ -= MOVEMENT_INTERVAL_S;
y_++;
x_ += vx_ / 60.0f; // Convierte de pixels/segundo a pixels/frame para movimiento discreto
x_ += vx_ / 60.0F; // Convierte de pixels/segundo a pixels/frame para movimiento discreto
// Comprueba no se salga por los laterales
const int MIN_X = play_area_.x;
@@ -276,12 +276,12 @@ void Balloon::updateState(float deltaTime) {
if (x_ < MIN_X || x_ > MAX_X) {
// Corrige y cambia el sentido de la velocidad
x_ -= vx_ / 60.0f;
x_ -= vx_ / 60.0F;
vx_ = -vx_;
}
}
creation_counter_ -= deltaTime;
if (creation_counter_ < 0) creation_counter_ = 0;
creation_counter_ -= delta_time;
creation_counter_ = std::max<float>(creation_counter_, 0);
}
else {

View File

@@ -77,7 +77,7 @@ class Balloon {
Size size = Size::EXTRALARGE;
float vel_x = VELX_POSITIVE;
float game_tempo = GAME_TEMPO.at(0);
float creation_counter = 0.0f;
float creation_counter = 0.0F;
SDL_FRect play_area = {.x = 0.0F, .y = 0.0F, .w = 0.0F, .h = 0.0F};
std::shared_ptr<Texture> texture = nullptr;
std::vector<std::string> animation;
@@ -91,8 +91,8 @@ class Balloon {
// --- Métodos principales ---
void alignTo(int x); // Centra el globo en la posición X
void render(); // Pinta el globo en la pantalla
void move(float deltaTime); // Actualiza la posición y estados del globo (time-based)
void update(float deltaTime); // Actualiza el globo (posición, animación, contadores) (time-based)
void move(float delta_time); // Actualiza la posición y estados del globo (time-based)
void update(float delta_time); // Actualiza el globo (posición, animación, contadores) (time-based)
void stop(); // Detiene el globo
void start(); // Pone el globo en movimiento
void pop(bool should_sound = false); // Explota el globo
@@ -268,7 +268,7 @@ class Balloon {
Uint8 menace_; // Amenaza que genera el globo
Uint32 counter_ = 0; // Contador interno
float game_tempo_; // Multiplicador de tempo del juego
float movement_accumulator_ = 0.0f; // Acumulador para movimiento durante creación (deltaTime)
float movement_accumulator_ = 0.0F; // Acumulador para movimiento durante creación (deltaTime)
Uint8 power_; // Poder que alberga el globo
SDL_FRect play_area_; // Zona de movimiento del globo
Sound sound_; // Configuración de sonido del globo
@@ -279,14 +279,14 @@ class Balloon {
void shiftSprite(); // Alinea el sprite en pantalla
// --- Animación y sonido ---
void setAnimation(); // Establece la animación correspondiente
void playBouncingSound(); // Reproduce el sonido de rebote
void playPoppingSound(); // Reproduce el sonido de reventar
void setAnimation(); // Establece la animación correspondiente
void playBouncingSound() const; // Reproduce el sonido de rebote
void playPoppingSound() const; // Reproduce el sonido de reventar
// --- Movimiento y física ---
void handleHorizontalMovement(float deltaTime); // Maneja el movimiento horizontal (time-based)
void handleVerticalMovement(float deltaTime); // Maneja el movimiento vertical (time-based)
void applyGravity(float deltaTime); // Aplica la gravedad al objeto (time-based)
void handleHorizontalMovement(float delta_time); // Maneja el movimiento horizontal (time-based)
void handleVerticalMovement(float delta_time); // Maneja el movimiento vertical (time-based)
void applyGravity(float delta_time); // Aplica la gravedad al objeto (time-based)
// --- Rebote ---
void enableBounceEffect(); // Activa el efecto de rebote
@@ -301,5 +301,5 @@ class Balloon {
void handleBottomCollision(); // Maneja la colisión inferior
// --- Lógica de estado ---
void updateState(float deltaTime); // Actualiza los estados del globo (time-based)
void updateState(float delta_time); // Actualiza los estados del globo (time-based)
};

View File

@@ -235,10 +235,10 @@ void BalloonFormations::createFloaterVariants() {
#ifdef _DEBUG
void BalloonFormations::addTestFormation() {
std::vector<SpawnParams> test_params = {
{10, -BLOCK, 0, Balloon::Type::FLOATER, Balloon::Size::SMALL, 3.334f}, // 200 frames ÷ 60fps = 3.334s
{50, -BLOCK, 0, Balloon::Type::FLOATER, Balloon::Size::MEDIUM, 3.334f}, // 200 frames ÷ 60fps = 3.334s
{90, -BLOCK, 0, Balloon::Type::FLOATER, Balloon::Size::LARGE, 3.334f}, // 200 frames ÷ 60fps = 3.334s
{140, -BLOCK, 0, Balloon::Type::FLOATER, Balloon::Size::EXTRALARGE, 3.334f}}; // 200 frames ÷ 60fps = 3.334s
{10, -BLOCK, 0, Balloon::Type::FLOATER, Balloon::Size::SMALL, 3.334F}, // 200 frames ÷ 60fps = 3.334s
{50, -BLOCK, 0, Balloon::Type::FLOATER, Balloon::Size::MEDIUM, 3.334F}, // 200 frames ÷ 60fps = 3.334s
{90, -BLOCK, 0, Balloon::Type::FLOATER, Balloon::Size::LARGE, 3.334F}, // 200 frames ÷ 60fps = 3.334s
{140, -BLOCK, 0, Balloon::Type::FLOATER, Balloon::Size::EXTRALARGE, 3.334F}}; // 200 frames ÷ 60fps = 3.334s
formations_.at(99) = Formation(test_params);
}

View File

@@ -1,14 +1,14 @@
#pragma once
#include <algorithm> // Para copy, max
#include <cstddef> // Para size_t
#include <map> // Para map
#include <optional> // Para optional
#include <string> // Para string
#include <utility> // Para pair
#include <vector> // Para vector
#include <cstddef> // Para size_t
#include <iterator> // Para pair
#include <map> // Para map
#include <optional> // Para optional
#include <string> // Para string
#include <utility> // Para pair
#include <vector> // Para vector
#include "balloon.hpp" // Para Balloon
#include "balloon.hpp" // for Balloon
// --- Clase BalloonFormations ---
class BalloonFormations {
@@ -20,7 +20,7 @@ class BalloonFormations {
float vel_x = 0.0F; // Velocidad inicial en el eje X
Balloon::Type type = Balloon::Type::BALLOON; // Tipo de globo
Balloon::Size size = Balloon::Size::SMALL; // Tamaño de globo
float creation_counter = 0.0f; // Temporizador para la creación del globo
float creation_counter = 0.0F; // Temporizador para la creación del globo
// Constructor por defecto
SpawnParams() = default;
@@ -82,8 +82,8 @@ class BalloonFormations {
private:
// --- Constantes ---
static constexpr int BALLOON_SPAWN_HEIGHT = 208; // Altura desde el suelo en la que aparecen los globos
static constexpr float CREATION_TIME = 5.0f; // Tiempo base de creación de los globos en segundos (300 frames ÷ 60fps = 5.0s)
static constexpr float DEFAULT_CREATION_TIME = 3.334f; // Tiempo base de creación de los globos en segundos (200 frames ÷ 60fps = 3.334s)
static constexpr float CREATION_TIME = 5.0F; // Tiempo base de creación de los globos en segundos (300 frames ÷ 60fps = 5.0s)
static constexpr float DEFAULT_CREATION_TIME = 3.334F; // Tiempo base de creación de los globos en segundos (200 frames ÷ 60fps = 3.334s)
// --- Variables ---
std::vector<Formation> formations_; // Vector con todas las formaciones disponibles

View File

@@ -63,12 +63,12 @@ void BalloonManager::init() {
}
// Actualiza (time-based)
void BalloonManager::update(float deltaTime) {
void BalloonManager::update(float delta_time) {
for (const auto& balloon : balloons_) {
balloon->update(deltaTime);
balloon->update(delta_time);
}
updateBalloonDeployCounter(deltaTime);
explosions_->update(deltaTime);
updateBalloonDeployCounter(delta_time);
explosions_->update(delta_time);
}
// Renderiza los objetos
@@ -82,7 +82,7 @@ void BalloonManager::render() {
// Crea una formación de globos
void BalloonManager::deployRandomFormation(int stage) {
// Solo despliega una formación enemiga si el timer ha llegado a cero
if (balloon_deploy_counter_ <= 0.0f) {
if (balloon_deploy_counter_ <= 0.0F) {
// En este punto se decide entre crear una powerball o una formación enemiga
if ((rand() % 100 < 15) && (canPowerBallBeCreated())) {
createPowerBall(); // Crea una powerball
@@ -114,7 +114,7 @@ void BalloonManager::deployRandomFormation(int stage) {
.size = balloon.size,
.vel_x = balloon.vel_x,
.game_tempo = balloon_speed_,
.creation_counter = creation_time_enabled_ ? balloon.creation_counter : 0.0f};
.creation_counter = creation_time_enabled_ ? balloon.creation_counter : 0.0F};
createBalloon(config);
}
@@ -163,9 +163,9 @@ void BalloonManager::freeBalloons() {
}
// Actualiza el timer de despliegue de globos (time-based)
void BalloonManager::updateBalloonDeployCounter(float deltaTime) {
void BalloonManager::updateBalloonDeployCounter(float delta_time) {
// DeltaTime en segundos - timer decrementa hasta llegar a cero
balloon_deploy_counter_ -= deltaTime;
balloon_deploy_counter_ -= delta_time;
}
// Indica si se puede crear una powerball

View File

@@ -2,19 +2,18 @@
#include <SDL3/SDL.h> // Para SDL_FRect
#include <algorithm> // Para max
#include <array> // Para array
#include <memory> // Para shared_ptr, unique_ptr
#include <string> // Para string
#include <vector> // Para vector
#include <array> // Para array
#include <memory> // Para shared_ptr, unique_ptr
#include <string> // Para basic_string, string
#include <vector> // Para vector
#include "balloon.hpp" // Para BALLOON_SPEED, Balloon, Balloon::Size (ptr only), Balloon::Type (ptr only)
#include "balloon_formations.hpp" // Para BalloonFormations
#include "explosions.hpp" // Para Explosions
#include "param.hpp" // Para Param, ParamGame, param
#include "stage_interface.hpp" // Para IStageInfo
#include "utils.hpp" // Para Zone
#include "balloon.hpp" // for Balloon
#include "balloon_formations.hpp" // for BalloonFormations
#include "explosions.hpp" // for Explosions
#include "param.hpp" // for Param, ParamGame, param
#include "utils.hpp" // for Zone
class IStageInfo;
class Texture;
// --- Types ---
@@ -28,8 +27,8 @@ class BalloonManager {
~BalloonManager() = default;
// --- Métodos principales ---
void update(float deltaTime); // Actualiza el estado de los globos (time-based)
void render(); // Renderiza los globos en pantalla
void update(float delta_time); // Actualiza el estado de los globos (time-based)
void render(); // Renderiza los globos en pantalla
// --- Gestión de globos ---
void freeBalloons(); // Libera globos que ya no sirven
@@ -49,7 +48,7 @@ class BalloonManager {
void setBalloonSpeed(float speed); // Ajusta la velocidad de los globos
void setDefaultBalloonSpeed(float speed) { default_balloon_speed_ = speed; }; // Establece la velocidad base
void resetBalloonSpeed() { setBalloonSpeed(default_balloon_speed_); }; // Restablece la velocidad de los globos
void updateBalloonDeployCounter(float deltaTime); // Actualiza el contador de despliegue (time-based)
void updateBalloonDeployCounter(float delta_time); // Actualiza el contador de despliegue (time-based)
auto canPowerBallBeCreated() -> bool; // Indica si se puede crear una PowerBall
auto calculateScreenPower() -> int; // Calcula el poder de los globos en pantalla
@@ -82,9 +81,9 @@ class BalloonManager {
private:
// --- Constantes ---
static constexpr float DEFAULT_BALLOON_DEPLOY_DELAY = 5.0f; // 300 frames = 5 segundos
static constexpr float POWERBALL_DEPLOY_DELAY = 0.167f; // 10 frames = 0.167 segundos
static constexpr float BALLOON_POP_DELAY = 0.333f; // 20 frames = 0.333 segundos
static constexpr float DEFAULT_BALLOON_DEPLOY_DELAY = 5.0F; // 300 frames = 5 segundos
static constexpr float POWERBALL_DEPLOY_DELAY = 0.167F; // 10 frames = 0.167 segundos
static constexpr float BALLOON_POP_DELAY = 0.333F; // 20 frames = 0.333 segundos
// --- Objetos y punteros ---
Balloons balloons_; // Vector con los globos activos

View File

@@ -1,10 +1,9 @@
#include "bullet.hpp"
#include <memory> // Para allocator, unique_ptr, make_unique
#include <string> // Para char_traits, basic_string, operator+, string
#include <memory> // Para unique_ptr, make_unique
#include <string> // Para basic_string, string
#include "param.hpp" // Para Param, ParamGame, param
#include "player.hpp" // Para Player::Id
#include "resource.hpp" // Para Resource
// Constructor
@@ -79,20 +78,20 @@ void Bullet::render() {
}
// Actualiza el estado del objeto
auto Bullet::update(float deltaTime) -> MoveStatus {
sprite_->update(deltaTime);
return move(deltaTime);
auto Bullet::update(float delta_time) -> MoveStatus {
sprite_->update(delta_time);
return move(delta_time);
}
// Implementación del movimiento usando MoveStatus
auto Bullet::move(float deltaTime) -> MoveStatus {
pos_x_ += vel_x_ * deltaTime;
auto Bullet::move(float delta_time) -> MoveStatus {
pos_x_ += vel_x_ * delta_time;
if (pos_x_ < param.game.play_area.rect.x - WIDTH || pos_x_ > param.game.play_area.rect.w) {
disable();
return MoveStatus::OUT;
}
pos_y_ += VEL_Y * deltaTime;
pos_y_ += VEL_Y * delta_time;
if (pos_y_ < param.game.play_area.rect.y - HEIGHT) {
disable();
return MoveStatus::OUT;

View File

@@ -40,9 +40,9 @@ class Bullet {
~Bullet() = default; // Destructor
// --- Métodos principales ---
void render(); // Dibuja la bala en pantalla
auto update(float deltaTime) -> MoveStatus; // Actualiza el estado del objeto (time-based)
void disable(); // Desactiva la bala
void render(); // Dibuja la bala en pantalla
auto update(float delta_time) -> MoveStatus; // Actualiza el estado del objeto (time-based)
void disable(); // Desactiva la bala
// --- Getters ---
[[nodiscard]] auto isEnabled() const -> bool; // Comprueba si está activa
@@ -70,7 +70,7 @@ class Bullet {
// --- Métodos internos ---
void shiftColliders(); // Ajusta el círculo de colisión
void shiftSprite(); // Ajusta el sprite
auto move(float deltaTime) -> MoveStatus; // Mueve la bala y devuelve su estado (time-based)
auto move(float delta_time) -> MoveStatus; // Mueve la bala y devuelve su estado (time-based)
static auto calculateVelocity(Type type) -> float; // Calcula la velocidad horizontal de la bala
static auto buildAnimationString(Type type, Color color) -> std::string; // Construye el string de animación
};

View File

@@ -1,10 +1,11 @@
#include "bullet_manager.hpp"
#include <algorithm> // Para remove_if
#include <utility>
#include "bullet.hpp" // Para Bullet
#include "param.hpp" // Para param
#include "player.hpp" // Para Player
#include "param.hpp" // Para Param, ParamGame, param
#include "utils.hpp" // Para Circle, Zone
// Constructor
BulletManager::BulletManager()
@@ -12,10 +13,10 @@ BulletManager::BulletManager()
}
// Actualiza el estado de todas las balas
void BulletManager::update(float deltaTime) {
void BulletManager::update(float delta_time) {
for (auto& bullet : bullets_) {
if (bullet->isEnabled()) {
processBulletUpdate(bullet, deltaTime);
processBulletUpdate(bullet, delta_time);
}
}
}
@@ -36,14 +37,9 @@ void BulletManager::createBullet(int x, int y, Bullet::Type type, Bullet::Color
// Libera balas que ya no están habilitadas
void BulletManager::freeBullets() {
if (!bullets_.empty()) {
// Elimina las balas deshabilitadas del vector
bullets_.erase(
std::remove_if(bullets_.begin(), bullets_.end(), [](const std::shared_ptr<Bullet>& bullet) {
return !bullet->isEnabled();
}),
bullets_.end());
}
std::erase_if(bullets_, [](const std::shared_ptr<Bullet>& bullet) {
return !bullet->isEnabled();
});
}
// Elimina todas las balas
@@ -72,24 +68,24 @@ void BulletManager::checkCollisions() {
// Establece el callback para colisión con Tabe
void BulletManager::setTabeCollisionCallback(CollisionCallback callback) {
tabe_collision_callback_ = callback;
tabe_collision_callback_ = std::move(callback);
}
// Establece el callback para colisión con globos
void BulletManager::setBalloonCollisionCallback(CollisionCallback callback) {
balloon_collision_callback_ = callback;
balloon_collision_callback_ = std::move(callback);
}
// Establece el callback para balas fuera de límites
void BulletManager::setOutOfBoundsCallback(OutOfBoundsCallback callback) {
out_of_bounds_callback_ = callback;
out_of_bounds_callback_ = std::move(callback);
}
// --- Métodos privados ---
// Procesa la actualización individual de una bala
void BulletManager::processBulletUpdate(const std::shared_ptr<Bullet>& bullet, float deltaTime) {
auto status = bullet->update(deltaTime);
void BulletManager::processBulletUpdate(const std::shared_ptr<Bullet>& bullet, float delta_time) {
auto status = bullet->update(delta_time);
// Si la bala salió de los límites, llama al callback
if (status == Bullet::MoveStatus::OUT && out_of_bounds_callback_) {
@@ -98,7 +94,7 @@ void BulletManager::processBulletUpdate(const std::shared_ptr<Bullet>& bullet, f
}
// Verifica si la bala está fuera de los límites del área de juego
auto BulletManager::isBulletOutOfBounds(const std::shared_ptr<Bullet>& bullet) -> bool {
auto BulletManager::isBulletOutOfBounds(const std::shared_ptr<Bullet>& bullet) const -> bool {
auto collider = bullet->getCollider();
return (collider.x < play_area_.x ||

View File

@@ -3,18 +3,14 @@
#include <SDL3/SDL.h> // Para SDL_FRect
#include <functional> // Para function
#include <memory> // Para shared_ptr, unique_ptr
#include <memory> // Para shared_ptr
#include <vector> // Para vector
#include "bullet.hpp" // Para Bullet
#include "utils.hpp" // Para Circle
#include "bullet.hpp" // for Bullet
// --- Types ---
using Bullets = std::vector<std::shared_ptr<Bullet>>;
// --- Forward declarations ---
class Player;
// --- Clase BulletManager: gestiona todas las balas del juego ---
//
// Esta clase se encarga de la gestión completa de las balas del juego,
@@ -40,8 +36,8 @@ class BulletManager {
~BulletManager() = default;
// --- Métodos principales ---
void update(float deltaTime); // Actualiza el estado de las balas (time-based)
void render(); // Renderiza las balas en pantalla
void update(float delta_time); // Actualiza el estado de las balas (time-based)
void render(); // Renderiza las balas en pantalla
// --- Gestión de balas ---
void createBullet(int x, int y, Bullet::Type type, Bullet::Color color, int owner); // Crea una nueva bala
@@ -74,6 +70,6 @@ class BulletManager {
OutOfBoundsCallback out_of_bounds_callback_; // Callback para balas fuera de límites
// --- Métodos internos ---
void processBulletUpdate(const std::shared_ptr<Bullet>& bullet, float deltaTime); // Procesa actualización individual
auto isBulletOutOfBounds(const std::shared_ptr<Bullet>& bullet) -> bool; // Verifica si la bala está fuera de límites
void processBulletUpdate(const std::shared_ptr<Bullet>& bullet, float delta_time); // Procesa actualización individual
auto isBulletOutOfBounds(const std::shared_ptr<Bullet>& bullet) const -> bool; // Verifica si la bala está fuera de límites
};

View File

@@ -43,7 +43,7 @@ auto Color::fromHex(const std::string& hex_str) -> Color {
}
// Implementaciones de métodos estáticos de Color
constexpr auto Color::rgbToHsv(Color color) -> HSV {
constexpr auto Color::RGB_TO_HSV(Color color) -> HSV {
float r = color.r / 255.0F;
float g = color.g / 255.0F;
float b = color.b / 255.0F;
@@ -73,7 +73,7 @@ constexpr auto Color::rgbToHsv(Color color) -> HSV {
return {.h = h, .s = s, .v = v};
}
constexpr auto Color::hsvToRgb(HSV hsv) -> Color {
constexpr auto Color::HSV_TO_RGB(HSV hsv) -> Color {
float c = hsv.v * hsv.s;
float x = c * (1 - std::abs(std::fmod(hsv.h / 60.0F, 2) - 1));
float m = hsv.v - c;
@@ -133,7 +133,7 @@ auto getColorLikeKnightRider(const std::vector<Color>& colors, int counter) -> C
auto generateMirroredCycle(Color base, ColorCycleStyle style) -> Cycle {
Cycle result{};
HSV base_hsv = Color::rgbToHsv(base);
HSV base_hsv = Color::RGB_TO_HSV(base);
for (size_t i = 0; i < CYCLE_SIZE; ++i) {
float t = static_cast<float>(i) / (CYCLE_SIZE - 1); // 0 → 1
@@ -176,7 +176,7 @@ auto generateMirroredCycle(Color base, ColorCycleStyle style) -> Cycle {
.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 = Color::hsvToRgb(adjusted);
Color c = Color::HSV_TO_RGB(adjusted);
result[i] = c;
result[(2 * CYCLE_SIZE) - 1 - i] = c; // espejo
}

View File

@@ -72,8 +72,8 @@ struct Color {
static auto fromHex(const std::string& hex_str) -> Color;
// Conversiones de formato de color
[[nodiscard]] constexpr static auto rgbToHsv(Color color) -> HSV;
[[nodiscard]] constexpr static auto hsvToRgb(HSV hsv) -> Color;
[[nodiscard]] constexpr static auto RGB_TO_HSV(Color color) -> HSV;
[[nodiscard]] constexpr static auto HSV_TO_RGB(HSV hsv) -> Color;
[[nodiscard]] constexpr auto IS_EQUAL_TO(const Color& other) const -> bool {
return r == other.r && g == other.g && b == other.b && a == other.a;
@@ -98,11 +98,11 @@ struct Color {
// Interpolación lineal hacia otro color (t=0.0: this, t=1.0: target)
[[nodiscard]] constexpr auto LERP(const Color& target, float t) const -> Color {
// Asegurar que t esté en el rango [0.0, 1.0]
t = std::clamp(t, 0.0f, 1.0f);
t = std::clamp(t, 0.0F, 1.0F);
// Interpolación lineal para cada componente
auto lerp_component = [t](Uint8 start, Uint8 end) -> Uint8 {
return static_cast<Uint8>(start + (end - start) * t);
return static_cast<Uint8>(start + ((end - start) * t));
};
return Color(

View File

@@ -1,15 +1,13 @@
#include "define_buttons.hpp"
#include <algorithm> // Para __all_of_fn, all_of
#include <functional> // Para identity
#include <memory> // Para allocator, unique_ptr, shared_ptr, make_unique, operator==
#include <algorithm> // Para __all_of_fn, all_of
#include <memory> // Para unique_ptr, allocator, shared_ptr, operator==, make_unique
#include "color.hpp" // Para Color
#include "input.hpp" // Para Input
#include "input_types.hpp" // Para InputAction
#include "lang.hpp" // Para getText
#include "options.hpp" // Para Gamepad
#include "param.hpp" // Para Param, ParamGame, param
#include "param.hpp" // Para Param, param, ParamGame, ParamServiceMenu
#include "resource.hpp" // Para Resource
#include "ui/window_message.hpp" // Para WindowMessage
#include "utils.hpp" // Para Zone
@@ -234,7 +232,7 @@ void DefineButtons::checkEnd() {
// Solo marcar que ya mostramos el mensaje
message_shown_ = true;
message_timer_ = 0.0f;
message_timer_ = 0.0F;
}
}

View File

@@ -48,7 +48,7 @@ class DefineButtons {
private:
// --- Constantes ---
static constexpr float MESSAGE_DISPLAY_DURATION_S = 2.0f; // Cuánto tiempo mostrar el mensaje en segundos
static constexpr float MESSAGE_DISPLAY_DURATION_S = 2.0F; // Cuánto tiempo mostrar el mensaje en segundos
// --- Objetos y punteros ---
Input* input_ = nullptr; // Entrada del usuario
@@ -59,7 +59,7 @@ class DefineButtons {
std::vector<Button> buttons_; // Lista de botones
std::vector<std::string> controller_names_; // Nombres de los controladores
size_t index_button_ = 0; // Índice del botón seleccionado
float message_timer_ = 0.0f; // Timer en segundos para el mensaje
float message_timer_ = 0.0F; // Timer en segundos para el mensaje
bool enabled_ = false; // Flag para indicar si está activo
bool finished_ = false; // Flag para indicar si ha terminado
bool closing_ = false; // Flag para indicar que está cerrando

View File

@@ -5,8 +5,8 @@
#include <stdexcept> // Para runtime_error
#include "resource_helper.hpp" // Para ResourceHelper
#include "utils.hpp" // Para printWithDots, getFileName
#include "ui/logger.hpp"
#include "utils.hpp" // Para printWithDots, getFileName
// Carga el fichero de datos para la demo
auto loadDemoDataFromFile(const std::string& file_path) -> DemoData {

View File

@@ -1,26 +1,27 @@
// IWYU pragma: no_include <bits/chrono.h>
#include "director.hpp"
#include <SDL3/SDL.h> // Para SDL_LogInfo, SDL_LogCategory, SDL_SetLogPriority, SDL_LogPriority, SDL_Quit
#include <SDL3/SDL.h> // Para SDL_SetLogPriority, SDL_LogCategory, SDL_LogPriority, SDL_Quit
#include <cstdlib> // Para srand, exit, rand, EXIT_FAILURE
#include <ctime> // Para time
#include <iostream> // Para basic_ostream, operator<<, cerr, endl
#include <memory> // Para make_unique, unique_ptr
#include <span> // Para span
#include <stdexcept> // Para runtime_error
#include <string> // Para allocator, char_traits, operator==, string, basic_string, operator+
#include <cstdlib> // Para srand, exit, rand, EXIT_FAILURE
#include <ctime> // Para time
#include <filesystem> // Para path, absolute
#include <iostream> // Para basic_ostream, operator<<, cerr
#include <memory> // Para make_unique, unique_ptr
#include <span> // Para span
#include <stdexcept> // Para runtime_error
#include <string> // Para allocator, basic_string, char_traits, operator+, string, operator==
#include "asset.hpp" // Para Asset
#include "audio.hpp" // Para Audio
#include "input.hpp" // Para Input
#include "lang.hpp" // Para setLanguage
#include "manage_hiscore_table.hpp" // Para ManageHiScoreTable
#include "options.hpp" // Para loadFromFile, saveToFile, Settings, settings, setConfigFile, setControllersFile
#include "options.hpp" // Para Settings, loadFromFile, saveToFile, settings, setConfigFile, setControllersFile
#include "param.hpp" // Para loadParamsFromFile
#include "player.hpp" // Para Player
#include "resource.hpp" // Para Resource
#include "resource_helper.hpp" // Para ResourceHelper
#include "resource_helper.hpp" // Para initializeResourceSystem
#include "screen.hpp" // Para Screen
#include "section.hpp" // Para Name, Options, name, options, AttractMode, attract_mode
#include "sections/credits.hpp" // Para Credits
@@ -32,10 +33,10 @@
#include "sections/title.hpp" // Para Title
#include "shutdown.hpp" // Para resultToString, shutdownSystem, ShutdownResult
#include "system_utils.hpp" // Para createApplicationFolder, resultToString, Result
#include "ui/logger.hpp" // Para section, put
#include "ui/notifier.hpp" // Para Notifier
#include "ui/service_menu.hpp" // Para ServiceMenu
#include "utils.hpp" // Para Overrides, overrides, getPath
#include "ui/logger.hpp"
#include "utils.hpp" // Para Overrides, overrides
// Constructor
Director::Director(int argc, std::span<char*> argv) {
@@ -85,28 +86,27 @@ void Director::init() {
#else
ResourceHelper::initializeResourceSystem(executable_path_ + "resources.pack");
#endif
loadAssets(); // Crea el índice de archivos
loadAssets(); // Crea el índice de archivos
Logger::section("INIT INPUT");
Input::init(Asset::get()->get("gamecontrollerdb.txt"), Asset::get()->get("controllers.json")); // Carga configuración de controles
Logger::section("INIT CONFIG");
Options::setConfigFile(Asset::get()->get("config_v2.txt")); // Establece el fichero de configuración
Options::setControllersFile(Asset::get()->get("controllers.json")); // Establece el fichero de configuración de mandos
Options::loadFromFile(); // Carga el archivo de configuración
loadParams(); // Carga los parámetros del programa
loadScoreFile(); // Carga el archivo de puntuaciones
Options::setConfigFile(Asset::get()->get("config_v2.txt")); // Establece el fichero de configuración
Options::setControllersFile(Asset::get()->get("controllers.json")); // Establece el fichero de configuración de mandos
Options::loadFromFile(); // Carga el archivo de configuración
loadParams(); // Carga los parámetros del programa
loadScoreFile(); // Carga el archivo de puntuaciones
// Inicialización de subsistemas principales
Lang::setLanguage(Options::settings.language); // Carga el archivo de idioma
Logger::section("INIT VIDEO");
Screen::init(); // Inicializa la pantalla y el sistema de renderizado
Screen::init(); // Inicializa la pantalla y el sistema de renderizado
Logger::section("INIT AUDIO");
Audio::init(); // Activa el sistema de audio
Audio::init(); // Activa el sistema de audio
Logger::section("INIT RESOURCES");
#ifdef _DEBUG
Resource::init(Resource::LoadingMode::PRELOAD); // Inicializa el sistema de gestión de recursos

View File

@@ -6,8 +6,7 @@
// Constructor
EnterName::EnterName()
: character_list_("ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789."),
selected_index_(0) {}
: character_list_("ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.") {}
// Inicializa el objeto
void EnterName::init(const std::string& name) {

View File

@@ -1,15 +1,13 @@
#include "explosions.hpp"
#include <algorithm> // Para max
#include "animated_sprite.hpp" // Para AnimatedSprite
class Texture; // lines 4-4
// Actualiza la lógica de la clase (time-based)
void Explosions::update(float deltaTime) {
void Explosions::update(float delta_time) {
for (auto& explosion : explosions_) {
explosion->update(deltaTime);
explosion->update(delta_time);
}
// Vacia el vector de elementos finalizados

View File

@@ -29,8 +29,8 @@ class Explosions {
~Explosions() = default; // Destructor por defecto
// --- Métodos principales ---
void update(float deltaTime); // Actualiza la lógica de la clase (time-based)
void render(); // Dibuja el objeto en pantalla
void update(float delta_time); // Actualiza la lógica de la clase (time-based)
void render(); // Dibuja el objeto en pantalla
// --- Configuración ---
void addTexture(int size, const std::shared_ptr<Texture>& texture, const std::vector<std::string>& animation); // Añade texturas al objeto

View File

@@ -366,7 +366,7 @@ void Fade::activateDiagonal(int diagonal_index, Uint32 current_time) {
// Verificar que y está dentro de los límites
if (y >= 0 && y < num_squares_height_) {
// Convertir coordenadas (x,y) a índice en el vector
int index = y * num_squares_width_ + x;
int index = (y * num_squares_width_) + x;
if (index >= 0 && index < static_cast<int>(square_age_.size())) {
if (square_age_[index] == -1) {
@@ -405,12 +405,12 @@ void Fade::drawDiagonal() {
} else {
// Cuadrado activado - calculamos progreso
Uint32 square_elapsed = current_time - square_age_[i];
float progress = std::min(static_cast<float>(square_elapsed) / square_transition_duration_, 1.0f);
float progress = std::min(static_cast<float>(square_elapsed) / square_transition_duration_, 1.0F);
if (mode_ == Mode::OUT) {
current_alpha = static_cast<Uint8>(progress * a_); // 0 → 255
} else {
current_alpha = static_cast<Uint8>((1.0f - progress) * a_); // 255 → 0
current_alpha = static_cast<Uint8>((1.0F - progress) * a_); // 255 → 0
}
}
@@ -470,12 +470,12 @@ void Fade::drawRandomSquares2() {
} else {
// Cuadrado activado - calculamos progreso
Uint32 square_elapsed = current_time - square_age_[i];
float progress = std::min(static_cast<float>(square_elapsed) / square_transition_duration_, 1.0f);
float progress = std::min(static_cast<float>(square_elapsed) / square_transition_duration_, 1.0F);
if (mode_ == Mode::OUT) {
current_alpha = static_cast<Uint8>(progress * a_); // 0 → 255
} else {
current_alpha = static_cast<Uint8>((1.0f - progress) * a_); // 255 → 0
current_alpha = static_cast<Uint8>((1.0F - progress) * a_); // 255 → 0
}
}

View File

@@ -3,6 +3,7 @@
#include <SDL3/SDL.h> // Para SDL_SetTextureScaleMode, SDL_FlipMode, SDL_ScaleMode
#include <algorithm> // Para max
#include <string> // Para basic_string
#include "animated_sprite.hpp" // Para AnimatedSprite
#include "audio.hpp" // Para Audio
@@ -15,8 +16,8 @@
#include "texture.hpp" // Para Texture
constexpr int ZOOM_FACTOR = 5;
constexpr float FLASH_DELAY_S = 0.05f; // 3 frames → 0.05s
constexpr float FLASH_DURATION_S = 0.1f; // 6 frames → 0.1s (3 + 3)
constexpr float FLASH_DELAY_S = 0.05F; // 3 frames → 0.05s
constexpr float FLASH_DURATION_S = 0.1F; // 6 frames → 0.1s (3 + 3)
constexpr Color FLASH_COLOR = Color(0xFF, 0xFF, 0xFF); // Color blanco para el flash
// Constructor
@@ -46,7 +47,7 @@ void GameLogo::init() {
arcade_edition_status_ = Status::DISABLED;
shake_.init(1, 2, 8, XP);
zoom_ = 3.0F * ZOOM_FACTOR;
post_finished_timer_ = 0.0f;
post_finished_timer_ = 0.0F;
// Inicializa el bitmap de 'Coffee'
coffee_sprite_->setPosX(XP);
@@ -59,7 +60,7 @@ void GameLogo::init() {
coffee_sprite_->setAccelY(COFFEE_ACCEL_Y);
coffee_sprite_->setSpriteClip(0, 0, coffee_texture_->getWidth(), coffee_texture_->getHeight());
coffee_sprite_->setEnabled(true);
coffee_sprite_->setFinishedDelay(0.0f);
coffee_sprite_->setFinishedDelay(0.0F);
coffee_sprite_->setDestX(XP);
coffee_sprite_->setDestY(y_ - coffee_texture_->getHeight());
@@ -74,7 +75,7 @@ void GameLogo::init() {
crisis_sprite_->setAccelY(CRISIS_ACCEL_Y);
crisis_sprite_->setSpriteClip(0, 0, crisis_texture_->getWidth(), crisis_texture_->getHeight());
crisis_sprite_->setEnabled(true);
crisis_sprite_->setFinishedDelay(0.0f);
crisis_sprite_->setFinishedDelay(0.0F);
crisis_sprite_->setDestX(XP + CRISIS_OFFSET_X);
crisis_sprite_->setDestY(y_);
@@ -115,44 +116,44 @@ void GameLogo::render() {
}
// Actualiza la lógica de la clase (time-based)
void GameLogo::update(float deltaTime) {
updateCoffeeCrisis(deltaTime);
updateArcadeEdition(deltaTime);
updatePostFinishedCounter(deltaTime);
void GameLogo::update(float delta_time) {
updateCoffeeCrisis(delta_time);
updateArcadeEdition(delta_time);
updatePostFinishedCounter(delta_time);
}
void GameLogo::updateCoffeeCrisis(float deltaTime) {
void GameLogo::updateCoffeeCrisis(float delta_time) {
switch (coffee_crisis_status_) {
case Status::MOVING:
handleCoffeeCrisisMoving(deltaTime);
handleCoffeeCrisisMoving(delta_time);
break;
case Status::SHAKING:
handleCoffeeCrisisShaking(deltaTime);
handleCoffeeCrisisShaking(delta_time);
break;
case Status::FINISHED:
handleCoffeeCrisisFinished(deltaTime);
handleCoffeeCrisisFinished(delta_time);
break;
default:
break;
}
}
void GameLogo::updateArcadeEdition(float deltaTime) {
void GameLogo::updateArcadeEdition(float delta_time) {
switch (arcade_edition_status_) {
case Status::MOVING:
handleArcadeEditionMoving(deltaTime);
handleArcadeEditionMoving(delta_time);
break;
case Status::SHAKING:
handleArcadeEditionShaking(deltaTime);
handleArcadeEditionShaking(delta_time);
break;
default:
break;
}
}
void GameLogo::handleCoffeeCrisisMoving(float deltaTime) {
coffee_sprite_->update(deltaTime);
crisis_sprite_->update(deltaTime);
void GameLogo::handleCoffeeCrisisMoving(float delta_time) {
coffee_sprite_->update(delta_time);
crisis_sprite_->update(delta_time);
if (coffee_sprite_->hasFinished() && crisis_sprite_->hasFinished()) {
coffee_crisis_status_ = Status::SHAKING;
@@ -160,23 +161,23 @@ void GameLogo::handleCoffeeCrisisMoving(float deltaTime) {
}
}
void GameLogo::handleCoffeeCrisisShaking(float deltaTime) {
void GameLogo::handleCoffeeCrisisShaking(float delta_time) {
if (shake_.remaining > 0) {
processShakeEffect(coffee_sprite_.get(), crisis_sprite_.get(), deltaTime);
processShakeEffect(coffee_sprite_.get(), crisis_sprite_.get(), delta_time);
} else {
finishCoffeeCrisisShaking();
}
updateDustSprites(deltaTime);
updateDustSprites(delta_time);
}
void GameLogo::handleCoffeeCrisisFinished(float deltaTime) {
updateDustSprites(deltaTime);
void GameLogo::handleCoffeeCrisisFinished(float delta_time) {
updateDustSprites(delta_time);
}
void GameLogo::handleArcadeEditionMoving(float deltaTime) {
void GameLogo::handleArcadeEditionMoving(float delta_time) {
// DeltaTime en segundos: decremento por segundo
zoom_ -= (ZOOM_DECREMENT_PER_S * ZOOM_FACTOR) * deltaTime;
zoom_ -= (ZOOM_DECREMENT_PER_S * ZOOM_FACTOR) * delta_time;
arcade_edition_sprite_->setZoom(zoom_);
if (zoom_ <= 1.0F) {
@@ -184,17 +185,17 @@ void GameLogo::handleArcadeEditionMoving(float deltaTime) {
}
}
void GameLogo::handleArcadeEditionShaking(float deltaTime) {
void GameLogo::handleArcadeEditionShaking(float delta_time) {
if (shake_.remaining > 0) {
processArcadeEditionShake(deltaTime);
processArcadeEditionShake(delta_time);
} else {
arcade_edition_sprite_->setX(shake_.origin);
arcade_edition_status_ = Status::FINISHED;
}
}
void GameLogo::processShakeEffect(SmartSprite* primary_sprite, SmartSprite* secondary_sprite, float deltaTime) {
shake_.time_accumulator += deltaTime;
void GameLogo::processShakeEffect(SmartSprite* primary_sprite, SmartSprite* secondary_sprite, float delta_time) {
shake_.time_accumulator += delta_time;
if (shake_.time_accumulator >= SHAKE_DELAY_S) {
shake_.time_accumulator -= SHAKE_DELAY_S;
@@ -207,14 +208,14 @@ void GameLogo::processShakeEffect(SmartSprite* primary_sprite, SmartSprite* seco
}
}
void GameLogo::processArcadeEditionShake(float deltaTime) {
void GameLogo::processArcadeEditionShake(float delta_time) {
// Delay fijo en segundos (shake_.delay era frames, ahora usamos constante)
float delayTime = SHAKE_DELAY_S;
float delay_time = SHAKE_DELAY_S;
shake_.time_accumulator += deltaTime;
shake_.time_accumulator += delta_time;
if (shake_.time_accumulator >= delayTime) {
shake_.time_accumulator -= delayTime;
if (shake_.time_accumulator >= delay_time) {
shake_.time_accumulator -= delay_time;
const auto DISPLACEMENT = calculateShakeDisplacement();
arcade_edition_sprite_->setX(shake_.origin + DISPLACEMENT);
shake_.remaining--;
@@ -246,15 +247,15 @@ void GameLogo::playTitleEffects() {
Screen::get()->shake();
}
void GameLogo::updateDustSprites(float deltaTime) {
dust_right_sprite_->update(deltaTime);
dust_left_sprite_->update(deltaTime);
void GameLogo::updateDustSprites(float delta_time) {
dust_right_sprite_->update(delta_time);
dust_left_sprite_->update(delta_time);
}
void GameLogo::updatePostFinishedCounter(float deltaTime) {
void GameLogo::updatePostFinishedCounter(float delta_time) {
if (coffee_crisis_status_ == Status::FINISHED &&
arcade_edition_status_ == Status::FINISHED) {
post_finished_timer_ += deltaTime;
post_finished_timer_ += delta_time;
}
}

View File

@@ -27,9 +27,9 @@ class GameLogo {
~GameLogo() = default;
// --- Métodos principales ---
void render(); // Pinta la clase en pantalla
void update(float deltaTime); // Actualiza la lógica de la clase (time-based)
void enable(); // Activa la clase
void render(); // Pinta la clase en pantalla
void update(float delta_time); // Actualiza la lógica de la clase (time-based)
void enable(); // Activa la clase
// --- Getters ---
[[nodiscard]] auto hasFinished() const -> bool; // Indica si ha terminado la animación
@@ -50,7 +50,7 @@ class GameLogo {
int length = 8; // Cantidad de desplazamientos a realizar
int remaining = length; // Cantidad de desplazamientos pendientes a realizar
int counter = delay; // Contador para el retraso (frame-based)
float time_accumulator = 0.0f; // Acumulador de tiempo para deltaTime
float time_accumulator = 0.0F; // Acumulador de tiempo para deltaTime
int origin = 0; // Valor inicial de la pantalla para dejarla igual tras el desplazamiento
Shake() = default;
@@ -68,7 +68,7 @@ class GameLogo {
length = l;
remaining = l;
counter = de;
time_accumulator = 0.0f;
time_accumulator = 0.0F;
origin = o;
}
};
@@ -93,33 +93,33 @@ class GameLogo {
float y_; // Posición Y del logo
float zoom_ = 1.0F; // Zoom aplicado al texto "ARCADE EDITION"
float post_finished_delay_s_ = POST_FINISHED_FRAME_TIME_S; // Retraso final tras animaciones (s)
float post_finished_timer_ = 0.0f; // Timer acumulado para retraso final (s)
float post_finished_timer_ = 0.0F; // Timer acumulado para retraso final (s)
// --- Inicialización ---
void init(); // Inicializa las variables
[[nodiscard]] auto getInitialVerticalDesp() const -> int; // Calcula el desplazamiento vertical inicial
// --- Actualización de estados específicos ---
void updateCoffeeCrisis(float deltaTime); // Actualiza el estado de "Coffee Crisis" (time-based)
void updateArcadeEdition(float deltaTime); // Actualiza el estado de "Arcade Edition" (time-based)
void updatePostFinishedCounter(float deltaTime); // Actualiza el contador tras finalizar una animación (time-based)
void updateCoffeeCrisis(float delta_time); // Actualiza el estado de "Coffee Crisis" (time-based)
void updateArcadeEdition(float delta_time); // Actualiza el estado de "Arcade Edition" (time-based)
void updatePostFinishedCounter(float delta_time); // Actualiza el contador tras finalizar una animación (time-based)
// --- Efectos visuales: movimiento y sacudidas ---
void handleCoffeeCrisisMoving(float deltaTime); // Maneja el movimiento de "Coffee Crisis" (time-based)
void handleCoffeeCrisisShaking(float deltaTime); // Maneja la sacudida de "Coffee Crisis" (time-based)
void handleArcadeEditionMoving(float deltaTime); // Maneja el movimiento de "Arcade Edition" (time-based)
void handleArcadeEditionShaking(float deltaTime); // Maneja la sacudida de "Arcade Edition" (time-based)
void processShakeEffect(SmartSprite* primary_sprite, SmartSprite* secondary_sprite = nullptr); // Procesa el efecto de sacudida en sprites (frame-based)
void processShakeEffect(SmartSprite* primary_sprite, SmartSprite* secondary_sprite, float deltaTime); // Procesa el efecto de sacudida en sprites (time-based)
void processArcadeEditionShake(float deltaTime); // Procesa la sacudida específica de "Arcade Edition" (time-based)
[[nodiscard]] auto calculateShakeDisplacement() const -> int; // Calcula el desplazamiento de la sacudida
void handleCoffeeCrisisMoving(float delta_time); // Maneja el movimiento de "Coffee Crisis" (time-based)
void handleCoffeeCrisisShaking(float delta_time); // Maneja la sacudida de "Coffee Crisis" (time-based)
void handleArcadeEditionMoving(float delta_time); // Maneja el movimiento de "Arcade Edition" (time-based)
void handleArcadeEditionShaking(float delta_time); // Maneja la sacudida de "Arcade Edition" (time-based)
void processShakeEffect(SmartSprite* primary_sprite, SmartSprite* secondary_sprite = nullptr); // Procesa el efecto de sacudida en sprites (frame-based)
void processShakeEffect(SmartSprite* primary_sprite, SmartSprite* secondary_sprite, float delta_time); // Procesa el efecto de sacudida en sprites (time-based)
void processArcadeEditionShake(float delta_time); // Procesa la sacudida específica de "Arcade Edition" (time-based)
[[nodiscard]] auto calculateShakeDisplacement() const -> int; // Calcula el desplazamiento de la sacudida
// --- Gestión de finalización de efectos ---
void handleCoffeeCrisisFinished(float deltaTime); // Maneja el final de la animación "Coffee Crisis" (time-based)
void finishCoffeeCrisisShaking(); // Finaliza la sacudida de "Coffee Crisis"
void finishArcadeEditionMoving(); // Finaliza el movimiento de "Arcade Edition"
void handleCoffeeCrisisFinished(float delta_time); // Maneja el final de la animación "Coffee Crisis" (time-based)
void finishCoffeeCrisisShaking(); // Finaliza la sacudida de "Coffee Crisis"
void finishArcadeEditionMoving(); // Finaliza el movimiento de "Arcade Edition"
// --- Utilidades ---
static void playTitleEffects(); // Reproduce efectos visuales/sonoros del título
void updateDustSprites(float deltaTime); // Actualiza los sprites de polvo (time-based)
static void playTitleEffects(); // Reproduce efectos visuales/sonoros del título
void updateDustSprites(float delta_time); // Actualiza los sprites de polvo (time-based)
};

View File

@@ -1,9 +1,9 @@
#include "global_inputs.hpp"
#include <algorithm> // Para std::ranges::any_of
#include <algorithm> // Para __any_of_fn, any_of
#include <functional> // Para function
#include <memory> // Para allocator, shared_ptr
#include <string> // Para operator+, char_traits, string, to_string
#include <iterator> // Para pair
#include <string> // Para basic_string, operator+, allocator, char_traits, string, to_string
#include <utility> // Para pair
#include <vector> // Para vector

View File

@@ -1,13 +1,14 @@
#include "input.hpp"
#include <SDL3/SDL.h> // Para SDL_GamepadButton, SDL_GetGamepadAxis, SDL_GetError, SDL_GamepadAxis, SDL_JoystickID, SDL_AddGamepadMappingsFromFile, SDL_Event, SDL_EventType, SDL_GetGamepadButton, SDL_GetKeyboardState, SDL_INIT_GAMEPAD, SDL_InitSubSystem, SDL_LogCategory, SDL_LogError, SDL_LogInfo, SDL_OpenGamepad, SDL_PollEvent, SDL_WasInit, SDL_Gamepad, SDL_Scancode
#include <SDL3/SDL.h> // Para SDL_GetGamepadAxis, SDL_GamepadAxis, SDL_GamepadButton, SDL_GetError, SDL_JoystickID, SDL_AddGamepadMappingsFromFile, SDL_Event, SDL_EventType, SDL_GetGamepadButton, SDL_GetKeyboardState, SDL_INIT_GAMEPAD, SDL_InitSubSystem, SDL_LogError, SDL_OpenGamepad, SDL_PollEvent, SDL_WasInit, Sint16, SDL_Gamepad, SDL_LogCategory, SDL_Scancode
#include <algorithm> // Para find_if, remove_if
#include <iostream> // Para basic_ostream, operator<<, endl, cout, cerr
#include <iostream> // Para basic_ostream, operator<<, cout, cerr
#include <memory> // Para shared_ptr, __shared_ptr_access, allocator, operator==, make_shared
#include <unordered_map> // Para unordered_map, operator==, _Node_iterator_base, _Node_iterator, _Node_const_iterator
#include <ranges> // Para __find_if_fn, find_if
#include <unordered_map> // Para unordered_map, _Node_iterator, operator==, _Node_iterator_base, _Node_const_iterator
#include <utility> // Para pair, move
#include "ui/logger.hpp"
#include "ui/logger.hpp" // Para info
// Singleton
Input* Input::instance = nullptr;

View File

@@ -1,15 +1,16 @@
#pragma once
#include <SDL3/SDL.h> // Para SDL_Scancode, SDL_GamepadButton, SDL_JoystickID, SDL_CloseGamepad, SDL_Gamepad, SDL_GetGamepadJoystick, SDL_GetGamepadName, SDL_GetGamepadPath, SDL_GetJoystickID, Uint8, SDL_Event, Sint16
#include <SDL3/SDL.h> // Para SDL_Scancode, SDL_GamepadButton, SDL_JoystickID, SDL_CloseGamepad, SDL_Gamepad, SDL_GetGamepadJoystick, SDL_GetGamepadName, SDL_GetGamepadPath, SDL_GetJoystickID, Sint16, Uint8, SDL_Event
#include <array> // Para array
#include <memory> // Para shared_ptr, allocator
#include <string> // Para string
#include <memory> // Para shared_ptr
#include <string> // Para string, basic_string
#include <unordered_map> // Para unordered_map
#include <utility> // Para pair
#include <vector> // Para vector
#include "gamepad_config_manager.hpp" // Para GamepadConfig (ptr only), GamepadConfigs
#include "input_types.hpp" // Para InputAction
#include "gamepad_config_manager.hpp" // for GamepadConfig (ptr only), GamepadConfigs
#include "input_types.hpp" // for InputAction
// --- Clase Input: gestiona la entrada de teclado y mandos (singleton) ---
class Input {

View File

@@ -1,5 +1,7 @@
#include "input_types.hpp"
#include <utility> // Para pair
// Definición de los mapas
const std::unordered_map<InputAction, std::string> ACTION_TO_STRING = {
{InputAction::FIRE_LEFT, "FIRE_LEFT"},

View File

@@ -29,14 +29,14 @@ Item::Item(ItemType type, float x, float y, SDL_FRect& play_area, const std::sha
pos_x_ = x;
pos_y_ = y;
// 6 velocidades: 3 negativas (-1.0, -0.66, -0.33) y 3 positivas (0.33, 0.66, 1.0)
const int direction = rand() % 6;
if (direction < 3) {
const int DIRECTION = rand() % 6;
if (DIRECTION < 3) {
// Velocidades negativas: -1.0, -0.66, -0.33
vel_x_ = -ITEM_VEL_X_BASE + (direction * ITEM_VEL_X_STEP);
vel_x_ = -ITEM_VEL_X_BASE + (DIRECTION * ITEM_VEL_X_STEP);
rotate_speed_ = -720.0F;
} else {
// Velocidades positivas: 0.33, 0.66, 1.0
vel_x_ = ITEM_VEL_X_STEP + ((direction - 3) * ITEM_VEL_X_STEP);
vel_x_ = ITEM_VEL_X_STEP + ((DIRECTION - 3) * ITEM_VEL_X_STEP);
rotate_speed_ = 720.0F;
}
vel_y_ = ITEM_VEL_Y;
@@ -71,33 +71,33 @@ void Item::alignTo(int x) {
void Item::render() {
if (enabled_) {
// Muestra normalmente hasta los últimos ~3.3 segundos
constexpr float BLINK_START_S = LIFETIME_DURATION_S - 3.33f;
constexpr float BLINK_START_S = LIFETIME_DURATION_S - 3.33F;
if (lifetime_timer_ < BLINK_START_S) {
sprite_->render();
} else {
// Efecto de parpadeo en los últimos segundos (cada ~0.33 segundos)
constexpr float BLINK_INTERVAL_S = 0.33f;
const float phase = fmod(lifetime_timer_, BLINK_INTERVAL_S);
const float half_interval = BLINK_INTERVAL_S / 2.0f;
constexpr float BLINK_INTERVAL_S = 0.33F;
const float PHASE = std::fmod(lifetime_timer_, BLINK_INTERVAL_S);
const float HALF_INTERVAL = BLINK_INTERVAL_S / 2.0F;
if (phase < half_interval) {
if (PHASE < HALF_INTERVAL) {
sprite_->render();
}
}
}
}
void Item::move(float deltaTime) {
void Item::move(float delta_time) {
floor_collision_ = false;
// Calcula la nueva posición usando deltaTime (velocidad en pixels/segundo)
pos_x_ += vel_x_ * deltaTime;
pos_y_ += vel_y_ * deltaTime;
pos_x_ += vel_x_ * delta_time;
pos_y_ += vel_y_ * delta_time;
// Aplica las aceleraciones a la velocidad usando deltaTime (aceleración en pixels/segundo²)
vel_x_ += accel_x_ * deltaTime;
vel_y_ += accel_y_ * deltaTime;
vel_x_ += accel_x_ * delta_time;
vel_y_ += accel_y_ * delta_time;
// Comprueba los laterales de la zona de juego
const float MIN_X = param.game.play_area.rect.x;
@@ -160,14 +160,14 @@ void Item::move(float deltaTime) {
void Item::disable() { enabled_ = false; }
void Item::update(float deltaTime) {
move(deltaTime);
sprite_->update(deltaTime);
updateTimeToLive(deltaTime);
void Item::update(float delta_time) {
move(delta_time);
sprite_->update(delta_time);
updateTimeToLive(delta_time);
}
void Item::updateTimeToLive(float deltaTime) {
lifetime_timer_ += deltaTime;
void Item::updateTimeToLive(float delta_time) {
lifetime_timer_ += delta_time;
if (lifetime_timer_ >= LIFETIME_DURATION_S) {
disable();
}

View File

@@ -31,7 +31,7 @@ class Item {
static constexpr float HEIGHT = 20.0F; // ALtura del item
static constexpr int COFFEE_MACHINE_WIDTH = 30; // Anchura de la máquina de café
static constexpr int COFFEE_MACHINE_HEIGHT = 39; // Altura de la máquina de café
static constexpr float LIFETIME_DURATION_S = 10.0f; // Duración de vida del ítem en segundos
static constexpr float LIFETIME_DURATION_S = 10.0F; // Duración de vida del ítem en segundos
// Velocidades base (pixels/segundo) - Coffee Machine
static constexpr float COFFEE_MACHINE_VEL_X_FACTOR = 30.0F; // Factor para velocidad X de máquina de café (0.5*60fps)
@@ -55,10 +55,10 @@ class Item {
~Item() = default; // Destructor
// --- Métodos principales ---
void alignTo(int x); // Centra el objeto en la posición X indicada
void render(); // Renderiza el objeto en pantalla
void disable(); // Desactiva el objeto
void update(float deltaTime); // Actualiza la posición, animación y contadores (time-based)
void alignTo(int x); // Centra el objeto en la posición X indicada
void render(); // Renderiza el objeto en pantalla
void disable(); // Desactiva el objeto
void update(float delta_time); // Actualiza la posición, animación y contadores (time-based)
// --- Getters ---
[[nodiscard]] auto getPosX() const -> float { return pos_x_; } // Obtiene la posición X
@@ -87,14 +87,14 @@ class Item {
float width_ = WIDTH; // Ancho del objeto
float height_ = HEIGHT; // Alto del objeto
float rotate_speed_ = 0.0F; // Velocidad de rotacion
float lifetime_timer_ = 0.0f; // Acumulador de tiempo de vida del ítem (segundos)
float lifetime_timer_ = 0.0F; // Acumulador de tiempo de vida del ítem (segundos)
bool floor_collision_ = false; // Indica si el objeto colisiona con el suelo
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(float deltaTime); // Actualiza la posición y estados del objeto (time-based)
void updateTimeToLive(float deltaTime); // Actualiza el contador de tiempo de vida (time-based)
void move(float delta_time); // Actualiza la posición y estados del objeto (time-based)
void updateTimeToLive(float delta_time); // Actualiza el contador de tiempo de vida (time-based)
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,12 +1,15 @@
#include "manage_hiscore_table.hpp"
#include <SDL3/SDL.h> // Para SDL_ReadIO, SDL_WriteIO, SDL_CloseIO, SDL_GetError, SDL_IOFromFile, SDL_LogCategory, SDL_LogError, SDL_LogInfo
#include <SDL3/SDL.h> // Para SDL_ReadIO, SDL_WriteIO, SDL_CloseIO, SDL_GetError, SDL_IOFromFile, SDL_LogError, SDL_LogCategory, SDL_LogInfo
#include <algorithm> // Para find_if, sort
#include <iterator> // Para distance
#include <algorithm> // Para __sort_fn, sort
#include <functional> // Para identity
#include <iterator> // Para distance
#include <ranges> // Para __find_if_fn, find_if
#include <utility> // Para move
#include "utils.hpp" // Para getFileName
#include "ui/logger.hpp"
#include "ui/logger.hpp" // Para info
#include "utils.hpp" // Para getFileName
// Resetea la tabla a los valores por defecto
void ManageHiScoreTable::clear() {
@@ -170,7 +173,7 @@ auto ManageHiScoreTable::saveToFile(const std::string& file_path) -> bool {
SDL_WriteIO(file, &occ_value, sizeof(int));
}
//SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "Writing file: %s", getFileName(file_path).c_str());
// SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "Writing file: %s", getFileName(file_path).c_str());
Logger::info("Writing file: " + getFileName(file_path));
SDL_CloseIO(file);
} else {

View File

@@ -55,23 +55,23 @@ void MovingSprite::stop() {
}
// Mueve el sprite (time-based)
void MovingSprite::move(float deltaTime) {
void MovingSprite::move(float delta_time) {
// DeltaTime puro: velocidad (pixels/ms) * tiempo (ms)
x_ += vx_ * deltaTime;
y_ += vy_ * deltaTime;
x_ += vx_ * delta_time;
y_ += vy_ * delta_time;
// Aceleración (pixels/ms²) * tiempo (ms)
vx_ += ax_ * deltaTime;
vy_ += ay_ * deltaTime;
vx_ += ax_ * delta_time;
vy_ += ay_ * delta_time;
pos_.x = static_cast<int>(x_);
pos_.y = static_cast<int>(y_);
}
// Actualiza las variables internas del objeto (time-based)
void MovingSprite::update(float deltaTime) {
move(deltaTime);
rotate(deltaTime);
void MovingSprite::update(float delta_time) {
move(delta_time);
rotate(delta_time);
}
// Muestra el sprite por pantalla
@@ -80,9 +80,9 @@ void MovingSprite::render() {
}
// Establece la rotacion (time-based)
void MovingSprite::rotate(float deltaTime) {
void MovingSprite::rotate(float delta_time) {
if (rotate_.enabled) {
rotate_.angle += rotate_.amount * deltaTime;
rotate_.angle += rotate_.amount * delta_time;
}
}

View File

@@ -2,10 +2,9 @@
#include <SDL3/SDL.h> // Para SDL_FlipMode, SDL_FPoint, SDL_FRect
#include <algorithm> // Para max
#include <memory> // Para shared_ptr
#include <memory> // Para shared_ptr
#include "sprite.hpp" // Para Sprite
#include "sprite.hpp" // for Sprite
class Texture;
@@ -27,10 +26,10 @@ class MovingSprite : public Sprite {
~MovingSprite() override = default;
// --- Métodos principales ---
virtual void update(float deltaTime); // Actualiza las variables internas del objeto (time-based)
void clear() override; // Reinicia todas las variables a cero
void stop(); // Elimina el movimiento del sprite
void render() override; // Muestra el sprite por pantalla
virtual void update(float delta_time); // Actualiza las variables internas del objeto (time-based)
void clear() override; // Reinicia todas las variables a cero
void stop(); // Elimina el movimiento del 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
@@ -79,6 +78,6 @@ class MovingSprite : public Sprite {
// --- Métodos internos ---
void updateAngle() { rotate_.angle += rotate_.amount; } // Incrementa el valor del ángulo
void move(float deltaTime); // Mueve el sprite según velocidad y aceleración (time-based)
void rotate(float deltaTime); // Rota el sprite según los parámetros de rotación (time-based)
void move(float delta_time); // Mueve el sprite según velocidad y aceleración (time-based)
void rotate(float delta_time); // Rota el sprite según los parámetros de rotación (time-based)
};

View File

@@ -1,24 +1,23 @@
#include "options.hpp"
#include <SDL3/SDL.h> // Para SDL_ScaleMode, SDL_GamepadButton, SDL_LogCategory, SDL_LogInfo, SDL_LogError, SDL_LogWarn
#include <SDL3/SDL.h> // Para SDL_ScaleMode, SDL_LogCategory, SDL_LogError, SDL_LogInfo, SDL_LogWarn
#include <algorithm> // Para clamp, max
#include <algorithm> // Para clamp, __any_of_fn, any_of
#include <cstddef> // Para size_t
#include <fstream> // Para basic_ostream, operator<<, basic_ostream::operator<<, basic_ofstream, basic_istream, basic_ifstream, ifstream, ofstream
#include <fstream> // Para basic_ostream, operator<<, basic_ofstream, basic_ostream::operator<<, basic_istream, basic_ifstream, ifstream, istringstream, ofstream
#include <functional> // Para function
#include <map> // Para map, operator==, _Rb_tree_const_iterator
#include <ranges> // Para std::ranges::any_of
#include <sstream> // Para istringstream
#include <sstream> // Para basic_istringstream
#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
#include <string> // Para char_traits, basic_string, stoi, string, operator<<, operator+, operator==, operator>>, getline, operator<=>, to_string
#include <utility> // Para pair
#include <vector> // Para vector
#include "difficulty.hpp" // Para Code, init
#include "input.hpp" // Para InputDevice
#include "lang.hpp" // Para Code
#include "ui/logger.hpp" // Para Logger
#include "utils.hpp" // Para boolToString, stringToBool, getFileName
#include "input.hpp" // Para Input
#include "lang.hpp" // Para getText, Code
#include "ui/logger.hpp" // Para info
#include "utils.hpp" // Para stringToBool, boolToString, getFileName
namespace Options {
// --- Variables globales ---
@@ -116,7 +115,7 @@ auto saveToFile() -> bool {
return false;
}
//SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "Writing file: %s", getFileName(settings.config_file).c_str());
// SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "Writing file: %s", getFileName(settings.config_file).c_str());
Logger::info("Writing file: " + getFileName(settings.config_file));
applyPendingChanges();

View File

@@ -2,24 +2,23 @@
#include <SDL3/SDL.h> // Para SDL_ScaleMode
#include <algorithm> // Para copy
#include <array> // Para array
#include <cstddef> // Para size_t
#include <exception> // Para exception
#include <fstream> // Para basic_ostream, operator<<, basic_ofstream, basic_ostream::operator<<, ofstream
#include <memory> // Para shared_ptr, swap
#include <memory> // Para shared_ptr, __shared_ptr_access, swap
#include <stdexcept> // Para out_of_range, invalid_argument
#include <string> // Para char_traits, string, allocator, operator==, swap, operator<<, basic_string, stoi
#include <string> // Para char_traits, basic_string, string, operator==, operator<<, swap, stoi
#include <string_view> // Para string_view
#include <utility> // Para swap
#include <utility> // Para move
#include <vector> // Para vector
#include "defaults.hpp" // Para GameDefaults
#include "difficulty.hpp" // Para Code
#include "input.hpp" // Para Input
#include "lang.hpp" // Para Code
#include "manage_hiscore_table.hpp" // Para ManageHiScoreTable, Table
#include "player.hpp" // Para Player
#include "defaults.hpp" // for AUDIO_ENABLED, AUDIO_VOLUME, MUSIC_ENABLED, MUSIC_VOLUME, PARAMS_FILE, SETTINGS_AUTOFIRE, SETTINGS_SHUTDOWN_ENABLED, SOUND_ENABLED, SOUND_VOLUME, VIDEO_FULLSCREEN, VIDEO_INTEGER_SCALE, VIDEO_SCALE_MODE, VIDEO_SHADERS, VIDEO_VSYNC, WINDOW_CAPTION, WINDOW_MAX_ZOOM, WINDOW_ZOOM
#include "difficulty.hpp" // for Code
#include "input.hpp" // for Input
#include "lang.hpp" // for Code
#include "manage_hiscore_table.hpp" // for ManageHiScoreTable, Table
#include "player.hpp" // for Player
// --- Namespace Options: gestión de configuración y opciones del juego ---
namespace Options {

View File

@@ -1,18 +1,19 @@
#include "param.hpp"
#include <SDL3/SDL.h> // Para SDL_LogCategory, SDL_LogError, SDL_LogInfo
#include <SDL3/SDL.h> // Para SDL_LogWarn, SDL_LogCategory, SDL_LogError
#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 <unordered_map>
#include <fstream> // Para basic_istream, basic_ifstream, ifstream, istringstream
#include <functional> // Para function
#include <sstream> // Para basic_istringstream
#include <stdexcept> // Para runtime_error
#include <string> // Para string, basic_string, stoi, stof, hash, allocator, operator==, char_traits, operator+, operator>>, getline
#include <unordered_map> // Para unordered_map, operator==, _Node_iterator_base
#include <utility> // Para pair
#include "color.hpp"
#include "ui/notifier.hpp" // Para Notifier::Position
#include "utils.hpp"
#include "ui/logger.hpp" // Para Logger
#include "color.hpp" // Para Color
#include "ui/logger.hpp" // Para info, YELLOW
#include "ui/notifier.hpp" // Para Notifier
#include "utils.hpp" // Para Zone, stringToBool, getFileName
// Variable global - ahora se inicializa automáticamente con valores por defecto
Param param;
@@ -53,7 +54,7 @@ void loadParamsFromFile(const std::string& file_path) {
throw std::runtime_error("No se pudo abrir el archivo: " + file_path);
}
//SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "\nReading file: %s", getFileName(file_path).c_str());
// SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "\nReading file: %s", getFileName(file_path).c_str());
Logger::info("Reading file: " + getFileName(file_path));
std::string line;
@@ -202,37 +203,37 @@ auto setParams(const std::string& var, const std::string& value) -> bool {
{"red", true},
{"green", true}};
auto validateBalloonColor = [](const std::string& color) -> bool {
auto validate_balloon_color = [](const std::string& color) -> bool {
return VALID_BALLOON_COLORS.find(color) != VALID_BALLOON_COLORS.end();
};
static const std::unordered_map<std::string, std::function<void(const std::string&)>> STRING_PARAMS = {
{"balloon.color[0]", [validateBalloonColor](const std::string& v) {
if (!validateBalloonColor(v)) {
{"balloon.color[0]", [validate_balloon_color](const std::string& v) {
if (!validate_balloon_color(v)) {
SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION, "Color de globo inválido '%s'. Usando 'blue' por defecto.", v.c_str());
param.balloon.color.at(0) = "blue";
} else {
param.balloon.color.at(0) = v;
}
}},
{"balloon.color[1]", [validateBalloonColor](const std::string& v) {
if (!validateBalloonColor(v)) {
{"balloon.color[1]", [validate_balloon_color](const std::string& v) {
if (!validate_balloon_color(v)) {
SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION, "Color de globo inválido '%s'. Usando 'orange' por defecto.", v.c_str());
param.balloon.color.at(1) = "orange";
} else {
param.balloon.color.at(1) = v;
}
}},
{"balloon.color[2]", [validateBalloonColor](const std::string& v) {
if (!validateBalloonColor(v)) {
{"balloon.color[2]", [validate_balloon_color](const std::string& v) {
if (!validate_balloon_color(v)) {
SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION, "Color de globo inválido '%s'. Usando 'red' por defecto.", v.c_str());
param.balloon.color.at(2) = "red";
} else {
param.balloon.color.at(2) = v;
}
}},
{"balloon.color[3]", [validateBalloonColor](const std::string& v) {
if (!validateBalloonColor(v)) {
{"balloon.color[3]", [validate_balloon_color](const std::string& v) {
if (!validate_balloon_color(v)) {
SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION, "Color de globo inválido '%s'. Usando 'green' por defecto.", v.c_str());
param.balloon.color.at(3) = "green";
} else {

View File

@@ -1,6 +1,7 @@
// IWYU pragma: no_include <bits/std_abs.h>
#include "path_sprite.hpp"
#include <cmath> // Para abs
#include <functional> // Para function
#include <utility> // Para move
@@ -75,32 +76,32 @@ void PathSprite::addPath(Path path, bool centered) {
switch (path_centered) {
case PathCentered::ON_X: {
// Centrar en el eje X (para paths Verticales)
const float X_offset = pos_.w / 2.0f; // Asume que pos_.w está inicializado por el constructor de Sprite
const float X_OFFSET = pos_.w / 2.0F; // Asume que pos_.w está inicializado por el constructor de Sprite
if (path.is_point_path) {
const float X_base = !path.spots.empty() ? path.spots.front().x : 0.0f;
const float X = X_base - X_offset;
const float X_BASE = !path.spots.empty() ? path.spots.front().x : 0.0F;
const float X = X_BASE - X_OFFSET;
for (auto& spot : path.spots) {
spot.x = X;
}
} else {
// Es un path generado, ajustamos la posición fija (que es X)
path.fixed_pos -= X_offset;
path.fixed_pos -= X_OFFSET;
}
paths_.emplace_back(std::move(path)); // Usamos std::move
break;
}
case PathCentered::ON_Y: {
// Centrar en el eje Y (para paths Horizontales)
const float Y_offset = pos_.h / 2.0f; // Asume que pos_.h está inicializado
const float Y_OFFSET = pos_.h / 2.0F; // Asume que pos_.h está inicializado
if (path.is_point_path) {
const float Y_base = !path.spots.empty() ? path.spots.front().y : 0.0f;
const float Y = Y_base - Y_offset;
const float Y_BASE = !path.spots.empty() ? path.spots.front().y : 0.0F;
const float Y = Y_BASE - Y_OFFSET;
for (auto& spot : path.spots) {
spot.y = Y;
}
} else {
// Es un path generado, ajustamos la posición fija (que es Y)
path.fixed_pos -= Y_offset;
path.fixed_pos -= Y_OFFSET;
}
paths_.emplace_back(std::move(path)); // Usamos std::move
break;
@@ -139,9 +140,9 @@ void PathSprite::enable() {
// Para paths generados, establecer posición inicial
SDL_FPoint initial_pos;
if (path.type == PathType::HORIZONTAL) {
initial_pos = {path.start_pos, path.fixed_pos};
initial_pos = {.x = path.start_pos, .y = path.fixed_pos};
} else {
initial_pos = {path.fixed_pos, path.start_pos};
initial_pos = {.x = path.fixed_pos, .y = path.start_pos};
}
setPosition(initial_pos);
}
@@ -177,8 +178,8 @@ void PathSprite::moveThroughCurrentPath(float delta_time) {
// Calcular progreso (0.0 a 1.0)
float progress = path.elapsed_time / path.duration_s;
if (progress >= 1.0f) {
progress = 1.0f;
if (progress >= 1.0F) {
progress = 1.0F;
path.on_destination = true;
}
@@ -186,14 +187,14 @@ void PathSprite::moveThroughCurrentPath(float delta_time) {
double eased_progress = path.easing_function(progress);
// Calcular posición actual
float current_pos = path.start_pos + (path.end_pos - path.start_pos) * static_cast<float>(eased_progress);
float current_pos = path.start_pos + ((path.end_pos - path.start_pos) * static_cast<float>(eased_progress));
// Establecer posición según el tipo
SDL_FPoint position;
if (path.type == PathType::HORIZONTAL) {
position = {current_pos, path.fixed_pos};
position = {.x = current_pos, .y = path.fixed_pos};
} else {
position = {path.fixed_pos, current_pos};
position = {.x = path.fixed_pos, .y = current_pos};
}
setPosition(position);
} else {

View File

@@ -32,8 +32,8 @@ struct Path { // Define un recorrido p
float duration_s; // Duración de la animación en segundos
float waiting_time_s; // Tiempo de espera una vez en el destino
std::function<double(double)> easing_function; // Función de easing
float elapsed_time = 0.0f; // Tiempo transcurrido
float waiting_elapsed = 0.0f; // Tiempo de espera transcurrido
float elapsed_time = 0.0F; // Tiempo transcurrido
float waiting_elapsed = 0.0F; // Tiempo de espera transcurrido
bool on_destination = false; // Indica si ha llegado al destino
bool finished = false; // Indica si ha terminado de esperarse
@@ -73,8 +73,8 @@ class PathSprite : public Sprite {
// --- Gestión de recorridos ---
void addPath(Path path, bool centered = false); // Añade un recorrido (Path)
void addPath(const std::vector<SDL_FPoint>& spots, float waiting_time_s = 0.0f); // Añade un recorrido a partir de puntos
void addPath(float start, float end, PathType type, float fixed_pos, float duration_s, const std::function<double(double)>& easing_function, float waiting_time_s = 0.0f); // Añade un recorrido generado
void addPath(const std::vector<SDL_FPoint>& spots, float waiting_time_s = 0.0F); // Añade un recorrido a partir de puntos
void addPath(float start, float end, PathType type, float fixed_pos, float duration_s, const std::function<double(double)>& easing_function, float waiting_time_s = 0.0F); // Añade un recorrido generado
// --- Estado y control ---
void enable(); // Habilita el objeto

View File

@@ -1,6 +1,6 @@
#include "player.hpp"
#include <SDL3/SDL.h> // Para SDL_GetTicks, SDL_FlipMode
#include <SDL3/SDL.h> // Para SDL_FlipMode
#include <algorithm> // Para clamp, max, min
#include <cmath> // Para fmod
@@ -14,12 +14,8 @@
#include "manage_hiscore_table.hpp" // Para ManageHiScoreTable, HiScoreEntry
#include "param.hpp" // Para Param, ParamGame, param
#include "scoreboard.hpp" // Para Scoreboard
#include "stage.hpp" // Para power_can_be_added
#include "stage_interface.hpp" // Para IStageInfo
#include "texture.hpp" // Para Texture
#ifdef _DEBUG
#include <iostream>
#endif
// Constructor
Player::Player(const Config& config)
@@ -61,8 +57,8 @@ void Player::init() {
extra_hit_ = false;
coffees_ = 0;
continue_counter_ = 10;
name_entry_idle_time_accumulator_ = 0.0f;
name_entry_total_time_accumulator_ = 0.0f;
name_entry_idle_time_accumulator_ = 0.0F;
name_entry_total_time_accumulator_ = 0.0F;
shiftColliders();
vel_x_ = 0;
vel_y_ = 0;
@@ -146,37 +142,37 @@ void Player::setInputEnteringName(Input::Action action) {
default:
break;
}
name_entry_idle_time_accumulator_ = 0.0f;
name_entry_idle_time_accumulator_ = 0.0F;
}
// Sistema de movimiento
void Player::move(float deltaTime) {
void Player::move(float delta_time) {
switch (playing_state_) {
case State::PLAYING:
handlePlayingMovement(deltaTime);
handlePlayingMovement(delta_time);
break;
case State::ROLLING:
handleRollingMovement();
break;
case State::TITLE_ANIMATION:
handleTitleAnimation(deltaTime);
handleTitleAnimation(delta_time);
break;
case State::CONTINUE_TIME_OUT:
handleContinueTimeOut();
break;
case State::LEAVING_SCREEN:
updateStepCounter(deltaTime);
handleLeavingScreen(deltaTime);
updateStepCounter(delta_time);
handleLeavingScreen(delta_time);
break;
case State::ENTERING_SCREEN:
updateStepCounter(deltaTime);
handleEnteringScreen(deltaTime);
updateStepCounter(delta_time);
handleEnteringScreen(delta_time);
break;
case State::CREDITS:
handleCreditsMovement(deltaTime);
handleCreditsMovement(delta_time);
break;
case State::WAITING:
handleWaitingMovement(deltaTime);
handleWaitingMovement(delta_time);
break;
case State::RECOVER:
handleRecoverMovement();
@@ -187,9 +183,9 @@ void Player::move(float deltaTime) {
}
// Movimiento time-based durante el juego
void Player::handlePlayingMovement(float deltaTime) {
void Player::handlePlayingMovement(float delta_time) {
// Mueve el jugador a derecha o izquierda (time-based en segundos)
pos_x_ += vel_x_ * deltaTime;
pos_x_ += vel_x_ * delta_time;
// Si el jugador abandona el area de juego por los laterales, restaura su posición
const float MIN_X = play_area_.x - 5;
@@ -253,10 +249,10 @@ void Player::handleRollingBounce() {
playSound("jump.wav");
}
void Player::handleTitleAnimation(float deltaTime) {
void Player::handleTitleAnimation(float delta_time) {
setInputBasedOnPlayerId();
pos_x_ += (vel_x_ * 2.0F) * deltaTime;
pos_x_ += (vel_x_ * 2.0F) * delta_time;
const float MIN_X = -WIDTH;
const float MAX_X = play_area_.w;
pos_x_ = std::clamp(pos_x_, MIN_X, MAX_X);
@@ -275,11 +271,11 @@ void Player::handleContinueTimeOut() {
}
}
void Player::handleLeavingScreen(float deltaTime) {
void Player::handleLeavingScreen(float delta_time) {
// updateStepCounter se llama desde move() con deltaTime
setInputBasedOnPlayerId();
pos_x_ += vel_x_ * deltaTime;
pos_x_ += vel_x_ * delta_time;
const float MIN_X = -WIDTH;
const float MAX_X = play_area_.w;
pos_x_ = std::clamp(pos_x_, MIN_X, MAX_X);
@@ -290,15 +286,15 @@ void Player::handleLeavingScreen(float deltaTime) {
}
}
void Player::handleEnteringScreen(float deltaTime) {
void Player::handleEnteringScreen(float delta_time) {
// updateStepCounter se llama desde move() con deltaTime
switch (id_) {
case Id::PLAYER1:
handlePlayer1Entering(deltaTime);
handlePlayer1Entering(delta_time);
break;
case Id::PLAYER2:
handlePlayer2Entering(deltaTime);
handlePlayer2Entering(delta_time);
break;
default:
break;
@@ -307,18 +303,18 @@ void Player::handleEnteringScreen(float deltaTime) {
shiftSprite();
}
void Player::handlePlayer1Entering(float deltaTime) {
void Player::handlePlayer1Entering(float delta_time) {
setInputPlaying(Input::Action::RIGHT);
pos_x_ += vel_x_ * deltaTime;
pos_x_ += vel_x_ * delta_time;
if (pos_x_ > default_pos_x_) {
pos_x_ = default_pos_x_;
setPlayingState(State::PLAYING);
}
}
void Player::handlePlayer2Entering(float deltaTime) {
void Player::handlePlayer2Entering(float delta_time) {
setInputPlaying(Input::Action::LEFT);
pos_x_ += vel_x_ * deltaTime;
pos_x_ += vel_x_ * delta_time;
if (pos_x_ < default_pos_x_) {
pos_x_ = default_pos_x_;
setPlayingState(State::PLAYING);
@@ -326,8 +322,8 @@ void Player::handlePlayer2Entering(float deltaTime) {
}
// Movimiento general en la pantalla de créditos (time-based)
void Player::handleCreditsMovement(float deltaTime) {
pos_x_ += (vel_x_ / 2.0F) * deltaTime;
void Player::handleCreditsMovement(float delta_time) {
pos_x_ += (vel_x_ / 2.0F) * delta_time;
if (vel_x_ > 0) {
handleCreditsRightMovement();
@@ -354,11 +350,11 @@ void Player::handleCreditsLeftMovement() {
}
// Controla la animación del jugador saludando (time-based)
void Player::handleWaitingMovement(float deltaTime) {
waiting_time_accumulator_ += deltaTime;
const float WAITING_DURATION_S = static_cast<float>(WAITING_COUNTER) / 60.0f; // Convert frames to seconds
void Player::handleWaitingMovement(float delta_time) {
waiting_time_accumulator_ += delta_time;
const float WAITING_DURATION_S = static_cast<float>(WAITING_COUNTER) / 60.0F; // Convert frames to seconds
if (waiting_time_accumulator_ >= WAITING_DURATION_S) {
waiting_time_accumulator_ = 0.0f;
waiting_time_accumulator_ = 0.0F;
player_sprite_->resetAnimation();
}
}
@@ -385,11 +381,11 @@ void Player::setInputBasedOnPlayerId() {
}
// Incrementa o ajusta el contador de pasos (time-based)
void Player::updateStepCounter(float deltaTime) {
step_time_accumulator_ += deltaTime;
const float STEP_INTERVAL_S = 10.0f / 60.0f; // 10 frames converted to seconds
void Player::updateStepCounter(float delta_time) {
step_time_accumulator_ += delta_time;
const float STEP_INTERVAL_S = 10.0F / 60.0F; // 10 frames converted to seconds
if (step_time_accumulator_ >= STEP_INTERVAL_S) {
step_time_accumulator_ = 0.0f;
step_time_accumulator_ = 0.0F;
playSound("walk.wav");
}
}
@@ -460,7 +456,7 @@ auto Player::computeAnimation() const -> std::pair<std::string, SDL_FlipMode> {
}
// Establece la animación correspondiente al estado
void Player::setAnimation(float deltaTime) {
void Player::setAnimation(float delta_time) {
switch (playing_state_) {
case State::PLAYING:
case State::ENTERING_SCREEN:
@@ -497,22 +493,22 @@ void Player::setAnimation(float deltaTime) {
}
// La diferencia clave: usa deltaTime para las animaciones
player_sprite_->update(deltaTime);
power_sprite_->update(deltaTime);
player_sprite_->update(delta_time);
power_sprite_->update(delta_time);
}
// Actualiza al jugador con deltaTime (time-based)
void Player::update(float deltaTime) {
move(deltaTime); // Sistema de movimiento time-based
setAnimation(deltaTime); // Animaciones time-based
shiftColliders(); // Sin cambios (posicional)
updateFireSystem(deltaTime); // Sistema de disparo de dos líneas
updatePowerUp(deltaTime); // Sistema de power-up time-based
updateInvulnerable(deltaTime); // Sistema de invulnerabilidad time-based
updateScoreboard(); // Sin cambios (no temporal)
updateContinueCounter(deltaTime); // Sistema de continue time-based
updateEnterNameCounter(deltaTime); // Sistema de name entry time-based
updateShowingName(deltaTime); // Sistema de showing name time-based
void Player::update(float delta_time) {
move(delta_time); // Sistema de movimiento time-based
setAnimation(delta_time); // Animaciones time-based
shiftColliders(); // Sin cambios (posicional)
updateFireSystem(delta_time); // Sistema de disparo de dos líneas
updatePowerUp(delta_time); // Sistema de power-up time-based
updateInvulnerable(delta_time); // Sistema de invulnerabilidad time-based
updateScoreboard(); // Sin cambios (no temporal)
updateContinueCounter(delta_time); // Sistema de continue time-based
updateEnterNameCounter(delta_time); // Sistema de name entry time-based
updateShowingName(delta_time); // Sistema de showing name time-based
}
void Player::passShowingName() {
@@ -584,7 +580,7 @@ void Player::setPlayingState(State state) {
case State::CONTINUE: {
// Inicializa el contador de continuar
continue_counter_ = 9;
continue_time_accumulator_ = 0.0f; // Initialize time accumulator
continue_time_accumulator_ = 0.0F; // Initialize time accumulator
playSound("continue_clock.wav");
setScoreboardMode(Scoreboard::Mode::CONTINUE);
break;
@@ -603,7 +599,7 @@ void Player::setPlayingState(State state) {
}
pos_y_ = default_pos_y_;
waiting_counter_ = 0;
waiting_time_accumulator_ = 0.0f; // Initialize time accumulator
waiting_time_accumulator_ = 0.0F; // Initialize time accumulator
shiftSprite();
player_sprite_->setCurrentAnimation("hello");
player_sprite_->animtionPause();
@@ -615,7 +611,7 @@ void Player::setPlayingState(State state) {
break;
}
case State::SHOWING_NAME: {
showing_name_time_accumulator_ = 0.0f; // Inicializar acumulador time-based
showing_name_time_accumulator_ = 0.0F; // Inicializar acumulador time-based
setScoreboardMode(Scoreboard::Mode::ENTER_TO_SHOW_NAME); // Iniciar animación de transición
Scoreboard::get()->setEnterName(scoreboard_panel_, last_enter_name_);
addScoreToScoreBoard();
@@ -624,7 +620,7 @@ void Player::setPlayingState(State state) {
case State::ROLLING: {
// Activa la animación de rodar dando botes
player_sprite_->setCurrentAnimation("rolling");
player_sprite_->setAnimationSpeed(4.0f / 60.0f); // 4 frames convertido a segundos
player_sprite_->setAnimationSpeed(4.0F / 60.0F); // 4 frames convertido a segundos
player_sprite_->setVelY(-396.0F); // Velocidad inicial (6.6 * 60 = 396 pixels/s)
player_sprite_->setAccelY(720.0F); // Gravedad (0.2 * 60² = 720 pixels/s²)
player_sprite_->setPosY(pos_y_ - 2); // Para "sacarlo" del suelo, ya que está hundido un pixel para ocultar el outline de los pies
@@ -648,7 +644,7 @@ void Player::setPlayingState(State state) {
player_sprite_->setVelY(-240.0F); // -4.0 * 60 = -240 pixels/s
player_sprite_->setVelX(0.0F);
player_sprite_->setCurrentAnimation("rolling");
player_sprite_->setAnimationSpeed(5.0f / 60.0f); // 5 frames convertido a segundos
player_sprite_->setAnimationSpeed(5.0F / 60.0F); // 5 frames convertido a segundos
setScoreboardMode(Scoreboard::Mode::GAME_OVER);
playSound("voice_aw_aw_aw.wav");
playSound("jump.wav");
@@ -671,14 +667,14 @@ void Player::setPlayingState(State state) {
}
case State::LEAVING_SCREEN: {
step_counter_ = 0;
step_time_accumulator_ = 0.0f; // Initialize time accumulator
step_time_accumulator_ = 0.0F; // Initialize time accumulator
setScoreboardMode(Scoreboard::Mode::GAME_COMPLETED);
break;
}
case State::ENTERING_SCREEN: {
init();
step_counter_ = 0;
step_time_accumulator_ = 0.0f; // Initialize time accumulator
step_time_accumulator_ = 0.0F; // Initialize time accumulator
setScoreboardMode(Scoreboard::Mode::SCORE);
switch (id_) {
case Id::PLAYER1:
@@ -719,25 +715,25 @@ void Player::decScoreMultiplier() {
void Player::setInvulnerable(bool value) {
invulnerable_ = value;
invulnerable_counter_ = invulnerable_ ? INVULNERABLE_COUNTER : 0;
invulnerable_time_accumulator_ = invulnerable_ ? static_cast<float>(INVULNERABLE_COUNTER) / 60.0f : 0.0f; // Convert frames to seconds
invulnerable_time_accumulator_ = invulnerable_ ? static_cast<float>(INVULNERABLE_COUNTER) / 60.0F : 0.0F; // Convert frames to seconds
}
// Monitoriza el estado (time-based)
void Player::updateInvulnerable(float deltaTime) {
void Player::updateInvulnerable(float delta_time) {
if (playing_state_ == State::PLAYING && invulnerable_) {
if (invulnerable_time_accumulator_ > 0) {
invulnerable_time_accumulator_ -= deltaTime;
invulnerable_time_accumulator_ -= delta_time;
// Frecuencia fija de parpadeo adaptada a deltaTime (en segundos)
constexpr float BLINK_PERIOD_S = 8.0f / 60.0f; // 8 frames convertidos a segundos
constexpr float BLINK_PERIOD_S = 8.0F / 60.0F; // 8 frames convertidos a segundos
// Calcula proporción decreciente basada en tiempo restante
const float TOTAL_INVULNERABLE_TIME_S = static_cast<float>(INVULNERABLE_COUNTER) / 60.0f;
float progress = 1.0f - (invulnerable_time_accumulator_ / TOTAL_INVULNERABLE_TIME_S);
float white_proportion = 0.5f - progress * 0.2f; // Menos blanco hacia el final
const float TOTAL_INVULNERABLE_TIME_S = static_cast<float>(INVULNERABLE_COUNTER) / 60.0F;
float progress = 1.0F - (invulnerable_time_accumulator_ / TOTAL_INVULNERABLE_TIME_S);
float white_proportion = 0.5F - (progress * 0.2F); // Menos blanco hacia el final
// Calcula si debe mostrar textura de invulnerabilidad basado en el ciclo temporal
float cycle_position = fmod(invulnerable_time_accumulator_, BLINK_PERIOD_S) / BLINK_PERIOD_S;
float cycle_position = std::fmod(invulnerable_time_accumulator_, BLINK_PERIOD_S) / BLINK_PERIOD_S;
bool should_show_invulnerable = cycle_position < white_proportion;
size_t target_texture = should_show_invulnerable ? INVULNERABLE_TEXTURE : coffees_;
@@ -758,17 +754,17 @@ void Player::updateInvulnerable(float deltaTime) {
void Player::setPowerUp() {
power_up_ = true;
power_up_counter_ = POWERUP_COUNTER;
power_up_time_accumulator_ = static_cast<float>(POWERUP_COUNTER) / 60.0f; // Convert frames to seconds
power_up_time_accumulator_ = static_cast<float>(POWERUP_COUNTER) / 60.0F; // Convert frames to seconds
power_sprite_visible_ = true; // Inicialmente visible cuando se activa el power-up
in_power_up_ending_phase_ = false; // Empezar en fase normal
bullet_color_toggle_ = false; // Resetear toggle
}
// Actualiza el valor de la variable (time-based)
void Player::updatePowerUp(float deltaTime) {
void Player::updatePowerUp(float delta_time) {
if (playing_state_ == State::PLAYING) {
if (power_up_) {
power_up_time_accumulator_ -= deltaTime;
power_up_time_accumulator_ -= delta_time;
power_up_ = power_up_time_accumulator_ > 0;
if (!power_up_) {
power_up_time_accumulator_ = 0;
@@ -778,8 +774,8 @@ void Player::updatePowerUp(float deltaTime) {
// Los colores ahora se manejan dinámicamente en getNextBulletColor()
} else {
// Calcular visibilidad del power sprite
const float TOTAL_POWERUP_TIME_S = static_cast<float>(POWERUP_COUNTER) / 60.0f;
const float QUARTER_TIME_S = TOTAL_POWERUP_TIME_S / 4.0f;
const float TOTAL_POWERUP_TIME_S = static_cast<float>(POWERUP_COUNTER) / 60.0F;
const float QUARTER_TIME_S = TOTAL_POWERUP_TIME_S / 4.0F;
if (power_up_time_accumulator_ > QUARTER_TIME_S) {
// En los primeros 75% del tiempo, siempre visible
@@ -787,10 +783,10 @@ void Player::updatePowerUp(float deltaTime) {
in_power_up_ending_phase_ = false;
} else {
// En el último 25%, parpadea cada 20 frames (≈0.333s)
constexpr float BLINK_PERIOD_S = 20.0f / 60.0f;
constexpr float VISIBLE_PROPORTION = 4.0f / 20.0f;
constexpr float BLINK_PERIOD_S = 20.0F / 60.0F;
constexpr float VISIBLE_PROPORTION = 4.0F / 20.0F;
float cycle_position = fmod(power_up_time_accumulator_, BLINK_PERIOD_S) / BLINK_PERIOD_S;
float cycle_position = std::fmod(power_up_time_accumulator_, BLINK_PERIOD_S) / BLINK_PERIOD_S;
power_sprite_visible_ = cycle_position >= VISIBLE_PROPORTION;
in_power_up_ending_phase_ = true; // Activar modo alternancia de colores de balas
}
@@ -836,10 +832,10 @@ void Player::setPlayerTextures(const std::vector<std::shared_ptr<Texture>>& text
}
// Actualiza el contador de continue (time-based)
void Player::updateContinueCounter(float deltaTime) {
void Player::updateContinueCounter(float delta_time) {
if (playing_state_ == State::CONTINUE) {
continue_time_accumulator_ += deltaTime;
constexpr float CONTINUE_INTERVAL_S = 1.0f; // 1 segundo
continue_time_accumulator_ += delta_time;
constexpr float CONTINUE_INTERVAL_S = 1.0F; // 1 segundo
if (continue_time_accumulator_ >= CONTINUE_INTERVAL_S) {
continue_time_accumulator_ -= CONTINUE_INTERVAL_S;
decContinueCounter();
@@ -848,10 +844,10 @@ void Player::updateContinueCounter(float deltaTime) {
}
// Actualiza el contador de entrar nombre (time-based)
void Player::updateEnterNameCounter(float deltaTime) {
void Player::updateEnterNameCounter(float delta_time) {
if (playing_state_ == State::ENTERING_NAME || playing_state_ == State::ENTERING_NAME_GAME_COMPLETED) {
name_entry_time_accumulator_ += deltaTime;
constexpr float NAME_ENTRY_INTERVAL_S = 1.0f; // 1 segundo
name_entry_time_accumulator_ += delta_time;
constexpr float NAME_ENTRY_INTERVAL_S = 1.0F; // 1 segundo
if (name_entry_time_accumulator_ >= NAME_ENTRY_INTERVAL_S) {
name_entry_time_accumulator_ -= NAME_ENTRY_INTERVAL_S;
decNameEntryCounter();
@@ -860,10 +856,10 @@ void Player::updateEnterNameCounter(float deltaTime) {
}
// Actualiza el estado de SHOWING_NAME (time-based)
void Player::updateShowingName(float deltaTime) {
void Player::updateShowingName(float delta_time) {
if (playing_state_ == State::SHOWING_NAME) {
showing_name_time_accumulator_ += deltaTime;
constexpr float SHOWING_NAME_DURATION_S = 5.0f; // 5 segundos
showing_name_time_accumulator_ += delta_time;
constexpr float SHOWING_NAME_DURATION_S = 5.0F; // 5 segundos
if (showing_name_time_accumulator_ >= SHOWING_NAME_DURATION_S) {
game_completed_ ? setPlayingState(State::LEAVING_SCREEN) : setPlayingState(State::CONTINUE);
}
@@ -872,7 +868,7 @@ void Player::updateShowingName(float deltaTime) {
// Decrementa el contador de continuar
void Player::decContinueCounter() {
continue_time_accumulator_ = 0.0f; // Reset time accumulator
continue_time_accumulator_ = 0.0F; // Reset time accumulator
--continue_counter_;
if (continue_counter_ < 0) {
setPlayingState(State::CONTINUE_TIME_OUT);
@@ -883,16 +879,16 @@ void Player::decContinueCounter() {
// Decrementa el contador de entrar nombre
void Player::decNameEntryCounter() {
name_entry_time_accumulator_ = 0.0f; // Reset time accumulator
name_entry_time_accumulator_ = 0.0F; // Reset time accumulator
// Incrementa acumuladores de tiempo (1 segundo)
name_entry_idle_time_accumulator_ += 1.0f;
name_entry_total_time_accumulator_ += 1.0f;
name_entry_idle_time_accumulator_ += 1.0F;
name_entry_total_time_accumulator_ += 1.0F;
if ((name_entry_total_time_accumulator_ >= param.game.name_entry_total_time) ||
(name_entry_idle_time_accumulator_ >= param.game.name_entry_idle_time)) {
name_entry_total_time_accumulator_ = 0.0f;
name_entry_idle_time_accumulator_ = 0.0f;
name_entry_total_time_accumulator_ = 0.0F;
name_entry_idle_time_accumulator_ = 0.0F;
if (playing_state_ == State::ENTERING_NAME) {
last_enter_name_ = getRecordName();
setPlayingState(State::SHOWING_NAME);
@@ -977,15 +973,15 @@ void Player::addCredit() {
// ========================================
// Método principal del sistema de disparo
void Player::updateFireSystem(float deltaTime) {
updateFunctionalLine(deltaTime); // Línea 1: CanFire
updateVisualLine(deltaTime); // Línea 2: Animaciones
void Player::updateFireSystem(float delta_time) {
updateFunctionalLine(delta_time); // Línea 1: CanFire
updateVisualLine(delta_time); // Línea 2: Animaciones
}
// LÍNEA 1: Sistema Funcional (CanFire)
void Player::updateFunctionalLine(float deltaTime) {
void Player::updateFunctionalLine(float delta_time) {
if (fire_cooldown_timer_ > 0) {
fire_cooldown_timer_ -= deltaTime;
fire_cooldown_timer_ -= delta_time;
can_fire_new_system_ = false;
} else {
fire_cooldown_timer_ = 0; // Evitar valores negativos
@@ -994,12 +990,12 @@ void Player::updateFunctionalLine(float deltaTime) {
}
// LÍNEA 2: Sistema Visual (Animaciones)
void Player::updateVisualLine(float deltaTime) {
void Player::updateVisualLine(float delta_time) {
if (visual_fire_state_ == VisualFireState::NORMAL) {
return; // No hay temporizador activo en estado NORMAL
}
visual_state_timer_ -= deltaTime;
visual_state_timer_ -= delta_time;
switch (visual_fire_state_) {
case VisualFireState::AIMING:
@@ -1029,7 +1025,7 @@ void Player::updateVisualLine(float deltaTime) {
// Inicia un disparo en ambas líneas
void Player::startFiringSystem(int cooldown_frames) {
// LÍNEA 1: Inicia cooldown funcional
fire_cooldown_timer_ = static_cast<float>(cooldown_frames) / 60.0f; // Convertir frames a segundos
fire_cooldown_timer_ = static_cast<float>(cooldown_frames) / 60.0F; // Convertir frames a segundos
can_fire_new_system_ = false;
// LÍNEA 2: Resetea completamente el estado visual

View File

@@ -1,21 +1,23 @@
#pragma once
#include <SDL3/SDL.h> // Para Uint32, SDL_FRect, SDL_FlipMode
#include <SDL3/SDL.h> // Para SDL_FRect, SDL_FlipMode
#include <memory> // Para shared_ptr, allocator, unique_ptr
#include <string> // Para string
#include <utility> // Para pair
#include <vector> // Para vector
#include <cstddef> // Para size_t
#include <iterator> // Para pair
#include <memory> // Para shared_ptr, unique_ptr
#include <string> // Para basic_string, string
#include <utility> // Para move, pair
#include <vector> // Para vector
#include "animated_sprite.hpp" // Para AnimatedSprite
#include "bullet.hpp" // Para Bullet
#include "enter_name.hpp" // Para EnterName
#include "input.hpp" // Para Input
#include "manage_hiscore_table.hpp" // Para Table
#include "scoreboard.hpp" // Para Scoreboard
#include "stage_interface.hpp" // Para IStageInfo
#include "utils.hpp" // Para Circle
#include "animated_sprite.hpp" // for AnimatedSprite
#include "bullet.hpp" // for Bullet
#include "enter_name.hpp" // for EnterName
#include "input.hpp" // for Input
#include "manage_hiscore_table.hpp" // for Table
#include "scoreboard.hpp" // for Scoreboard
#include "utils.hpp" // for Circle
class IStageInfo;
class Texture;
// --- Clase Player: jugador principal del juego ---
@@ -115,9 +117,9 @@ class Player {
~Player() = default;
// --- Inicialización y ciclo de vida ---
void init(); // Inicializa el jugador
void update(float deltaTime); // Actualiza estado, animación y contadores (time-based)
void render(); // Dibuja el jugador en pantalla
void init(); // Inicializa el jugador
void update(float delta_time); // Actualiza estado, animación y contadores (time-based)
void render(); // Dibuja el jugador en pantalla
// --- Entrada y control ---
void setInput(Input::Action action); // Procesa entrada general
@@ -125,8 +127,8 @@ class Player {
void setInputEnteringName(Input::Action action); // Procesa entrada al introducir nombre
// --- Movimiento y animación ---
void move(float deltaTime); // Mueve el jugador (time-based)
void setAnimation(float deltaTime); // Establece la animación según el estado (time-based)
void move(float delta_time); // Mueve el jugador (time-based)
void setAnimation(float delta_time); // Establece la animación según el estado (time-based)
// --- Texturas y animaciones ---
void setPlayerTextures(const std::vector<std::shared_ptr<Texture>>& texture); // Cambia las texturas del jugador
@@ -140,7 +142,7 @@ class Player {
void setPlayingState(State state); // Cambia el estado de juego
void setInvulnerable(bool value); // Establece el valor del estado de invulnerabilidad
void setPowerUp(); // Activa el modo PowerUp
void updatePowerUp(float deltaTime); // Actualiza el valor de PowerUp
void updatePowerUp(float delta_time); // Actualiza el valor de PowerUp
void giveExtraHit(); // Concede un toque extra al jugador
void removeExtraHit(); // Quita el toque extra al jugador
void decContinueCounter(); // Decrementa el contador de continuar
@@ -221,7 +223,7 @@ class Player {
private:
// --- Constantes de física y movimiento ---
static constexpr float BASE_SPEED = 90.0f; // Velocidad base del jugador (pixels/segundo)
static constexpr float BASE_SPEED = 90.0F; // Velocidad base del jugador (pixels/segundo)
// --- Constantes de power-ups y estados especiales ---
static constexpr int POWERUP_COUNTER = 1500; // Duración del estado PowerUp (frames)
@@ -236,10 +238,10 @@ class Player {
static constexpr int WAITING_COUNTER = 1000; // Tiempo de espera en estado de espera
// --- Constantes del nuevo sistema de disparo de dos líneas ---
static constexpr float AIMING_DURATION_FACTOR = 0.5f; // 50% del cooldown funcional
static constexpr float RECOILING_DURATION_MULTIPLIER = 4.0f; // 4 veces la duración de aiming
static constexpr float THREAT_POSE_DURATION = 50.0f / 60.0f; // 50 frames = ~0.833s (duración base)
static constexpr float MIN_THREAT_POSE_DURATION = 6.0f / 60.0f; // 6 frames = ~0.1s (duración mínima)
static constexpr float AIMING_DURATION_FACTOR = 0.5F; // 50% del cooldown funcional
static constexpr float RECOILING_DURATION_MULTIPLIER = 4.0F; // 4 veces la duración de aiming
static constexpr float THREAT_POSE_DURATION = 50.0F / 60.0F; // 50 frames = ~0.833s (duración base)
static constexpr float MIN_THREAT_POSE_DURATION = 6.0F / 60.0F; // 6 frames = ~0.1s (duración mínima)
// --- Objetos y punteros ---
std::unique_ptr<AnimatedSprite> player_sprite_; // Sprite para dibujar el jugador
@@ -251,17 +253,17 @@ class Player {
IStageInfo* stage_info_; // Informacion de la pantalla actual
// --- Variables de estado ---
SDL_FRect play_area_; // Rectángulo con la zona de juego
Circle collider_ = Circle(0, 0, 9); // Círculo de colisión del jugador
std::string name_; // Nombre del jugador
std::string last_enter_name_; // Último nombre introducido en la tabla de puntuaciones
Scoreboard::Id scoreboard_panel_ = Scoreboard::Id::LEFT; // Panel del marcador asociado al jugador
Id id_; // Identificador para el jugador
State walking_state_ = State::WALKING_STOP; // Estado del jugador al moverse
State firing_state_ = State::FIRING_NONE; // Estado del jugador al disparar
State playing_state_ = State::WAITING; // Estado del jugador en el juego
BulletColorPair bullet_colors_ = {Bullet::Color::YELLOW, Bullet::Color::GREEN}; // Par de colores de balas para este jugador
std::string bullet_sound_file_ = "bullet1p.wav"; // Archivo de sonido de bala para este jugador
SDL_FRect play_area_; // Rectángulo con la zona de juego
Circle collider_ = Circle(0, 0, 9); // Círculo de colisión del jugador
std::string name_; // Nombre del jugador
std::string last_enter_name_; // Último nombre introducido en la tabla de puntuaciones
Scoreboard::Id scoreboard_panel_ = Scoreboard::Id::LEFT; // Panel del marcador asociado al jugador
Id id_; // Identificador para el jugador
State walking_state_ = State::WALKING_STOP; // Estado del jugador al moverse
State firing_state_ = State::FIRING_NONE; // Estado del jugador al disparar
State playing_state_ = State::WAITING; // Estado del jugador en el juego
BulletColorPair bullet_colors_ = {.normal_color = Bullet::Color::YELLOW, .powered_color = Bullet::Color::GREEN}; // Par de colores de balas para este jugador
std::string bullet_sound_file_ = "bullet1p.wav"; // Archivo de sonido de bala para este jugador
float pos_x_ = 0.0F; // Posición en el eje X
float default_pos_x_; // Posición inicial para el jugador
@@ -270,20 +272,20 @@ class Player {
int pos_y_ = 0; // Posición en el eje Y
int default_pos_y_; // Posición inicial para el jugador
int vel_y_ = 0; // Cantidad de píxeles a desplazarse en el eje Y
float invulnerable_time_accumulator_ = 0.0f; // Acumulador de tiempo para invulnerabilidad (time-based)
float power_up_time_accumulator_ = 0.0f; // Acumulador de tiempo para power-up (time-based)
float continue_time_accumulator_ = 0.0f; // Acumulador de tiempo para continue counter (time-based)
float name_entry_time_accumulator_ = 0.0f; // Acumulador de tiempo para name entry counter (time-based)
float showing_name_time_accumulator_ = 0.0f; // Acumulador de tiempo para showing name (time-based)
float waiting_time_accumulator_ = 0.0f; // Acumulador de tiempo para waiting movement (time-based)
float step_time_accumulator_ = 0.0f; // Acumulador de tiempo para step counter (time-based)
float invulnerable_time_accumulator_ = 0.0F; // Acumulador de tiempo para invulnerabilidad (time-based)
float power_up_time_accumulator_ = 0.0F; // Acumulador de tiempo para power-up (time-based)
float continue_time_accumulator_ = 0.0F; // Acumulador de tiempo para continue counter (time-based)
float name_entry_time_accumulator_ = 0.0F; // Acumulador de tiempo para name entry counter (time-based)
float showing_name_time_accumulator_ = 0.0F; // Acumulador de tiempo para showing name (time-based)
float waiting_time_accumulator_ = 0.0F; // Acumulador de tiempo para waiting movement (time-based)
float step_time_accumulator_ = 0.0F; // Acumulador de tiempo para step counter (time-based)
// ========================================
// NUEVO SISTEMA DE DISPARO DE DOS LÍNEAS
// ========================================
// LÍNEA 1: SISTEMA FUNCIONAL (CanFire)
float fire_cooldown_timer_ = 0.0f; // Tiempo restante hasta poder disparar otra vez
float fire_cooldown_timer_ = 0.0F; // Tiempo restante hasta poder disparar otra vez
bool can_fire_new_system_ = true; // true si puede disparar ahora mismo
// LÍNEA 2: SISTEMA VISUAL (Animaciones)
@@ -295,9 +297,9 @@ class Player {
};
VisualFireState visual_fire_state_ = VisualFireState::NORMAL;
float visual_state_timer_ = 0.0f; // Tiempo en el estado visual actual
float aiming_duration_ = 0.0f; // Duración del estado AIMING
float recoiling_duration_ = 0.0f; // Duración del estado RECOILING
float visual_state_timer_ = 0.0F; // Tiempo en el estado visual actual
float aiming_duration_ = 0.0F; // Duración del estado AIMING
float recoiling_duration_ = 0.0F; // Duración del estado RECOILING
int invulnerable_counter_ = INVULNERABLE_COUNTER; // Contador para la invulnerabilidad
int score_ = 0; // Puntos del jugador
@@ -307,8 +309,8 @@ class Player {
int continue_counter_ = 10; // Contador para poder continuar
int controller_index_ = 0; // Índice del array de mandos que utilizará para moverse
size_t demo_file_ = 0; // Indice del fichero de datos para el modo demo
float name_entry_idle_time_accumulator_ = 0.0f; // Tiempo idle acumulado para poner nombre (milisegundos)
float name_entry_total_time_accumulator_ = 0.0f; // Tiempo total acumulado poniendo nombre (milisegundos)
float name_entry_idle_time_accumulator_ = 0.0F; // Tiempo idle acumulado para poner nombre (milisegundos)
float name_entry_total_time_accumulator_ = 0.0F; // Tiempo total acumulado poniendo nombre (milisegundos)
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
@@ -336,11 +338,11 @@ class Player {
void setScoreMultiplier(float value) { score_multiplier_ = value; }
// --- Actualizadores de estado (time-based) ---
void updateInvulnerable(float deltaTime); // Monitoriza el estado de invulnerabilidad
void updateContinueCounter(float deltaTime); // Actualiza el contador de continue
void updateEnterNameCounter(float deltaTime); // Actualiza el contador de entrar nombre
void updateShowingName(float deltaTime); // Actualiza el estado SHOWING_NAME
void decNameEntryCounter(); // Decrementa el contador de entrar nombre
void updateInvulnerable(float delta_time); // Monitoriza el estado de invulnerabilidad
void updateContinueCounter(float delta_time); // Actualiza el contador de continue
void updateEnterNameCounter(float delta_time); // Actualiza el contador de entrar nombre
void updateShowingName(float delta_time); // Actualiza el estado SHOWING_NAME
void decNameEntryCounter(); // Decrementa el contador de entrar nombre
// --- Utilidades generales ---
void updateScoreboard(); // Actualiza el panel del marcador
@@ -350,19 +352,19 @@ class Player {
void addScoreToScoreBoard() const; // Añade una puntuación a la tabla de records
// --- Sistema de disparo (nuevo - dos líneas) ---
void updateFireSystem(float deltaTime); // Método principal del nuevo sistema de disparo
void updateFunctionalLine(float deltaTime); // Actualiza la línea funcional (CanFire)
void updateVisualLine(float deltaTime); // Actualiza la línea visual (Animaciones)
void updateFiringStateFromVisual(); // Sincroniza firing_state_ con visual_fire_state_
void transitionToRecoilingNew(); // Transición AIMING → RECOILING
void transitionToThreatPose(); // Transición RECOILING → THREAT_POSE
void transitionToNormalNew(); // Transición THREAT_POSE → NORMAL
void updateFireSystem(float delta_time); // Método principal del nuevo sistema de disparo
void updateFunctionalLine(float delta_time); // Actualiza la línea funcional (CanFire)
void updateVisualLine(float delta_time); // Actualiza la línea visual (Animaciones)
void updateFiringStateFromVisual(); // Sincroniza firing_state_ con visual_fire_state_
void transitionToRecoilingNew(); // Transición AIMING → RECOILING
void transitionToThreatPose(); // Transición RECOILING → THREAT_POSE
void transitionToNormalNew(); // Transición THREAT_POSE → NORMAL
// --- Manejadores de movimiento ---
void handlePlayingMovement(float deltaTime); // Gestiona el movimiento durante el juego
void handleRecoverMovement(); // Comprueba si ha acabado la animación de recuperación
void updateStepCounter(float deltaTime); // Incrementa o ajusta el contador de pasos
void setInputBasedOnPlayerId(); // Asocia las entradas de control según el jugador
void handlePlayingMovement(float delta_time); // Gestiona el movimiento durante el juego
void handleRecoverMovement(); // Comprueba si ha acabado la animación de recuperación
void updateStepCounter(float delta_time); // Incrementa o ajusta el contador de pasos
void setInputBasedOnPlayerId(); // Asocia las entradas de control según el jugador
// --- Manejadores de estados especiales ---
void handleRollingMovement(); // Actualiza la lógica de movimiento de "rodar"
@@ -373,18 +375,18 @@ class Player {
void handleContinueTimeOut(); // Gestiona tiempo de espera en pantalla "Continuar"
// --- Manejadores de transiciones de pantalla ---
void handleTitleAnimation(float deltaTime); // Ejecuta animación del título
void handleLeavingScreen(float deltaTime); // Lógica para salir de pantalla
void handleEnteringScreen(float deltaTime); // Lógica para entrar en pantalla
void handlePlayer1Entering(float deltaTime); // Entrada del Jugador 1
void handlePlayer2Entering(float deltaTime); // Entrada del Jugador 2
void handleTitleAnimation(float delta_time); // Ejecuta animación del título
void handleLeavingScreen(float delta_time); // Lógica para salir de pantalla
void handleEnteringScreen(float delta_time); // Lógica para entrar en pantalla
void handlePlayer1Entering(float delta_time); // Entrada del Jugador 1
void handlePlayer2Entering(float delta_time); // Entrada del Jugador 2
// --- Manejadores de pantallas especiales ---
void handleCreditsMovement(float deltaTime); // Movimiento en pantalla de créditos
void handleCreditsRightMovement(); // Movimiento hacia la derecha en créditos
void handleCreditsLeftMovement(); // Movimiento hacia la izquierda en créditos
void handleWaitingMovement(float deltaTime); // Animación del jugador saludando
void updateWalkingStateForCredits(); // Actualiza estado de caminata en créditos
void handleCreditsMovement(float delta_time); // Movimiento en pantalla de créditos
void handleCreditsRightMovement(); // Movimiento hacia la derecha en créditos
void handleCreditsLeftMovement(); // Movimiento hacia la izquierda en créditos
void handleWaitingMovement(float delta_time); // Animación del jugador saludando
void updateWalkingStateForCredits(); // Actualiza estado de caminata en créditos
// --- Utilidades de animación ---
[[nodiscard]] auto computeAnimation() const -> std::pair<std::string, SDL_FlipMode>; // Calcula animación de movimiento y disparo

View File

@@ -24,10 +24,10 @@ class ShaderBackend {
* @param fragment_source Código fuente del fragment shader
* @return true si la inicialización fue exitosa
*/
virtual bool init(SDL_Window* window,
virtual auto init(SDL_Window* window,
SDL_Texture* texture,
const std::string& vertex_source,
const std::string& fragment_source) = 0;
const std::string& fragment_source) -> bool = 0;
/**
* @brief Renderiza la textura con los shaders aplicados
@@ -50,7 +50,7 @@ class ShaderBackend {
* @brief Verifica si el backend está usando aceleración por hardware
* @return true si usa aceleración (OpenGL/Metal/Vulkan)
*/
virtual bool isHardwareAccelerated() const = 0;
[[nodiscard]] virtual auto isHardwareAccelerated() const -> bool = 0;
};
} // namespace Rendering

View File

@@ -2,31 +2,33 @@
#include <SDL3/SDL.h> // Para SDL_LogInfo, SDL_LogCategory, SDL_LogError, SDL_SetRenderDrawColor, SDL_EventType, SDL_PollEvent, SDL_RenderFillRect, SDL_RenderRect, SDLK_ESCAPE, SDL_Event
#include <algorithm> // Para find_if, max, find
#include <array> // Para array
#include <cstdlib> // Para exit, getenv
#include <filesystem> // Para filesystem::remove, filesystem::exists
#include <fstream> // Para ofstream
#include <cstdlib> // Para exit
#include <exception> // Para exception
#include <filesystem> // Para exists, path, remove
#include <fstream> // Para basic_ofstream, basic_ios, basic_ostream::write, ios, ofstream
#include <ranges> // Para __find_if_fn, find_if, __find_fn, find
#include <stdexcept> // Para runtime_error
#include <utility> // Para move
#include "asset.hpp" // Para Asset
#include "color.hpp" // Para Color
#include "color.hpp" // Para Color, NO_COLOR_MOD
#include "external/jail_audio.h" // Para JA_LoadMusic, JA_LoadSound, JA_DeleteMusic, JA_DeleteSound
#include "lang.hpp" // Para getText
#include "param.hpp" // Para Param, param, ParamResource, ParamGame
#include "resource_helper.hpp" // Para ResourceHelper
#include "param.hpp" // Para Param, param, ParamPlayer, ParamResource, ParamGame
#include "resource_helper.hpp" // Para loadFile
#include "screen.hpp" // Para Screen
#include "text.hpp" // Para Text
#include "version.h" // Para Version::APP_NAME y Version::GIT_HASH
#include "ui/logger.hpp" // Para Logger
#include "ui/logger.hpp" // Para info, CR, dots
#include "utils.hpp" // Para getFileName
#include "version.h" // Para APP_NAME, GIT_HASH
struct JA_Music_t; // lines 11-11
struct JA_Sound_t; // lines 12-12
// Helper para cargar archivos de audio desde pack o filesystem
namespace {
std::string createTempAudioFile(const std::string& file_path, std::vector<std::string>& temp_files_tracker) {
auto createTempAudioFile(const std::string& file_path, std::vector<std::string>& temp_files_tracker) -> std::string {
auto resource_data = ResourceHelper::loadFile(file_path);
if (!resource_data.empty()) {
// Crear archivo temporal
@@ -319,8 +321,8 @@ auto Resource::getAnimation(const std::string& name) -> AnimationsFileBuffer& {
auto Resource::getDemoData(int index) -> DemoData& {
if (index < 0 || index >= static_cast<int>(demos_.size())) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Index %d out of range for demo data (size: %d)", index, static_cast<int>(demos_.size()));
static DemoData empty_demo;
return empty_demo;
static DemoData empty_demo_;
return empty_demo_;
}
return demos_.at(index);
}
@@ -446,7 +448,7 @@ void Resource::load() {
auto vsync = Screen::getVSync();
screen->setVSync(false);
//SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "\n** LOADING RESOURCES");
// SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "\n** LOADING RESOURCES");
loadSounds(); // Carga sonidos
loadMusics(); // Carga músicas
loadTextures(); // Carga texturas
@@ -456,7 +458,7 @@ void Resource::load() {
createText(); // Crea objetos de texto
createTextTextures(); // Crea texturas a partir de texto
createPlayerTextures(); // Crea las texturas de jugadores con todas sus variantes de paleta
//SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "\n** RESOURCES LOADED");
// SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "\n** RESOURCES LOADED");
// Restablece el sincronismo vertical a su valor original
screen->setVSync(vsync);
@@ -489,7 +491,7 @@ void Resource::loadSounds() {
// Carga las músicas del juego
void Resource::loadMusics() {
Logger::CR();
Logger::cr();
Logger::info("MUSIC FILES");
auto list = Asset::get()->getListByType(Asset::Type::MUSIC);
musics_.clear();
@@ -505,7 +507,7 @@ void Resource::loadMusics() {
// Carga las texturas del juego
void Resource::loadTextures() {
Logger::CR();
Logger::cr();
Logger::info("TEXTURES");
auto list = Asset::get()->getListByType(Asset::Type::BITMAP);
textures_.clear();
@@ -519,7 +521,7 @@ void Resource::loadTextures() {
// Carga los ficheros de texto del juego
void Resource::loadTextFiles() {
Logger::CR();
Logger::cr();
Logger::info("TEXT FILES");
auto list = Asset::get()->getListByType(Asset::Type::FONT);
text_files_.clear();
@@ -533,7 +535,7 @@ void Resource::loadTextFiles() {
// Carga las animaciones del juego
void Resource::loadAnimations() {
Logger::CR();
Logger::cr();
Logger::info("ANIMATIONS");
auto list = Asset::get()->getListByType(Asset::Type::ANIMATION);
animations_.clear();
@@ -547,7 +549,7 @@ void Resource::loadAnimations() {
// Carga los datos para el modo demostración
void Resource::loadDemoData() {
Logger::CR();
Logger::cr();
Logger::info("DEMO FILES");
auto list = Asset::get()->getListByType(Asset::Type::DEMODATA);
demos_.clear();
@@ -561,7 +563,7 @@ void Resource::loadDemoData() {
// Crea las texturas de jugadores con todas sus variantes de paleta
void Resource::createPlayerTextures() {
Logger::CR();
Logger::cr();
Logger::info("CREATING PLAYER TEXTURES");
// Configuración de jugadores y sus paletas
@@ -650,7 +652,7 @@ void Resource::createTextTextures() {
text(std::move(text_init)) {}
};
Logger::CR();
Logger::cr();
Logger::info("CREATING TEXTURES");
// Texturas de tamaño normal con outline
@@ -700,7 +702,7 @@ void Resource::createText() {
white_texture_file(std::move(w_file)) {}
};
Logger::CR();
Logger::cr();
Logger::info("CREATING TEXT OBJECTS");
std::vector<ResourceInfo> resources = {
@@ -890,7 +892,7 @@ void Resource::cleanupTempAudioFiles() {
try {
if (std::filesystem::exists(temp_path)) {
std::filesystem::remove(temp_path);
//SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "Removed temp audio file: %s", temp_path.c_str());
// SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "Removed temp audio file: %s", temp_path.c_str());
}
} catch (const std::exception& e) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to remove temp audio file %s: %s", temp_path.c_str(), e.what());

View File

@@ -1,21 +1,23 @@
#include "resource_helper.hpp"
#include <algorithm>
#include <filesystem>
#include <fstream>
#include <iostream>
#include <algorithm> // Para replace
#include <cstddef> // Para size_t
#include <fstream> // Para basic_ifstream, basic_ostream, basic_ios, operator<<, ios, basic_istream, endl, operator|, basic_istream::read, basic_istream::seekg, basic_istream::tellg, ifstream, streamsize
#include <iostream> // Para cout
#include "resource_loader.hpp" // Para ResourceLoader
namespace ResourceHelper {
static bool resource_system_initialized = false;
bool initializeResourceSystem(const std::string& pack_file) {
auto initializeResourceSystem(const std::string& pack_file) -> bool {
auto& loader = ResourceLoader::getInstance();
resource_system_initialized = loader.initialize(pack_file, true);
if (resource_system_initialized) {
std::cout << "Resource system initialized with pack: " << pack_file << std::endl;
std::cout << "Resource system initialized with pack: " << pack_file << '\n';
} else {
std::cout << "Resource system using fallback mode (filesystem only)" << std::endl;
std::cout << "Resource system using fallback mode (filesystem only)" << '\n';
}
return true; // Always return true as fallback is acceptable
@@ -28,7 +30,7 @@ void shutdownResourceSystem() {
}
}
std::vector<uint8_t> loadFile(const std::string& filepath) {
auto loadFile(const std::string& filepath) -> std::vector<uint8_t> {
if (resource_system_initialized && shouldUseResourcePack(filepath)) {
auto& loader = ResourceLoader::getInstance();
std::string pack_path = getPackPath(filepath);
@@ -45,18 +47,18 @@ std::vector<uint8_t> loadFile(const std::string& filepath) {
return {};
}
std::streamsize fileSize = file.tellg();
std::streamsize file_size = file.tellg();
file.seekg(0, std::ios::beg);
std::vector<uint8_t> data(fileSize);
if (!file.read(reinterpret_cast<char*>(data.data()), fileSize)) {
std::vector<uint8_t> data(file_size);
if (!file.read(reinterpret_cast<char*>(data.data()), file_size)) {
return {};
}
return data;
}
bool shouldUseResourcePack(const std::string& filepath) {
auto shouldUseResourcePack(const std::string& filepath) -> bool {
// Archivos que NO van al pack:
// - config/ (ahora está fuera de data/)
// - archivos absolutos del sistema
@@ -73,11 +75,11 @@ bool shouldUseResourcePack(const std::string& filepath) {
return false;
}
std::string getPackPath(const std::string& asset_path) {
auto getPackPath(const std::string& asset_path) -> std::string {
std::string pack_path = asset_path;
// Normalizar separadores de path a '/'
std::replace(pack_path.begin(), pack_path.end(), '\\', '/');
std::ranges::replace(pack_path, '\\', '/');
// Remover prefijo "data/" si existe
size_t data_pos = pack_path.find("data/");

View File

@@ -1,33 +1,31 @@
#pragma once
#include <filesystem>
#include <fstream>
#include <memory>
#include <string>
#include <vector>
#include "resource_loader.hpp"
#include <cstdint> // Para uint8_t
#include <filesystem> // Para remove, path
#include <fstream> // Para basic_ofstream, basic_ios, basic_ostream::write, ios, ofstream
#include <string> // Para string, basic_string, hash, operator+, to_string, __str_hash_base
#include <vector> // Para vector
// Helper functions para integrar ResourceLoader con el sistema existente
namespace ResourceHelper {
// Inicializa ResourceLoader (llamar al inicio del programa)
bool initializeResourceSystem(const std::string& pack_file = "resources.pack");
auto initializeResourceSystem(const std::string& pack_file = "resources.pack") -> bool;
// Cierra ResourceLoader
void shutdownResourceSystem();
// Carga un archivo usando ResourceLoader o fallback a filesystem
std::vector<uint8_t> loadFile(const std::string& filepath);
auto loadFile(const std::string& filepath) -> std::vector<uint8_t>;
// Verifica si un archivo debería cargarse del pack vs filesystem
bool shouldUseResourcePack(const std::string& filepath);
auto shouldUseResourcePack(const std::string& filepath) -> bool;
// Convierte ruta Asset a ruta relativa para ResourceLoader
std::string getPackPath(const std::string& asset_path);
auto getPackPath(const std::string& asset_path) -> std::string;
// Wrappea la carga de archivos para mantener compatibilidad
template <typename T>
T* loadResourceFile(const std::string& asset_path, T* (*loader_func)(const char*)) {
auto loadResourceFile(const std::string& asset_path, T* (*loader_func)(const char*)) -> T* {
auto data = loadFile(asset_path);
if (data.empty()) {
return loader_func(asset_path.c_str());

View File

@@ -1,17 +1,19 @@
#include "resource_loader.hpp"
#include <algorithm>
#include <filesystem>
#include <fstream>
#include <iostream>
#include <algorithm> // Para replace
#include <filesystem> // Para exists, path, recursive_directory_iterator, directory_entry, relative
#include <fstream> // Para basic_ostream, basic_ifstream, operator<<, basic_ios, endl, ios, basic_istream, operator|, basic_istream::read, basic_istream::seekg, basic_istream::tellg, ifstream, streamsize
#include <iostream> // Para cerr, cout
#include "resource_pack.hpp" // Para ResourcePack
std::unique_ptr<ResourceLoader> ResourceLoader::instance = nullptr;
ResourceLoader::ResourceLoader()
: resourcePack(nullptr),
fallbackToFiles(true) {}
: resource_pack_(nullptr),
fallback_to_files_(true) {}
ResourceLoader& ResourceLoader::getInstance() {
auto ResourceLoader::getInstance() -> ResourceLoader& {
if (!instance) {
instance = std::unique_ptr<ResourceLoader>(new ResourceLoader());
}
@@ -22,110 +24,109 @@ ResourceLoader::~ResourceLoader() {
shutdown();
}
bool ResourceLoader::initialize(const std::string& packFile, bool enableFallback) {
auto ResourceLoader::initialize(const std::string& packFile, bool enable_fallback) -> bool {
shutdown();
fallbackToFiles = enableFallback;
packPath = packFile;
fallback_to_files_ = enable_fallback;
pack_path_ = packFile;
if (std::filesystem::exists(packFile)) {
resourcePack = new ResourcePack();
if (resourcePack->loadPack(packFile)) {
std::cout << "Resource pack loaded successfully: " << packFile << std::endl;
std::cout << "Resources available: " << resourcePack->getResourceCount() << std::endl;
resource_pack_ = new ResourcePack();
if (resource_pack_->loadPack(packFile)) {
std::cout << "Resource pack loaded successfully: " << packFile << '\n';
std::cout << "Resources available: " << resource_pack_->getResourceCount() << '\n';
return true;
} else {
delete resourcePack;
resourcePack = nullptr;
std::cerr << "Failed to load resource pack: " << packFile << std::endl;
}
delete resource_pack_;
resource_pack_ = nullptr;
std::cerr << "Failed to load resource pack: " << packFile << std::endl;
}
if (fallbackToFiles) {
std::cout << "Using fallback mode: loading resources from data/ directory" << std::endl;
if (fallback_to_files_) {
std::cout << "Using fallback mode: loading resources from data/ directory" << '\n';
return true;
}
std::cerr << "Resource pack not found and fallback disabled: " << packFile << std::endl;
std::cerr << "Resource pack not found and fallback disabled: " << packFile << '\n';
return false;
}
void ResourceLoader::shutdown() {
if (resourcePack) {
delete resourcePack;
resourcePack = nullptr;
if (resource_pack_ != nullptr) {
delete resource_pack_;
resource_pack_ = nullptr;
}
}
std::vector<uint8_t> ResourceLoader::loadResource(const std::string& filename) {
if (resourcePack && resourcePack->hasResource(filename)) {
return resourcePack->getResource(filename);
auto ResourceLoader::loadResource(const std::string& filename) -> std::vector<uint8_t> {
if ((resource_pack_ != nullptr) && resource_pack_->hasResource(filename)) {
return resource_pack_->getResource(filename);
}
if (fallbackToFiles) {
if (fallback_to_files_) {
return loadFromFile(filename);
}
std::cerr << "Resource not found: " << filename << std::endl;
std::cerr << "Resource not found: " << filename << '\n';
return {};
}
bool ResourceLoader::resourceExists(const std::string& filename) {
if (resourcePack && resourcePack->hasResource(filename)) {
auto ResourceLoader::resourceExists(const std::string& filename) -> bool {
if ((resource_pack_ != nullptr) && resource_pack_->hasResource(filename)) {
return true;
}
if (fallbackToFiles) {
std::string fullPath = getDataPath(filename);
return std::filesystem::exists(fullPath);
if (fallback_to_files_) {
std::string full_path = getDataPath(filename);
return std::filesystem::exists(full_path);
}
return false;
}
std::vector<uint8_t> ResourceLoader::loadFromFile(const std::string& filename) {
std::string fullPath = getDataPath(filename);
auto ResourceLoader::loadFromFile(const std::string& filename) -> std::vector<uint8_t> {
std::string full_path = getDataPath(filename);
std::ifstream file(fullPath, std::ios::binary | std::ios::ate);
std::ifstream file(full_path, std::ios::binary | std::ios::ate);
if (!file) {
std::cerr << "Error: Could not open file: " << fullPath << std::endl;
std::cerr << "Error: Could not open file: " << full_path << '\n';
return {};
}
std::streamsize fileSize = file.tellg();
std::streamsize file_size = file.tellg();
file.seekg(0, std::ios::beg);
std::vector<uint8_t> data(fileSize);
if (!file.read(reinterpret_cast<char*>(data.data()), fileSize)) {
std::cerr << "Error: Could not read file: " << fullPath << std::endl;
std::vector<uint8_t> data(file_size);
if (!file.read(reinterpret_cast<char*>(data.data()), file_size)) {
std::cerr << "Error: Could not read file: " << full_path << '\n';
return {};
}
return data;
}
std::string ResourceLoader::getDataPath(const std::string& filename) {
auto ResourceLoader::getDataPath(const std::string& filename) -> std::string {
return "data/" + filename;
}
size_t ResourceLoader::getLoadedResourceCount() const {
if (resourcePack) {
return resourcePack->getResourceCount();
auto ResourceLoader::getLoadedResourceCount() const -> size_t {
if (resource_pack_ != nullptr) {
return resource_pack_->getResourceCount();
}
return 0;
}
std::vector<std::string> ResourceLoader::getAvailableResources() const {
if (resourcePack) {
return resourcePack->getResourceList();
auto ResourceLoader::getAvailableResources() const -> std::vector<std::string> {
if (resource_pack_ != nullptr) {
return resource_pack_->getResourceList();
}
std::vector<std::string> result;
if (fallbackToFiles && std::filesystem::exists("data")) {
if (fallback_to_files_ && std::filesystem::exists("data")) {
for (const auto& entry : std::filesystem::recursive_directory_iterator("data")) {
if (entry.is_regular_file()) {
std::string filename = std::filesystem::relative(entry.path(), "data").string();
std::replace(filename.begin(), filename.end(), '\\', '/');
std::ranges::replace(filename, '\\', '/');
result.push_back(filename);
}
}

View File

@@ -1,38 +1,39 @@
#ifndef RESOURCE_LOADER_H
#define RESOURCE_LOADER_H
#pragma once
#include <memory>
#include <cstddef> // Para size_t
#include <cstdint> // Para uint8_t
#include <memory> // Para unique_ptr
#include <string> // Para string, basic_string
#include <vector> // Para vector
#include "resource_pack.hpp"
class ResourcePack;
class ResourceLoader {
private:
static std::unique_ptr<ResourceLoader> instance;
ResourcePack* resourcePack;
std::string packPath;
bool fallbackToFiles;
ResourcePack* resource_pack_;
std::string pack_path_;
bool fallback_to_files_;
ResourceLoader();
public:
static ResourceLoader& getInstance();
static auto getInstance() -> ResourceLoader&;
~ResourceLoader();
bool initialize(const std::string& packFile, bool enableFallback = true);
auto initialize(const std::string& pack_file, bool enable_fallback = true) -> bool;
void shutdown();
std::vector<uint8_t> loadResource(const std::string& filename);
bool resourceExists(const std::string& filename);
auto loadResource(const std::string& filename) -> std::vector<uint8_t>;
auto resourceExists(const std::string& filename) -> bool;
void setFallbackToFiles(bool enable) { fallbackToFiles = enable; }
bool getFallbackToFiles() const { return fallbackToFiles; }
void setFallbackToFiles(bool enable) { fallback_to_files_ = enable; }
[[nodiscard]] auto getFallbackToFiles() const -> bool { return fallback_to_files_; }
size_t getLoadedResourceCount() const;
std::vector<std::string> getAvailableResources() const;
[[nodiscard]] auto getLoadedResourceCount() const -> size_t;
[[nodiscard]] auto getAvailableResources() const -> std::vector<std::string>;
private:
std::vector<uint8_t> loadFromFile(const std::string& filename);
std::string getDataPath(const std::string& filename);
auto loadFromFile(const std::string& filename) -> std::vector<uint8_t>;
static auto getDataPath(const std::string& filename) -> std::string;
};
#endif

View File

@@ -1,29 +1,32 @@
#include "resource_pack.hpp"
#include <algorithm>
#include <filesystem>
#include <fstream>
#include <iostream>
#include <algorithm> // Para replace
#include <filesystem> // Para path, recursive_directory_iterator, directory_entry, exists, relative
#include <fstream> // Para basic_ifstream, basic_ostream, basic_ofstream, operator<<, basic_ios, basic_istream::read, basic_ostream::write, endl, ios, basic_istream, ifstream, operator|, basic_istream::seekg, basic_istream::tellg, ofstream, streamsize
#include <iostream> // Para cerr
#include <utility> // Para pair
const std::string ResourcePack::DEFAULT_ENCRYPT_KEY = "CCAE_RESOURCES_2024";
const std::string ResourcePack::DEFAULT_ENCRYPT_KEY = "CCAE_RESOURCES__2024";
ResourcePack::ResourcePack()
: loaded(false) {}
: loaded_(false) {}
ResourcePack::~ResourcePack() {
clear();
}
uint32_t ResourcePack::calculateChecksum(const std::vector<uint8_t>& data) {
auto ResourcePack::calculateChecksum(const std::vector<uint8_t>& data) -> uint32_t {
uint32_t checksum = 0x12345678;
for (size_t i = 0; i < data.size(); ++i) {
checksum = ((checksum << 5) + checksum) + data[i];
for (unsigned char i : data) {
checksum = ((checksum << 5) + checksum) + i;
}
return checksum;
}
void ResourcePack::encryptData(std::vector<uint8_t>& data, const std::string& key) {
if (key.empty()) return;
if (key.empty()) {
return;
}
for (size_t i = 0; i < data.size(); ++i) {
data[i] ^= key[i % key.length()];
@@ -34,39 +37,39 @@ void ResourcePack::decryptData(std::vector<uint8_t>& data, const std::string& ke
encryptData(data, key);
}
bool ResourcePack::loadPack(const std::string& packFile) {
std::ifstream file(packFile, std::ios::binary);
auto ResourcePack::loadPack(const std::string& pack_file) -> bool {
std::ifstream file(pack_file, std::ios::binary);
if (!file) {
std::cerr << "Error: Could not open pack file: " << packFile << std::endl;
std::cerr << "Error: Could not open pack file: " << pack_file << '\n';
return false;
}
char header[4];
file.read(header, 4);
if (std::string(header, 4) != "CCAE") {
std::cerr << "Error: Invalid pack file format" << std::endl;
std::cerr << "Error: Invalid pack file format" << '\n';
return false;
}
uint32_t version;
file.read(reinterpret_cast<char*>(&version), sizeof(version));
if (version != 1) {
std::cerr << "Error: Unsupported pack version: " << version << std::endl;
std::cerr << "Error: Unsupported pack version: " << version << '\n';
return false;
}
uint32_t resourceCount;
file.read(reinterpret_cast<char*>(&resourceCount), sizeof(resourceCount));
uint32_t resource_count;
file.read(reinterpret_cast<char*>(&resource_count), sizeof(resource_count));
resources.clear();
resources.reserve(resourceCount);
resources_.clear();
resources_.reserve(resource_count);
for (uint32_t i = 0; i < resourceCount; ++i) {
uint32_t filenameLength;
file.read(reinterpret_cast<char*>(&filenameLength), sizeof(filenameLength));
for (uint32_t i = 0; i < resource_count; ++i) {
uint32_t filename_length;
file.read(reinterpret_cast<char*>(&filename_length), sizeof(filename_length));
std::string filename(filenameLength, '\0');
file.read(&filename[0], filenameLength);
std::string filename(filename_length, '\0');
file.read(filename.data(), filename_length);
ResourceEntry entry;
entry.filename = filename;
@@ -74,25 +77,25 @@ bool ResourcePack::loadPack(const std::string& packFile) {
file.read(reinterpret_cast<char*>(&entry.size), sizeof(entry.size));
file.read(reinterpret_cast<char*>(&entry.checksum), sizeof(entry.checksum));
resources[filename] = entry;
resources_[filename] = entry;
}
uint64_t dataSize;
file.read(reinterpret_cast<char*>(&dataSize), sizeof(dataSize));
uint64_t data_size;
file.read(reinterpret_cast<char*>(&data_size), sizeof(data_size));
data.resize(dataSize);
file.read(reinterpret_cast<char*>(data.data()), dataSize);
data_.resize(data_size);
file.read(reinterpret_cast<char*>(data_.data()), data_size);
decryptData(data, DEFAULT_ENCRYPT_KEY);
decryptData(data_, DEFAULT_ENCRYPT_KEY);
loaded = true;
loaded_ = true;
return true;
}
bool ResourcePack::savePack(const std::string& packFile) {
std::ofstream file(packFile, std::ios::binary);
auto ResourcePack::savePack(const std::string& pack_file) -> bool {
std::ofstream file(pack_file, std::ios::binary);
if (!file) {
std::cerr << "Error: Could not create pack file: " << packFile << std::endl;
std::cerr << "Error: Could not create pack file: " << pack_file << '\n';
return false;
}
@@ -101,60 +104,60 @@ bool ResourcePack::savePack(const std::string& packFile) {
uint32_t version = 1;
file.write(reinterpret_cast<const char*>(&version), sizeof(version));
uint32_t resourceCount = static_cast<uint32_t>(resources.size());
file.write(reinterpret_cast<const char*>(&resourceCount), sizeof(resourceCount));
auto resource_count = static_cast<uint32_t>(resources_.size());
file.write(reinterpret_cast<const char*>(&resource_count), sizeof(resource_count));
for (const auto& [filename, entry] : resources) {
uint32_t filenameLength = static_cast<uint32_t>(filename.length());
file.write(reinterpret_cast<const char*>(&filenameLength), sizeof(filenameLength));
file.write(filename.c_str(), filenameLength);
for (const auto& [filename, entry] : resources_) {
auto filename_length = static_cast<uint32_t>(filename.length());
file.write(reinterpret_cast<const char*>(&filename_length), sizeof(filename_length));
file.write(filename.c_str(), filename_length);
file.write(reinterpret_cast<const char*>(&entry.offset), sizeof(entry.offset));
file.write(reinterpret_cast<const char*>(&entry.size), sizeof(entry.size));
file.write(reinterpret_cast<const char*>(&entry.checksum), sizeof(entry.checksum));
}
std::vector<uint8_t> encryptedData = data;
encryptData(encryptedData, DEFAULT_ENCRYPT_KEY);
std::vector<uint8_t> encrypted_data = data_;
encryptData(encrypted_data, DEFAULT_ENCRYPT_KEY);
uint64_t dataSize = encryptedData.size();
file.write(reinterpret_cast<const char*>(&dataSize), sizeof(dataSize));
file.write(reinterpret_cast<const char*>(encryptedData.data()), dataSize);
uint64_t data_size = encrypted_data.size();
file.write(reinterpret_cast<const char*>(&data_size), sizeof(data_size));
file.write(reinterpret_cast<const char*>(encrypted_data.data()), data_size);
return true;
}
bool ResourcePack::addFile(const std::string& filename, const std::string& filepath) {
auto ResourcePack::addFile(const std::string& filename, const std::string& filepath) -> bool {
std::ifstream file(filepath, std::ios::binary | std::ios::ate);
if (!file) {
std::cerr << "Error: Could not open file: " << filepath << std::endl;
std::cerr << "Error: Could not open file: " << filepath << '\n';
return false;
}
std::streamsize fileSize = file.tellg();
std::streamsize file_size = file.tellg();
file.seekg(0, std::ios::beg);
std::vector<uint8_t> fileData(fileSize);
if (!file.read(reinterpret_cast<char*>(fileData.data()), fileSize)) {
std::cerr << "Error: Could not read file: " << filepath << std::endl;
std::vector<uint8_t> file_data(file_size);
if (!file.read(reinterpret_cast<char*>(file_data.data()), file_size)) {
std::cerr << "Error: Could not read file: " << filepath << '\n';
return false;
}
ResourceEntry entry;
entry.filename = filename;
entry.offset = data.size();
entry.size = fileData.size();
entry.checksum = calculateChecksum(fileData);
entry.offset = data_.size();
entry.size = file_data.size();
entry.checksum = calculateChecksum(file_data);
data.insert(data.end(), fileData.begin(), fileData.end());
resources[filename] = entry;
data_.insert(data_.end(), file_data.begin(), file_data.end());
resources_[filename] = entry;
return true;
}
bool ResourcePack::addDirectory(const std::string& directory) {
auto ResourcePack::addDirectory(const std::string& directory) -> bool {
if (!std::filesystem::exists(directory)) {
std::cerr << "Error: Directory does not exist: " << directory << std::endl;
std::cerr << "Error: Directory does not exist: " << directory << '\n';
return false;
}
@@ -163,7 +166,7 @@ bool ResourcePack::addDirectory(const std::string& directory) {
std::string filepath = entry.path().string();
std::string filename = std::filesystem::relative(entry.path(), directory).string();
std::replace(filename.begin(), filename.end(), '\\', '/');
std::ranges::replace(filename, '\\', '/');
if (!addFile(filename, filepath)) {
return false;
@@ -174,49 +177,49 @@ bool ResourcePack::addDirectory(const std::string& directory) {
return true;
}
std::vector<uint8_t> ResourcePack::getResource(const std::string& filename) {
auto it = resources.find(filename);
if (it == resources.end()) {
std::cerr << "Error: Resource not found: " << filename << std::endl;
auto ResourcePack::getResource(const std::string& filename) -> std::vector<uint8_t> {
auto it = resources_.find(filename);
if (it == resources_.end()) {
std::cerr << "Error: Resource not found: " << filename << '\n';
return {};
}
const ResourceEntry& entry = it->second;
if (entry.offset + entry.size > data.size()) {
std::cerr << "Error: Invalid resource data: " << filename << std::endl;
if (entry.offset + entry.size > data_.size()) {
std::cerr << "Error: Invalid resource data: " << filename << '\n';
return {};
}
std::vector<uint8_t> result(data.begin() + entry.offset,
data.begin() + entry.offset + entry.size);
std::vector<uint8_t> result(data_.begin() + entry.offset,
data_.begin() + entry.offset + entry.size);
uint32_t checksum = calculateChecksum(result);
if (checksum != entry.checksum) {
std::cerr << "Warning: Checksum mismatch for resource: " << filename << std::endl;
std::cerr << "Warning: Checksum mismatch for resource: " << filename << '\n';
}
return result;
}
bool ResourcePack::hasResource(const std::string& filename) const {
return resources.find(filename) != resources.end();
auto ResourcePack::hasResource(const std::string& filename) const -> bool {
return resources_.find(filename) != resources_.end();
}
void ResourcePack::clear() {
resources.clear();
data.clear();
loaded = false;
resources_.clear();
data_.clear();
loaded_ = false;
}
size_t ResourcePack::getResourceCount() const {
return resources.size();
auto ResourcePack::getResourceCount() const -> size_t {
return resources_.size();
}
std::vector<std::string> ResourcePack::getResourceList() const {
auto ResourcePack::getResourceList() const -> std::vector<std::string> {
std::vector<std::string> result;
result.reserve(resources.size());
result.reserve(resources_.size());
for (const auto& [filename, entry] : resources) {
for (const auto& [filename, entry] : resources_) {
result.push_back(filename);
}

View File

@@ -1,10 +1,11 @@
#ifndef RESOURCE_PACK_H
#define RESOURCE_PACK_H
#include <cstdint>
#include <string>
#include <unordered_map>
#include <vector>
#include <cstddef> // Para size_t
#include <cstdint> // Para uint8_t, uint32_t, uint64_t
#include <string> // Para string, basic_string, hash
#include <unordered_map> // Para unordered_map
#include <vector> // Para vector
struct ResourceEntry {
std::string filename;
@@ -15,30 +16,30 @@ struct ResourceEntry {
class ResourcePack {
private:
std::unordered_map<std::string, ResourceEntry> resources;
std::vector<uint8_t> data;
bool loaded;
std::unordered_map<std::string, ResourceEntry> resources_;
std::vector<uint8_t> data_;
bool loaded_;
uint32_t calculateChecksum(const std::vector<uint8_t>& data);
void encryptData(std::vector<uint8_t>& data, const std::string& key);
static auto calculateChecksum(const std::vector<uint8_t>& data) -> uint32_t;
static void encryptData(std::vector<uint8_t>& data, const std::string& key);
void decryptData(std::vector<uint8_t>& data, const std::string& key);
public:
ResourcePack();
~ResourcePack();
bool loadPack(const std::string& packFile);
bool savePack(const std::string& packFile);
auto loadPack(const std::string& pack_file) -> bool;
auto savePack(const std::string& pack_file) -> bool;
bool addFile(const std::string& filename, const std::string& filepath);
bool addDirectory(const std::string& directory);
auto addFile(const std::string& filename, const std::string& filepath) -> bool;
auto addDirectory(const std::string& directory) -> bool;
std::vector<uint8_t> getResource(const std::string& filename);
bool hasResource(const std::string& filename) const;
auto getResource(const std::string& filename) -> std::vector<uint8_t>;
auto hasResource(const std::string& filename) const -> bool;
void clear();
size_t getResourceCount() const;
std::vector<std::string> getResourceList() const;
auto getResourceCount() const -> size_t;
auto getResourceList() const -> std::vector<std::string>;
static const std::string DEFAULT_ENCRYPT_KEY;
};

View File

@@ -52,7 +52,7 @@ Scoreboard::Scoreboard()
continue_counter_.at(i) = 0;
carousel_prev_index_.at(i) = -1; // Inicializar a -1 para detectar primera inicialización
enter_name_ref_.at(i) = nullptr;
text_slide_offset_.at(i) = 0.0f;
text_slide_offset_.at(i) = 0.0F;
}
panel_.at(static_cast<size_t>(Id::LEFT)).mode = Mode::SCORE;
@@ -96,12 +96,12 @@ Scoreboard::~Scoreboard() {
// Configura la animación del carrusel
void Scoreboard::setCarouselAnimation(Id id, int selected_index, EnterName* enter_name_ptr) {
size_t idx = static_cast<size_t>(id);
auto idx = static_cast<size_t>(id);
// Guardar referencia a EnterName
enter_name_ref_.at(idx) = enter_name_ptr;
if (!enter_name_ptr || selected_index < 0) {
if ((enter_name_ptr == nullptr) || selected_index < 0) {
return;
}
@@ -144,7 +144,7 @@ void Scoreboard::setCarouselAnimation(Id id, int selected_index, EnterName* ente
// Establece el modo del panel y gestiona transiciones
void Scoreboard::setMode(Id id, Mode mode) {
size_t idx = static_cast<size_t>(id);
auto idx = static_cast<size_t>(id);
// Cambiar el modo
panel_.at(idx).mode = mode;
@@ -153,7 +153,7 @@ void Scoreboard::setMode(Id id, Mode mode) {
switch (mode) {
case Mode::SCORE_TO_ENTER_NAME:
// Iniciar animación de transición SCORE → ENTER_NAME
text_slide_offset_.at(idx) = 0.0f;
text_slide_offset_.at(idx) = 0.0F;
// Resetear carrusel para que se inicialice correctamente en ENTER_NAME
if (carousel_prev_index_.at(idx) != -1) {
carousel_prev_index_.at(idx) = -1;
@@ -166,17 +166,17 @@ void Scoreboard::setMode(Id id, Mode mode) {
if (carousel_prev_index_.at(idx) != -1) {
carousel_prev_index_.at(idx) = -1;
}
text_slide_offset_.at(idx) = 0.0f;
text_slide_offset_.at(idx) = 0.0F;
break;
case Mode::ENTER_TO_SHOW_NAME:
// Iniciar animación de transición ENTER_NAME → SHOW_NAME
text_slide_offset_.at(idx) = 0.0f;
text_slide_offset_.at(idx) = 0.0F;
break;
case Mode::SHOW_NAME:
// Asegurar que la animación está completa
text_slide_offset_.at(idx) = 1.0f;
text_slide_offset_.at(idx) = 1.0F;
break;
// Otros modos no requieren inicialización especial
@@ -216,17 +216,17 @@ void Scoreboard::updateNameColorIndex() {
}
// Actualiza la animación del carrusel
void Scoreboard::updateCarouselAnimation(float deltaTime) {
constexpr float CAROUSEL_SPEED = 8.0f; // Posiciones por segundo
void Scoreboard::updateCarouselAnimation(float delta_time) {
constexpr float CAROUSEL_SPEED = 8.0F; // Posiciones por segundo
for (size_t i = 0; i < carousel_position_.size(); ++i) {
// Solo animar si no hemos llegado al target
if (std::abs(carousel_position_.at(i) - carousel_target_.at(i)) > 0.01f) {
if (std::abs(carousel_position_.at(i) - carousel_target_.at(i)) > 0.01F) {
// Determinar dirección
float direction = (carousel_target_.at(i) > carousel_position_.at(i)) ? 1.0f : -1.0f;
float direction = (carousel_target_.at(i) > carousel_position_.at(i)) ? 1.0F : -1.0F;
// Calcular movimiento
float movement = CAROUSEL_SPEED * deltaTime * direction;
float movement = CAROUSEL_SPEED * delta_time * direction;
// Mover, pero no sobrepasar el target
float new_position = carousel_position_.at(i) + movement;
@@ -245,24 +245,24 @@ void Scoreboard::updateCarouselAnimation(float deltaTime) {
}
// Actualiza las animaciones de deslizamiento de texto
void Scoreboard::updateTextSlideAnimation(float deltaTime) {
void Scoreboard::updateTextSlideAnimation(float delta_time) {
for (size_t i = 0; i < static_cast<size_t>(Id::SIZE); ++i) {
Mode current_mode = panel_.at(i).mode;
if (current_mode == Mode::SCORE_TO_ENTER_NAME) {
// Incrementar progreso de animación SCORE → ENTER_NAME (0.0 a 1.0)
text_slide_offset_.at(i) += deltaTime / TEXT_SLIDE_DURATION;
text_slide_offset_.at(i) += delta_time / TEXT_SLIDE_DURATION;
// Terminar animación y cambiar a ENTER_NAME cuando se complete
if (text_slide_offset_.at(i) >= 1.0f) {
if (text_slide_offset_.at(i) >= 1.0F) {
setMode(static_cast<Id>(i), Mode::ENTER_NAME);
}
} else if (current_mode == Mode::ENTER_TO_SHOW_NAME) {
// Incrementar progreso de animación ENTER_NAME → SHOW_NAME (0.0 a 1.0)
text_slide_offset_.at(i) += deltaTime / TEXT_SLIDE_DURATION;
text_slide_offset_.at(i) += delta_time / TEXT_SLIDE_DURATION;
// Terminar animación y cambiar a SHOW_NAME cuando se complete
if (text_slide_offset_.at(i) >= 1.0f) {
if (text_slide_offset_.at(i) >= 1.0F) {
setMode(static_cast<Id>(i), Mode::SHOW_NAME);
}
}
@@ -270,11 +270,11 @@ void Scoreboard::updateTextSlideAnimation(float deltaTime) {
}
// Actualiza la lógica del marcador
void Scoreboard::update(float deltaTime) {
void Scoreboard::update(float delta_time) {
updateTimeCounter();
updateNameColorIndex();
updateCarouselAnimation(deltaTime);
updateTextSlideAnimation(deltaTime);
updateCarouselAnimation(delta_time);
updateTextSlideAnimation(delta_time);
fillBackgroundTexture(); // Renderizar DESPUÉS de actualizar
}
@@ -438,30 +438,30 @@ void Scoreboard::renderContinueMode(size_t panel_index) {
void Scoreboard::renderScoreToEnterNameMode(size_t panel_index) {
// Calcular progreso suavizado de la animación (0.0 a 1.0)
const float t = static_cast<float>(easeInOutSine(text_slide_offset_.at(panel_index)));
const auto T = static_cast<float>(easeInOutSine(text_slide_offset_.at(panel_index)));
// Calcular desplazamientos reales entre slots (no son exactamente ROW_SIZE)
const float delta_1_to_2 = slot4_2_.y - slot4_1_.y; // Diferencia real entre ROW1 y ROW2
const float delta_2_to_3 = slot4_3_.y - slot4_2_.y; // Diferencia real entre ROW2 y ROW3
const float delta_3_to_4 = slot4_4_.y - slot4_3_.y; // Diferencia real entre ROW3 y ROW4
const float DELTA_1_TO_2 = slot4_2_.y - slot4_1_.y; // Diferencia real entre ROW1 y ROW2
const float DELTA_2_TO_3 = slot4_3_.y - slot4_2_.y; // Diferencia real entre ROW2 y ROW3
const float DELTA_3_TO_4 = slot4_4_.y - slot4_3_.y; // Diferencia real entre ROW3 y ROW4
// ========== Texto que SALE hacia arriba ==========
// name_ (sale desde ROW1 hacia arriba)
text_->writeDX(Text::CENTER | Text::COLOR, slot4_1_.x, slot4_1_.y - t * delta_1_to_2, name_.at(panel_index), 1, text_color1_);
text_->writeDX(Text::CENTER | Text::COLOR, slot4_1_.x, slot4_1_.y - (T * DELTA_1_TO_2), name_.at(panel_index), 1, text_color1_);
// ========== Textos que SE MUEVEN hacia arriba ==========
// score_ (se mueve de ROW2 a ROW1)
text_->writeDX(Text::CENTER | Text::COLOR, slot4_2_.x, slot4_2_.y - t * delta_1_to_2, updateScoreText(score_.at(panel_index)), 1, text_color2_);
text_->writeDX(Text::CENTER | Text::COLOR, slot4_2_.x, slot4_2_.y - (T * DELTA_1_TO_2), updateScoreText(score_.at(panel_index)), 1, text_color2_);
// "ENTER NAME" (se mueve de ROW3 a ROW2)
text_->writeDX(Text::CENTER | Text::COLOR, slot4_3_.x, slot4_3_.y - t * delta_2_to_3, Lang::getText("[SCOREBOARD] 11"), 1, text_color1_);
text_->writeDX(Text::CENTER | Text::COLOR, slot4_3_.x, slot4_3_.y - (T * DELTA_2_TO_3), Lang::getText("[SCOREBOARD] 11"), 1, text_color1_);
// enter_name_ (se mueve de ROW4 a ROW3)
text_->writeDX(Text::CENTER | Text::COLOR, slot4_4_.x, slot4_4_.y - t * delta_3_to_4, enter_name_.at(panel_index), 1, text_color2_);
text_->writeDX(Text::CENTER | Text::COLOR, slot4_4_.x, slot4_4_.y - (T * DELTA_3_TO_4), enter_name_.at(panel_index), 1, text_color2_);
// ========== Elemento que ENTRA desde abajo ==========
// CARRUSEL (entra desde debajo de ROW4 hacia ROW4)
renderCarousel(panel_index, slot4_4_.x, static_cast<int>(slot4_4_.y + delta_3_to_4 - t * delta_3_to_4));
renderCarousel(panel_index, slot4_4_.x, static_cast<int>(slot4_4_.y + DELTA_3_TO_4 - (T * DELTA_3_TO_4)));
}
void Scoreboard::renderEnterNameMode(size_t panel_index) {
@@ -491,31 +491,31 @@ void Scoreboard::renderEnterNameMode(size_t panel_index) {
void Scoreboard::renderEnterToShowNameMode(size_t panel_index) {
// Calcular progreso suavizado de la animación (0.0 a 1.0)
const float t = static_cast<float>(easeInOutSine(text_slide_offset_.at(panel_index)));
const auto T = static_cast<float>(easeInOutSine(text_slide_offset_.at(panel_index)));
// Calcular desplazamientos reales entre slots (no son exactamente ROW_SIZE)
const float delta_1_to_2 = slot4_2_.y - slot4_1_.y; // Diferencia real entre ROW1 y ROW2
const float delta_2_to_3 = slot4_3_.y - slot4_2_.y; // Diferencia real entre ROW2 y ROW3
const float delta_3_to_4 = slot4_4_.y - slot4_3_.y; // Diferencia real entre ROW3 y ROW4
const float DELTA_1_TO_2 = slot4_2_.y - slot4_1_.y; // Diferencia real entre ROW1 y ROW2
const float DELTA_2_TO_3 = slot4_3_.y - slot4_2_.y; // Diferencia real entre ROW2 y ROW3
const float DELTA_3_TO_4 = slot4_4_.y - slot4_3_.y; // Diferencia real entre ROW3 y ROW4
// ========== Texto que ENTRA desde arriba ==========
// name_ (entra desde arriba hacia ROW1)
// Debe venir desde donde estaría ROW0, que está a delta_1_to_2 píxeles arriba de ROW1
text_->writeDX(Text::CENTER | Text::COLOR, slot4_1_.x, slot4_1_.y + t * delta_1_to_2 - delta_1_to_2, name_.at(panel_index), 1, text_color1_);
text_->writeDX(Text::CENTER | Text::COLOR, slot4_1_.x, slot4_1_.y + (T * DELTA_1_TO_2) - DELTA_1_TO_2, name_.at(panel_index), 1, text_color1_);
// ========== Textos que SE MUEVEN (renderizar UNA sola vez) ==========
// SCORE (se mueve de ROW1 a ROW2)
text_->writeDX(Text::CENTER | Text::COLOR, slot4_1_.x, slot4_1_.y + t * delta_1_to_2, updateScoreText(score_.at(panel_index)), 1, text_color2_);
text_->writeDX(Text::CENTER | Text::COLOR, slot4_1_.x, slot4_1_.y + (T * DELTA_1_TO_2), updateScoreText(score_.at(panel_index)), 1, text_color2_);
// "ENTER NAME" (se mueve de ROW2 a ROW3)
text_->writeDX(Text::CENTER | Text::COLOR, slot4_2_.x, slot4_2_.y + t * delta_2_to_3, Lang::getText("[SCOREBOARD] 11"), 1, text_color1_);
text_->writeDX(Text::CENTER | Text::COLOR, slot4_2_.x, slot4_2_.y + (T * DELTA_2_TO_3), Lang::getText("[SCOREBOARD] 11"), 1, text_color1_);
// enter_name_ (se mueve de ROW3 a ROW4)
text_->writeDX(Text::CENTER | Text::COLOR, slot4_3_.x, slot4_3_.y + t * delta_3_to_4, enter_name_.at(panel_index), 1, text_color2_);
text_->writeDX(Text::CENTER | Text::COLOR, slot4_3_.x, slot4_3_.y + (T * DELTA_3_TO_4), enter_name_.at(panel_index), 1, text_color2_);
// ========== Elemento que SALE hacia abajo ==========
// CARRUSEL (sale desde ROW4 hacia abajo, fuera de pantalla)
renderCarousel(panel_index, slot4_4_.x, static_cast<int>(slot4_4_.y + t * delta_3_to_4));
renderCarousel(panel_index, slot4_4_.x, static_cast<int>(slot4_4_.y + (T * DELTA_3_TO_4)));
}
void Scoreboard::renderShowNameMode(size_t panel_index) {
@@ -652,7 +652,7 @@ void Scoreboard::renderSeparator() {
void Scoreboard::renderCarousel(size_t panel_index, int center_x, int y) {
// Obtener referencia a EnterName
EnterName* enter_name = enter_name_ref_.at(panel_index);
if (!enter_name) {
if (enter_name == nullptr) {
return;
}
@@ -669,7 +669,7 @@ void Scoreboard::renderCarousel(size_t panel_index, int center_x, int y) {
constexpr int HALF_VISIBLE = CAROUSEL_VISIBLE_LETTERS / 2; // 4
// Posición flotante actual del carrusel (índice en character_list_)
const float carousel_pos = carousel_position_.at(panel_index);
const float CAROUSEL_POS = carousel_position_.at(panel_index);
// Calcular ancho promedio de una letra (asumimos ancho uniforme)
std::string sample_char(1, char_list[0]);
@@ -677,58 +677,58 @@ void Scoreboard::renderCarousel(size_t panel_index, int center_x, int y) {
const int CHAR_STEP = AVG_CHAR_WIDTH + EXTRA_SPACING;
// Calcular offset de píxeles basado en la parte fraccionaria de carousel_pos
const float fractional_offset = carousel_pos - std::floor(carousel_pos);
const int pixel_offset = static_cast<int>(fractional_offset * CHAR_STEP);
const float FRACTIONAL_OFFSET = CAROUSEL_POS - std::floor(CAROUSEL_POS);
const int PIXEL_OFFSET = static_cast<int>(FRACTIONAL_OFFSET * CHAR_STEP);
// Índice base en character_list_ (centro del carrusel)
const int base_index = static_cast<int>(std::floor(carousel_pos));
const int char_list_size = static_cast<int>(char_list.size());
const int BASE_INDEX = static_cast<int>(std::floor(CAROUSEL_POS));
const int CHAR_LIST_SIZE = static_cast<int>(char_list.size());
// Calcular posición X inicial (centrar el conjunto de 9 letras)
int start_x = center_x - (HALF_VISIBLE * CHAR_STEP) - (AVG_CHAR_WIDTH / 2) - pixel_offset;
int start_x = center_x - (HALF_VISIBLE * CHAR_STEP) - (AVG_CHAR_WIDTH / 2) - PIXEL_OFFSET;
// Renderizar las 9 letras visibles
for (int i = -HALF_VISIBLE; i <= HALF_VISIBLE; ++i) {
// Índice real en character_list_ (con wrap-around circular)
int char_index = base_index + i;
int char_index = BASE_INDEX + i;
// Wrap-around circular
char_index = char_index % char_list_size;
char_index = char_index % CHAR_LIST_SIZE;
if (char_index < 0) {
char_index += char_list_size;
char_index += CHAR_LIST_SIZE;
}
// Obtener el carácter directamente de character_list_
std::string single_char(1, char_list[char_index]);
// Calcular distancia flotante al centro visual basada en posición real del carácter
float distance_from_center = std::abs(static_cast<float>(char_index) - carousel_pos);
float distance_from_center = std::abs(static_cast<float>(char_index) - CAROUSEL_POS);
// Manejar wrap-around circular: elegir el camino más corto
if (distance_from_center > static_cast<float>(char_list_size) / 2.0f) {
distance_from_center = static_cast<float>(char_list_size) - distance_from_center;
if (distance_from_center > static_cast<float>(CHAR_LIST_SIZE) / 2.0F) {
distance_from_center = static_cast<float>(CHAR_LIST_SIZE) - distance_from_center;
}
// Calcular color con LERP dinámico continuo
Color letter_color;
if (distance_from_center < 0.5f) {
if (distance_from_center < 0.5F) {
// Letra cerca del centro: LERP hacia animated_color_
// distance_from_center va de 0.0 (centro exacto) a 0.5 (borde)
float lerp_to_animated = distance_from_center / 0.5f; // 0.0 a 1.0
float lerp_to_animated = distance_from_center / 0.5F; // 0.0 a 1.0
letter_color = animated_color_.LERP(text_color1_, lerp_to_animated);
} else {
// Letras alejadas: LERP hacia color_ (fade out)
float base_lerp = (distance_from_center - 0.5f) / (HALF_VISIBLE - 0.5f);
base_lerp = std::min(base_lerp, 1.0f);
const float LERP_FACTOR = base_lerp * 0.85f;
float base_lerp = (distance_from_center - 0.5F) / (HALF_VISIBLE - 0.5F);
base_lerp = std::min(base_lerp, 1.0F);
const float LERP_FACTOR = base_lerp * 0.85F;
letter_color = text_color1_.LERP(color_, LERP_FACTOR);
}
// Calcular posición X de esta letra
const int letter_x = start_x + (i + HALF_VISIBLE) * CHAR_STEP;
const int LETTER_X = start_x + ((i + HALF_VISIBLE) * CHAR_STEP);
// Pintar la letra
text_->writeDX(Text::COLOR, letter_x, y, single_char, 1, letter_color);
text_->writeDX(Text::COLOR, LETTER_X, y, single_char, 1, letter_color);
}
}

View File

@@ -55,8 +55,8 @@ class Scoreboard {
static auto get() -> Scoreboard*; // Obtiene el puntero al objeto Scoreboard
// --- Métodos principales ---
void update(float deltaTime); // Actualiza la lógica del marcador
void render(); // Pinta el marcador
void update(float delta_time); // Actualiza la lógica del marcador
void render(); // Pinta el marcador
// --- Setters ---
void setColor(Color color); // Establece el color del marcador
@@ -113,7 +113,7 @@ class Scoreboard {
// --- Constantes ---
static constexpr int CAROUSEL_VISIBLE_LETTERS = 9;
static constexpr float TEXT_SLIDE_DURATION = 0.3f; // Duración de la animación de deslizamiento en segundos
static constexpr float TEXT_SLIDE_DURATION = 0.3F; // Duración de la animación de deslizamiento en segundos
// --- Variables de aspecto ---
Color text_color1_, text_color2_; // Colores para los marcadores del texto;
@@ -131,8 +131,8 @@ class Scoreboard {
void fillBackgroundTexture(); // Rellena la textura de fondo
void updateTimeCounter(); // Actualiza el contador
void updateNameColorIndex(); // Actualiza el índice del color animado del nombre
void updateCarouselAnimation(float deltaTime); // Actualiza la animación del carrusel
void updateTextSlideAnimation(float deltaTime); // Actualiza la animación de deslizamiento de texto
void updateCarouselAnimation(float delta_time); // Actualiza la animación del carrusel
void updateTextSlideAnimation(float delta_time); // Actualiza la animación de deslizamiento de texto
void renderSeparator(); // Dibuja la línea que separa la zona de juego del marcador
void renderPanelContent(size_t panel_index);
void renderScoreMode(size_t panel_index);

View File

@@ -1,24 +1,23 @@
#include "screen.hpp"
#include <SDL3/SDL.h> // Para SDL_SetRenderTarget, SDL_LogCategory, SDL_LogInfo, SDL_RenderTexture, SDL_SetRenderDrawColor, SDL_SetRenderVSync, SDL_GetError, SDL_LogError, SDL_RendererLogicalPresentation, SDL_SetRenderLogicalPresentation, SDL_CreateTexture, SDL_DestroyTexture, SDL_DestroyWindow, SDL_GetTicks, SDL_Quit, SDL_RENDERER_VSYNC_DISABLED, SDL_RenderClear, SDL_CreateRenderer, SDL_CreateWindow, SDL_DestroyRenderer, SDL_DisplayID, SDL_FRect, SDL_GetCurrentDisplayMode, SDL_GetDisplayName, SDL_GetDisplays, SDL_GetRenderTarget, SDL_GetWindowPosition, SDL_GetWindowSize, SDL_Init, SDL_LogWarn, SDL_PixelFormat, SDL_RenderFillRect, SDL_RenderPresent, SDL_SetHint, SDL_SetRenderDrawBlendMode, SDL_SetTextureScaleMode, SDL_SetWindowFullscreen, SDL_SetWindowPosition, SDL_SetWindowSize, SDL_TextureAccess, SDL_free, SDL_BLENDMODE_BLEND, SDL_HINT_RENDER_DRIVER, SDL_INIT_VIDEO, SDL_PRIu32, SDL_ScaleMode, SDL_WINDOW_FULLSCREEN, SDL_WINDOW_OPENGL, SDL_WindowFlags
#include <SDL3/SDL.h> // Para SDL_SetRenderTarget, SDL_RenderTexture, SDL_SetRenderDrawColor, SDL_SetRenderVSync, SDL_LogCategory, SDL_GetError, SDL_LogError, SDL_LogInfo, SDL_RendererLogicalPresentation, SDL_SetRenderLogicalPresentation, SDL_CreateTexture, SDL_DestroyTexture, SDL_DestroyWindow, SDL_GetDisplayName, SDL_GetTicks, SDL_Quit, SDL_RENDERER_VSYNC_DISABLED, SDL_RenderClear, SDL_CreateRenderer, SDL_CreateWindow, SDL_DestroyRenderer, SDL_DisplayID, SDL_FRect, SDL_GetCurrentDisplayMode, SDL_GetDisplays, SDL_GetRenderTarget, SDL_GetWindowPosition, SDL_GetWindowSize, SDL_Init, SDL_LogWarn, SDL_PixelFormat, SDL_RenderFillRect, SDL_RenderPresent, SDL_SetHint, SDL_SetRenderDrawBlendMode, SDL_SetTextureScaleMode, SDL_SetWindowFullscreen, SDL_SetWindowPosition, SDL_SetWindowSize, SDL_TextureAccess, SDL_free, SDL_BLENDMODE_BLEND, SDL_HINT_RENDER_DRIVER, SDL_INIT_VIDEO, SDL_ScaleMode, SDL_WINDOW_FULLSCREEN, SDL_WINDOW_OPENGL, SDL_WindowFlags
#include <algorithm> // Para min, max
#include <fstream> // Para basic_ifstream, ifstream
#include <iterator> // Para istreambuf_iterator, operator==
#include <memory> // Para allocator, shared_ptr, make_shared, __shared_ptr_access
#include <string> // Para operator+, char_traits, to_string, string
#include <memory> // Para allocator, shared_ptr, unique_ptr, __shared_ptr_access, make_shared, make_unique
#include <string> // Para basic_string, operator+, char_traits, to_string, string
#include <vector> // Para vector
#include "asset.hpp" // Para Asset
#include "mouse.hpp" // Para updateCursorVisibility
#include "options.hpp" // Para VideoOptions, video, WindowOptions, window
#include "options.hpp" // Para Video, video, Window, window
#include "param.hpp" // Para Param, param, ParamGame, ParamDebug
#include "rendering/opengl/opengl_shader.hpp" // Para OpenGLShader
#include "text.hpp" // Para Text, Text::COLOR, Text::STROKE
#include "shader_backend.hpp" // Para ShaderBackend
#include "text.hpp" // Para Text
#include "texture.hpp" // Para Texture
#include "ui/logger.hpp" // Para Logger
#include "ui/logger.hpp" // Para info
#include "ui/notifier.hpp" // Para Notifier
#include "ui/service_menu.hpp" // Para ServiceMenu
#include "utils.hpp" // Para Zone
// Singleton
Screen* Screen::instance = nullptr;
@@ -232,13 +231,13 @@ void Screen::loadShaders() {
if (vertex_shader_source_.empty()) {
// Detectar si necesitamos OpenGL ES (Raspberry Pi)
// Intentar cargar versión ES primero si existe
std::string VERTEX_FILE = "crtpi_vertex_es.glsl";
auto data = Asset::get()->loadData(VERTEX_FILE);
std::string vertex_file = "crtpi_vertex_es.glsl";
auto data = Asset::get()->loadData(vertex_file);
if (data.empty()) {
// Si no existe versión ES, usar versión Desktop
VERTEX_FILE = "crtpi_vertex.glsl";
data = Asset::get()->loadData(VERTEX_FILE);
vertex_file = "crtpi_vertex.glsl";
data = Asset::get()->loadData(vertex_file);
SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION,
"Usando shaders OpenGL Desktop 3.3");
} else {
@@ -252,13 +251,13 @@ void Screen::loadShaders() {
}
if (fragment_shader_source_.empty()) {
// Intentar cargar versión ES primero si existe
std::string FRAGMENT_FILE = "crtpi_fragment_es.glsl";
auto data = Asset::get()->loadData(FRAGMENT_FILE);
std::string fragment_file = "crtpi_fragment_es.glsl";
auto data = Asset::get()->loadData(fragment_file);
if (data.empty()) {
// Si no existe versión ES, usar versión Desktop
FRAGMENT_FILE = "crtpi_fragment.glsl";
data = Asset::get()->loadData(FRAGMENT_FILE);
fragment_file = "crtpi_fragment.glsl";
data = Asset::get()->loadData(fragment_file);
}
if (!data.empty()) {
@@ -450,8 +449,6 @@ void Screen::getDisplayInfo() {
// SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "Window resolution: %dx%d x%d", static_cast<int>(param.game.width), static_cast<int>(param.game.height), Options::window.zoom);
Logger::info("Window resolution: " + std::to_string(static_cast<int>(param.game.width)) + "x" + std::to_string(static_cast<int>(param.game.height)) + "x" + std::to_string(Options::window.zoom));
// Calcula el máximo factor de zoom que se puede aplicar a la pantalla
const int MAX_ZOOM = std::min(dm->w / param.game.width, (dm->h - WINDOWS_DECORATIONS) / param.game.height);

View File

@@ -43,8 +43,8 @@ class Screen {
void initShaders(); // Inicializa los shaders
// --- Efectos visuales ---
void shake(int desp = 2, float delay_s = 0.05f, float duration_s = 0.133f) { shake_effect_.enable(src_rect_, dst_rect_, desp, delay_s, duration_s); } // Agita la pantalla (tiempo en segundos)
void flash(Color color, float duration_s = 0.167f, float delay_s = 0.0f) { flash_effect_ = FlashEffect(true, duration_s, delay_s, color); } // Pone la pantalla de color (tiempo en segundos)
void shake(int desp = 2, float delay_s = 0.05F, float duration_s = 0.133F) { shake_effect_.enable(src_rect_, dst_rect_, desp, delay_s, duration_s); } // Agita la pantalla (tiempo en segundos)
void flash(Color color, float duration_s = 0.167F, float delay_s = 0.0F) { flash_effect_ = FlashEffect(true, duration_s, delay_s, color); } // Pone la pantalla de color (tiempo en segundos)
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
@@ -107,7 +107,7 @@ class Screen {
float timer_s; // Timer en segundos (contador decreciente)
Color color; // Color del flash
explicit FlashEffect(bool enabled = false, float duration_s = 0.0f, float delay_s = 0.0f, Color color = Color(0xFF, 0xFF, 0xFF))
explicit FlashEffect(bool enabled = false, float duration_s = 0.0F, float delay_s = 0.0F, Color color = Color(0xFF, 0xFF, 0xFF))
: enabled(enabled),
duration_s(duration_s),
delay_s(delay_s),
@@ -115,9 +115,9 @@ class Screen {
color(color) {}
void update(float delta_time) {
if (enabled && timer_s > 0.0f) {
if (enabled && timer_s > 0.0F) {
timer_s -= delta_time;
if (timer_s <= 0.0f) {
if (timer_s <= 0.0F) {
enabled = false;
}
}
@@ -136,7 +136,7 @@ class Screen {
int original_width; // Ancho original de la imagen
bool enabled; // Indica si el efecto está activo
explicit ShakeEffect(bool en = false, int dp = 2, float dl_s = 0.05f, float cnt_s = 0.0f, float len_s = 0.133f, float rem_s = 0.0f, int orig_pos = 0, int orig_width = 800)
explicit ShakeEffect(bool en = false, int dp = 2, float dl_s = 0.05F, float cnt_s = 0.0F, float len_s = 0.133F, float rem_s = 0.0F, int orig_pos = 0, int orig_width = 800)
: desp(dp),
delay_s(dl_s),
counter_s(cnt_s),
@@ -147,7 +147,7 @@ class Screen {
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, float new_delay_s = -1.0f, float new_duration_s = -1.0f) {
void enable(SDL_FRect& src_rect, SDL_FRect& dst_rect, int new_desp = -1, float new_delay_s = -1.0F, float new_duration_s = -1.0F) {
if (!enabled) {
enabled = true;
original_pos = src_rect.x;
@@ -157,10 +157,10 @@ class Screen {
if (new_desp != -1) {
desp = new_desp;
}
if (new_delay_s >= 0.0f) {
if (new_delay_s >= 0.0F) {
delay_s = new_delay_s;
}
if (new_duration_s >= 0.0f) {
if (new_duration_s >= 0.0F) {
duration_s = new_duration_s;
}
@@ -175,17 +175,17 @@ class Screen {
void update(SDL_FRect& src_rect, SDL_FRect& dst_rect, float delta_time) {
if (enabled) {
counter_s -= delta_time;
if (counter_s <= 0.0f) {
if (counter_s <= 0.0F) {
counter_s = delay_s;
// Alternar desplazamiento basado en tiempo restante
const bool SHAKE_LEFT = static_cast<int>(remaining_s * 30.0f) % 2 == 0; // ~30 cambios por segundo
const bool SHAKE_LEFT = static_cast<int>(remaining_s * 30.0F) % 2 == 0; // ~30 cambios por segundo
const auto SRC_DESP = SHAKE_LEFT ? 0 : desp;
const auto DST_DESP = SHAKE_LEFT ? desp : 0;
src_rect.x = original_pos + SRC_DESP;
dst_rect.x = original_pos + DST_DESP;
remaining_s -= delay_s;
if (remaining_s <= 0.0f) {
if (remaining_s <= 0.0F) {
enabled = false;
src_rect.x = original_pos;
src_rect.w = original_width;

View File

@@ -1,10 +1,11 @@
// IWYU pragma: no_include <bits/std_abs.h>
#include "credits.hpp"
#include <SDL3/SDL.h> // Para SDL_RenderFillRect, SDL_RenderTexture, SDL_SetRenderTarget, SDL_SetRenderDrawColor, SDL_CreateTexture, SDL_DestroyTexture, SDL_GetTicks, SDL_GetRenderTarget, SDL_PixelFormat, SDL_PollEvent, SDL_RenderClear, SDL_RenderRect, SDL_SetTextureBlendMode, SDL_TextureAccess, SDL_BLENDMODE_BLEND, SDL_Event
#include <SDL3/SDL.h> // Para SDL_RenderFillRect, SDL_RenderTexture, SDL_SetRenderTarget, SDL_SetRenderDrawColor, SDL_CreateTexture, SDL_DestroyTexture, SDL_GetTicks, SDL_GetRenderTarget, SDL_PixelFormat, SDL_PollEvent, SDL_RenderClear, SDL_RenderRect, SDL_SetTextureBlendMode, SDL_TextureAccess, SDL_BLENDMODE_BLEND, SDL_Event, Uint64
#include <algorithm> // Para max, min, clamp
#include <array> // Para array
#include <cmath> // Para abs
#include <stdexcept> // Para runtime_error
#include <string> // Para basic_string, string
#include <string_view> // Para string_view
@@ -12,23 +13,23 @@
#include "audio.hpp" // Para Audio
#include "balloon_manager.hpp" // Para BalloonManager
#include "color.hpp" // Para Zone, Colors::SHADOW_TEXT, Colors::NO_COLOR_MOD, Color
#include "fade.hpp" // Para Fade, FadeType, FadeMode
#include "global_events.hpp" // Para check
#include "color.hpp" // Para Color, SHADOW_TEXT, NO_COLOR_MOD
#include "fade.hpp" // Para Fade
#include "global_events.hpp" // Para handle
#include "global_inputs.hpp" // Para check
#include "input.hpp" // Para Input, Input::ALLOW_REPEAT
#include "input.hpp" // Para Input
#include "lang.hpp" // Para getText
#include "param.hpp" // Para Param, param, ParamGame, ParamFade
#include "player.hpp" // Para Player, PlayerState
#include "player.hpp" // Para Player
#include "resource.hpp" // Para Resource
#include "screen.hpp" // Para Screen
#include "section.hpp" // Para Name, name
#include "sprite.hpp" // Para Sprite
#include "text.hpp" // Para Text, Text::CENTER, Text::SHADOW
#include "text.hpp" // Para Text
#include "texture.hpp" // Para Texture
#include "tiled_bg.hpp" // Para TiledBG, TiledBGMode
#include "ui/service_menu.hpp" // Para ServiceMenu
#include "utils.hpp"
#include "utils.hpp" // Para Zone
// Textos
constexpr std::string_view TEXT_COPYRIGHT = "@2020,2025 JailDesigner";
@@ -81,10 +82,10 @@ Credits::~Credits() {
// Calcula el deltatime
auto Credits::calculateDeltaTime() -> float {
const Uint64 current_time = SDL_GetTicks();
const float delta_time = static_cast<float>(current_time - last_time_) / 1000.0f; // Convertir ms a segundos
last_time_ = current_time;
return delta_time;
const Uint64 CURRENT_TIME = SDL_GetTicks();
const float DELTA_TIME = static_cast<float>(CURRENT_TIME - last_time_) / 1000.0F; // Convertir ms a segundos
last_time_ = CURRENT_TIME;
return DELTA_TIME;
}
// Bucle principal
@@ -93,33 +94,33 @@ void Credits::run() {
while (Section::name == Section::Name::CREDITS) {
checkInput();
const float delta_time = calculateDeltaTime();
update(delta_time);
const float DELTA_TIME = calculateDeltaTime();
update(DELTA_TIME);
checkEvents(); // Tiene que ir antes del render
render();
}
}
// Actualiza las variables (time-based)
void Credits::update(float deltaTime) {
const float multiplier = want_to_pass_ ? 4.0f : 1.0f;
const float adjusted_delta_time = deltaTime * multiplier;
void Credits::update(float delta_time) {
const float MULTIPLIER = want_to_pass_ ? 4.0F : 1.0F;
const float ADJUSTED_DELTA_TIME = delta_time * MULTIPLIER;
static auto* const SCREEN = Screen::get();
SCREEN->update(deltaTime); // Actualiza el objeto screen
Audio::update(); // Actualiza el objeto audio
SCREEN->update(delta_time); // Actualiza el objeto screen
Audio::update(); // Actualiza el objeto audio
tiled_bg_->update(adjusted_delta_time);
tiled_bg_->update(ADJUSTED_DELTA_TIME);
cycleColors();
balloon_manager_->update(adjusted_delta_time);
updateTextureDstRects(adjusted_delta_time);
throwBalloons(adjusted_delta_time);
updatePlayers(adjusted_delta_time);
updateAllFades(adjusted_delta_time);
balloon_manager_->update(ADJUSTED_DELTA_TIME);
updateTextureDstRects(ADJUSTED_DELTA_TIME);
throwBalloons(ADJUSTED_DELTA_TIME);
updatePlayers(ADJUSTED_DELTA_TIME);
updateAllFades(ADJUSTED_DELTA_TIME);
// Convertir deltaTime a equivalente de frames (60fps)
const float frameFactor = adjusted_delta_time * 60.0f;
counter_ += frameFactor;
const float FRAME_FACTOR = ADJUSTED_DELTA_TIME * 60.0F;
counter_ += FRAME_FACTOR;
fillCanvas();
}
@@ -291,9 +292,9 @@ void Credits::fillCanvas() {
}
// Actualiza el destino de los rectangulos de las texturas (time-based)
void Credits::updateTextureDstRects(float deltaTime) {
constexpr float TEXTURE_UPDATE_INTERVAL_S = 10.0f / 60.0f; // ~0.167s (cada 10 frames)
credits_state_.texture_accumulator += deltaTime;
void Credits::updateTextureDstRects(float delta_time) {
constexpr float TEXTURE_UPDATE_INTERVAL_S = 10.0F / 60.0F; // ~0.167s (cada 10 frames)
credits_state_.texture_accumulator += delta_time;
if (credits_state_.texture_accumulator >= TEXTURE_UPDATE_INTERVAL_S) {
credits_state_.texture_accumulator -= TEXTURE_UPDATE_INTERVAL_S;
@@ -325,18 +326,18 @@ void Credits::updateTextureDstRects(float deltaTime) {
}
// Tira globos al escenario (time-based)
void Credits::throwBalloons(float deltaTime) {
void Credits::throwBalloons(float delta_time) {
constexpr int SPEED = 200;
const std::vector<int> SETS = {0, 63, 25, 67, 17, 75, 13, 50};
constexpr float BALLOON_INTERVAL_S = SPEED / 60.0f; // ~3.33s (cada 200 frames)
constexpr float POWERBALL_INTERVAL_S = (SPEED * 4) / 60.0f; // ~13.33s (cada 800 frames)
constexpr float BALLOON_INTERVAL_S = SPEED / 60.0F; // ~3.33s (cada 200 frames)
constexpr float POWERBALL_INTERVAL_S = (SPEED * 4) / 60.0F; // ~13.33s (cada 800 frames)
if (counter_ > ((SETS.size() - 1) * SPEED) * 3) {
return;
}
credits_state_.balloon_accumulator += deltaTime;
credits_state_.powerball_accumulator += deltaTime;
credits_state_.balloon_accumulator += delta_time;
credits_state_.powerball_accumulator += delta_time;
if (credits_state_.balloon_accumulator >= BALLOON_INTERVAL_S) {
credits_state_.balloon_accumulator -= BALLOON_INTERVAL_S;
@@ -418,12 +419,12 @@ void Credits::initPlayers() {
}
// Actualiza los rectangulos negros (time-based)
void Credits::updateBlackRects(float deltaTime) {
static float current_step_ = static_cast<float>(steps_);
constexpr float BLACK_RECT_INTERVAL_S = 4.0f / 60.0f; // ~0.067s (cada 4 frames)
void Credits::updateBlackRects(float delta_time) {
static auto current_step_ = static_cast<float>(steps_);
constexpr float BLACK_RECT_INTERVAL_S = 4.0F / 60.0F; // ~0.067s (cada 4 frames)
if (top_black_rect_.h != param.game.game_area.center_y - 1 && bottom_black_rect_.y != param.game.game_area.center_y + 1) {
// Si los rectangulos superior e inferior no han llegado al centro
credits_state_.black_rect_accumulator += deltaTime;
credits_state_.black_rect_accumulator += delta_time;
if (credits_state_.black_rect_accumulator >= BLACK_RECT_INTERVAL_S) {
credits_state_.black_rect_accumulator -= BLACK_RECT_INTERVAL_S;
@@ -459,8 +460,8 @@ void Credits::updateBlackRects(float deltaTime) {
fade_out_->activate();
} else {
// Convertir deltaTime a equivalente de frames
const float frameFactor = deltaTime * 60.0f;
counter_pre_fade_ += frameFactor;
const float FRAME_FACTOR = delta_time * 60.0F;
counter_pre_fade_ += FRAME_FACTOR;
}
}
}
@@ -475,9 +476,9 @@ void Credits::updateRedRect() {
}
// Actualiza el estado de fade (time-based)
void Credits::updateAllFades(float deltaTime) {
void Credits::updateAllFades(float delta_time) {
if (fading_) {
updateBlackRects(deltaTime);
updateBlackRects(delta_time);
updateRedRect();
}
@@ -510,7 +511,7 @@ void Credits::cycleColors() {
constexpr int LOWER_LIMIT = 30; // Límite inferior
// Inicializar valores RGB si es la primera vez
if (credits_state_.r == 255.0f && credits_state_.g == 0.0f && credits_state_.b == 0.0f && credits_state_.step_r == -0.5f) {
if (credits_state_.r == 255.0F && credits_state_.g == 0.0F && credits_state_.b == 0.0F && credits_state_.step_r == -0.5F) {
credits_state_.r = static_cast<float>(UPPER_LIMIT);
credits_state_.g = static_cast<float>(LOWER_LIMIT);
credits_state_.b = static_cast<float>(LOWER_LIMIT);
@@ -540,9 +541,9 @@ void Credits::cycleColors() {
}
// Actualza los jugadores (time-based)
void Credits::updatePlayers(float deltaTime) {
void Credits::updatePlayers(float delta_time) {
for (auto& player : players_) {
player->update(deltaTime);
player->update(delta_time);
}
}

View File

@@ -27,10 +27,9 @@ class Credits {
private:
// --- Métodos del bucle principal ---
void update(float deltaTime); // Actualización principal de la lógica (time-based)
void update(float delta_time); // Actualización principal de la lógica (time-based)
auto calculateDeltaTime() -> float; // Calcula el deltatime
private:
// --- Constantes de clase ---
static constexpr int PLAY_AREA_HEIGHT = 200;
@@ -67,16 +66,16 @@ class Credits {
// --- Estado de acumuladores para animaciones ---
struct CreditsState {
float texture_accumulator = 0.0f;
float balloon_accumulator = 0.0f;
float powerball_accumulator = 0.0f;
float black_rect_accumulator = 0.0f;
float r = 255.0f; // UPPER_LIMIT
float g = 0.0f; // LOWER_LIMIT
float b = 0.0f; // LOWER_LIMIT
float step_r = -0.5f;
float step_g = 0.3f;
float step_b = 0.1f;
float texture_accumulator = 0.0F;
float balloon_accumulator = 0.0F;
float powerball_accumulator = 0.0F;
float black_rect_accumulator = 0.0F;
float r = 255.0F; // UPPER_LIMIT
float g = 0.0F; // LOWER_LIMIT
float b = 0.0F; // LOWER_LIMIT
float step_r = -0.5F;
float step_g = 0.3F;
float step_b = 0.1F;
} credits_state_;
// --- Rectángulos de renderizado ---
@@ -130,20 +129,20 @@ class Credits {
void renderPlayers(); // Renderiza los jugadores
// --- Métodos de lógica del juego ---
void throwBalloons(); // Lanzar globos al escenario (frame-based)
void throwBalloons(float deltaTime); // Lanzar globos al escenario (time-based)
void initPlayers(); // Inicializar jugadores
void updateAllFades(); // Actualizar estados de fade (frame-based)
void updateAllFades(float deltaTime); // Actualizar estados de fade (time-based)
void cycleColors(); // Cambiar colores de fondo
void updatePlayers(float deltaTime); // Actualza los jugadores (time-based)
void throwBalloons(); // Lanzar globos al escenario (frame-based)
void throwBalloons(float delta_time); // Lanzar globos al escenario (time-based)
void initPlayers(); // Inicializar jugadores
void updateAllFades(); // Actualizar estados de fade (frame-based)
void updateAllFades(float delta_time); // Actualizar estados de fade (time-based)
void cycleColors(); // Cambiar colores de fondo
void updatePlayers(float delta_time); // Actualza los jugadores (time-based)
// --- Métodos de interfaz ---
void updateBlackRects(); // Actualizar rectángulos negros (letterbox) (frame-based)
void updateBlackRects(float deltaTime); // Actualizar rectángulos negros (letterbox) (time-based)
void updateRedRect(); // Actualizar rectángulo rojo (borde)
void updateTextureDstRects(); // Actualizar destinos de texturas (frame-based)
void updateTextureDstRects(float deltaTime); // Actualizar destinos de texturas (time-based)
void updateBlackRects(); // Actualizar rectángulos negros (letterbox) (frame-based)
void updateBlackRects(float delta_time); // Actualizar rectángulos negros (letterbox) (time-based)
void updateRedRect(); // Actualizar rectángulo rojo (borde)
void updateTextureDstRects(); // Actualizar destinos de texturas (frame-based)
void updateTextureDstRects(float delta_time); // Actualizar destinos de texturas (time-based)
// --- Métodos de audio ---
static void setVolume(int amount); // Establecer volumen

View File

@@ -1,14 +1,16 @@
#include "game.hpp"
#include <SDL3/SDL.h> // Para SDL_GetTicks, SDL_SetRenderTarget, SDL_CreateTexture, SDL_Delay, SDL_DestroyTexture, SDL_EventType, SDL_GetRenderTarget, SDL_PollEvent, SDL_RenderTexture, SDL_SetTextureBlendMode, SDL_BLENDMODE_BLEND, SDL_Event, SDL_PixelFormat, SDL_Point, SDL_TextureAccess
#include <SDL3/SDL.h> // Para SDL_GetTicks, SDL_SetRenderTarget, SDL_EventType, SDL_CreateTexture, SDL_Delay, SDL_DestroyTexture, SDL_Event, SDL_GetRenderTarget, SDL_PollEvent, SDL_RenderTexture, SDL_SetTextureBlendMode, SDLK_1, SDLK_2, SDLK_3, SDLK_4, SDLK_5, SDLK_6, SDLK_7, SDLK_8, SDLK_9, SDLK_KP_MINUS, SDLK_KP_PLUS, SDL_BLENDMODE_BLEND, SDL_PixelFormat, SDL_Point, SDL_TextureAccess, Uint64
#include <algorithm> // Para find, clamp, find_if, min, std::shuffle, std::iota
#include <algorithm> // Para find, clamp, find_if, min, shuffle
#include <array> // Para array
#include <cstdlib> // Para rand, size_t
#include <functional> // Para function
#include <iterator> // Para size
#include <memory> // Para shared_ptr, unique_ptr, __shared_ptr_access, allocator, make_unique, operator==, make_shared
#include <random> // std::random_device, std::default_random_engine
#include <memory> // Para shared_ptr, unique_ptr, __shared_ptr_access, make_unique, allocator, operator==
#include <numeric> // Para iota
#include <optional> // Para optional
#include <random> // Para random_device, default_random_engine
#include <utility> // Para move
#include "asset.hpp" // Para Asset
@@ -16,12 +18,12 @@
#include "background.hpp" // Para Background
#include "balloon.hpp" // Para Balloon
#include "balloon_manager.hpp" // Para BalloonManager
#include "bullet.hpp" // Para Bullet, Bullet::Type, BulletMoveStatus
#include "bullet.hpp" // Para Bullet
#include "bullet_manager.hpp" // Para BulletManager
#include "color.hpp" // Para Color, Colors::FLASH
#include "color.hpp" // Para Color, FLASH, NO_COLOR_MOD
#include "difficulty.hpp" // Para Code
#include "fade.hpp" // Para Fade, FadeType, FadeMode
#include "global_events.hpp" // Para check
#include "fade.hpp" // Para Fade
#include "global_events.hpp" // Para handle
#include "global_inputs.hpp" // Para check
#include "hit.hpp" // Para Hit
#include "input.hpp" // Para Input
@@ -30,7 +32,7 @@
#include "lang.hpp" // Para getText
#include "manage_hiscore_table.hpp" // Para HiScoreEntry, ManageHiScoreTable
#include "param.hpp" // Para Param, param, ParamGame, ParamScoreboard, ParamFade, ParamBalloon
#include "path_sprite.hpp" // Para Path, PathSprite, createPath, PathType
#include "path_sprite.hpp" // Para Path, PathSprite, PathType
#include "pause_manager.hpp" // Para PauseManager
#include "player.hpp" // Para Player
#include "resource.hpp" // Para Resource
@@ -38,13 +40,14 @@
#include "screen.hpp" // Para Screen
#include "section.hpp" // Para Name, name, AttractMode, Options, attract_mode, options
#include "smart_sprite.hpp" // Para SmartSprite
#include "stage.hpp" // Para number, Stage, get, total_power, power, init, power_can_be_added, stages
#include "stage.hpp" // Para StageManager, StageData
#include "tabe.hpp" // Para Tabe
#include "text.hpp" // Para Text
#include "texture.hpp" // Para Texture
#include "ui/service_menu.hpp" // Para ServiceMenu
#include "utils.hpp" // Para Zone, checkCollision, easeInQuint, easeOutQuint, boolToString
#ifdef _DEBUG
#include <iostream> // Para std::cout
#include <iostream> // Para basic_ostream, basic_ostream::operator<<, operator<<, cout
#include "ui/notifier.hpp" // Para Notifier
#endif
@@ -240,9 +243,9 @@ void Game::updateHiScore() {
}
// Actualiza las variables del jugador
void Game::updatePlayers(float deltaTime) {
void Game::updatePlayers(float delta_time) {
for (auto& player : players_) {
player->update(deltaTime);
player->update(delta_time);
if (player->isPlaying()) {
// Comprueba la colisión entre el jugador y los globos
@@ -341,29 +344,29 @@ void Game::updateStage() {
}
// Actualiza las variables y sistemas durante el estado de fin de partida
void Game::updateGameStateGameOver(float deltaTime) {
void Game::updateGameStateGameOver(float delta_time) {
fade_out_->update();
updatePlayers(deltaTime);
updateScoreboard(deltaTime);
updateBackground(deltaTime);
balloon_manager_->update(deltaTime);
tabe_->update(deltaTime);
bullet_manager_->update(deltaTime);
updateItems(deltaTime);
updateSmartSprites(deltaTime);
updatePathSprites(deltaTime);
updateTimeStopped(deltaTime);
updatePlayers(delta_time);
updateScoreboard(delta_time);
updateBackground(delta_time);
balloon_manager_->update(delta_time);
tabe_->update(delta_time);
bullet_manager_->update(delta_time);
updateItems(delta_time);
updateSmartSprites(delta_time);
updatePathSprites(delta_time);
updateTimeStopped(delta_time);
bullet_manager_->checkCollisions();
cleanVectors();
if (game_over_timer_ < GAME_OVER_DURATION_S) {
game_over_timer_ += deltaTime; // Incremento time-based primero
handleGameOverEvents(); // Maneja eventos después del incremento
game_over_timer_ += delta_time; // Incremento time-based primero
handleGameOverEvents(); // Maneja eventos después del incremento
}
if (Options::audio.enabled) {
const float progress = std::min(game_over_timer_ / GAME_OVER_DURATION_S, 1.0f);
const float VOL = 64.0f * (1.0f - progress);
const float PROGRESS = std::min(game_over_timer_ / GAME_OVER_DURATION_S, 1.0F);
const float VOL = 64.0F * (1.0F - PROGRESS);
Audio::get()->setSoundVolume(static_cast<int>(VOL), Audio::Group::GAME);
}
@@ -378,16 +381,16 @@ void Game::updateGameStateGameOver(float deltaTime) {
}
// Gestiona eventos para el estado del final del juego
void Game::updateGameStateCompleted(float deltaTime) {
updatePlayers(deltaTime);
updateScoreboard(deltaTime);
updateBackground(deltaTime);
balloon_manager_->update(deltaTime);
tabe_->update(deltaTime);
bullet_manager_->update(deltaTime);
updateItems(deltaTime);
updateSmartSprites(deltaTime);
updatePathSprites(deltaTime);
void Game::updateGameStateCompleted(float delta_time) {
updatePlayers(delta_time);
updateScoreboard(delta_time);
updateBackground(delta_time);
balloon_manager_->update(delta_time);
tabe_->update(delta_time);
bullet_manager_->update(delta_time);
updateItems(delta_time);
updateSmartSprites(delta_time);
updatePathSprites(delta_time);
cleanVectors();
// Maneja eventos del juego completado
@@ -399,7 +402,7 @@ void Game::updateGameStateCompleted(float deltaTime) {
}
// Incrementa el acumulador al final
game_completed_timer_ += deltaTime;
game_completed_timer_ += delta_time;
}
// Comprueba el estado del juego
@@ -589,9 +592,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();
}
@@ -600,13 +603,13 @@ void Game::handleBalloonDestruction(std::shared_ptr<Balloon> balloon, const std:
}
// Actualiza los items
void Game::updateItems(float deltaTime) {
void Game::updateItems(float delta_time) {
for (auto& item : items_) {
if (item->isEnabled()) {
item->update(deltaTime);
item->update(delta_time);
if (item->isOnFloor()) {
playSound("title.wav");
screen_->shake(1, 0.033f, 0.067f); // desp=1, delay=0.033s, length=0.067s
screen_->shake(1, 0.033F, 0.067F); // desp=1, delay=0.033s, length=0.067s
}
}
}
@@ -711,8 +714,8 @@ void Game::createItemText(int x, const std::shared_ptr<Texture>& texture) {
path_sprites_.back()->setWidth(W);
path_sprites_.back()->setHeight(H);
path_sprites_.back()->setSpriteClip({0, 0, static_cast<float>(W), static_cast<float>(H)});
path_sprites_.back()->addPath(Y0, Y1, PathType::VERTICAL, x, 1.667f, easeOutQuint, 0); // 100 frames → 1.667s
path_sprites_.back()->addPath(Y1, Y2, PathType::VERTICAL, x, 1.333f, easeInQuint, 0); // 80 frames → 1.333s
path_sprites_.back()->addPath(Y0, Y1, PathType::VERTICAL, x, 1.667F, easeOutQuint, 0); // 100 frames → 1.667s
path_sprites_.back()->addPath(Y1, Y2, PathType::VERTICAL, x, 1.333F, easeInQuint, 0); // 80 frames → 1.333s
path_sprites_.back()->enable();
}
@@ -757,10 +760,10 @@ void Game::throwCoffee(int x, int y) {
smart_sprites_.back()->setPosY(y - 8);
smart_sprites_.back()->setWidth(Item::WIDTH);
smart_sprites_.back()->setHeight(Item::HEIGHT);
smart_sprites_.back()->setVelX((-1.0F + ((rand() % 5) * 0.5F)) * 60.0f); // Convertir a pixels/segundo
smart_sprites_.back()->setVelY(-4.0F * 60.0f); // Convertir a pixels/segundo
smart_sprites_.back()->setVelX((-1.0F + ((rand() % 5) * 0.5F)) * 60.0F); // Convertir a pixels/segundo
smart_sprites_.back()->setVelY(-4.0F * 60.0F); // Convertir a pixels/segundo
smart_sprites_.back()->setAccelX(0.0F);
smart_sprites_.back()->setAccelY(0.2F * 60.0f * 60.0f); // Convertir a pixels/segundo² (0.2 × 60²)
smart_sprites_.back()->setAccelY(0.2F * 60.0F * 60.0F); // Convertir a pixels/segundo² (0.2 × 60²)
smart_sprites_.back()->setDestX(x + (smart_sprites_.back()->getVelX() * 50));
smart_sprites_.back()->setDestY(param.game.height + 1);
smart_sprites_.back()->setEnabled(true);
@@ -772,9 +775,9 @@ void Game::throwCoffee(int x, int y) {
}
// Actualiza los SmartSprites
void Game::updateSmartSprites(float deltaTime) {
void Game::updateSmartSprites(float delta_time) {
for (auto& sprite : smart_sprites_) {
sprite->update(deltaTime);
sprite->update(delta_time);
}
}
@@ -786,9 +789,9 @@ void Game::renderSmartSprites() {
}
// Actualiza los PathSprites
void Game::updatePathSprites(float deltaTime) {
void Game::updatePathSprites(float delta_time) {
for (auto& sprite : path_sprites_) {
sprite->update(deltaTime);
sprite->update(delta_time);
}
}
@@ -831,44 +834,44 @@ void Game::handlePlayerCollision(std::shared_ptr<Player>& player, std::shared_pt
}
// Actualiza el estado del tiempo detenido
void Game::updateTimeStopped(float deltaTime) {
static constexpr float WARNING_THRESHOLD_S = 2.0f; // 120 frames a 60fps → segundos
static constexpr float CLOCK_SOUND_INTERVAL_S = 0.5f; // 30 frames a 60fps → segundos
static constexpr float COLOR_FLASH_INTERVAL_S = 0.25f; // 15 frames a 60fps → segundos
void Game::updateTimeStopped(float delta_time) {
static constexpr float WARNING_THRESHOLD_S = 2.0F; // 120 frames a 60fps → segundos
static constexpr float CLOCK_SOUND_INTERVAL_S = 0.5F; // 30 frames a 60fps → segundos
static constexpr float COLOR_FLASH_INTERVAL_S = 0.25F; // 15 frames a 60fps → segundos
if (time_stopped_timer_ > 0) {
time_stopped_timer_ -= deltaTime;
time_stopped_timer_ -= delta_time;
// Fase de advertencia (últimos 2 segundos)
if (time_stopped_timer_ <= WARNING_THRESHOLD_S) {
static float last_sound_time = 0.0f;
static float last_sound_time_ = 0.0F;
// CLAC al entrar en fase de advertencia
if (!time_stopped_flags_.warning_phase_started) {
playSound("clock.wav");
time_stopped_flags_.warning_phase_started = true;
last_sound_time = 0.0f; // Reset para empezar el ciclo rápido
last_sound_time_ = 0.0F; // Reset para empezar el ciclo rápido
}
last_sound_time += deltaTime;
last_sound_time_ += delta_time;
if (last_sound_time >= CLOCK_SOUND_INTERVAL_S) {
if (last_sound_time_ >= CLOCK_SOUND_INTERVAL_S) {
balloon_manager_->normalColorsToAllBalloons();
playSound("clock.wav");
last_sound_time = 0.0f;
last_sound_time_ = 0.0F;
time_stopped_flags_.color_flash_sound_played = false; // Reset flag para el próximo intervalo
} else if (last_sound_time >= COLOR_FLASH_INTERVAL_S && !time_stopped_flags_.color_flash_sound_played) {
} else if (last_sound_time_ >= COLOR_FLASH_INTERVAL_S && !time_stopped_flags_.color_flash_sound_played) {
balloon_manager_->reverseColorsToAllBalloons();
playSound("clock.wav");
time_stopped_flags_.color_flash_sound_played = true; // Evita que suene múltiples veces
}
} else {
// Fase normal - solo sonido ocasional
static float sound_timer = 0.0f;
sound_timer += deltaTime;
if (sound_timer >= CLOCK_SOUND_INTERVAL_S) {
static float sound_timer_ = 0.0F;
sound_timer_ += delta_time;
if (sound_timer_ >= CLOCK_SOUND_INTERVAL_S) {
playSound("clock.wav");
sound_timer = 0.0f;
sound_timer_ = 0.0F;
}
}
@@ -881,15 +884,15 @@ void Game::updateTimeStopped(float deltaTime) {
}
// Actualiza toda la lógica del juego
void Game::update(float deltaTime) {
screen_->update(deltaTime); // Actualiza el objeto screen
Audio::update(); // Actualiza el objeto audio
void Game::update(float delta_time) {
screen_->update(delta_time); // Actualiza el objeto screen
Audio::update(); // Actualiza el objeto audio
updateDemo(deltaTime);
updateDemo(delta_time);
#ifdef RECORDING
updateRecording(deltaTime);
#endif
updateGameStates(deltaTime);
updateGameStates(delta_time);
fillCanvas();
}
@@ -909,26 +912,26 @@ void Game::render() {
}
// Actualiza los estados del juego
void Game::updateGameStates(float deltaTime) {
void Game::updateGameStates(float delta_time) {
if (!pause_manager_->isPaused()) {
switch (state_) {
case State::FADE_IN:
updateGameStateFadeIn(deltaTime);
updateGameStateFadeIn(delta_time);
break;
case State::ENTERING_PLAYER:
updateGameStateEnteringPlayer(deltaTime);
updateGameStateEnteringPlayer(delta_time);
break;
case State::SHOWING_GET_READY_MESSAGE:
updateGameStateShowingGetReadyMessage(deltaTime);
updateGameStateShowingGetReadyMessage(delta_time);
break;
case State::PLAYING:
updateGameStatePlaying(deltaTime);
updateGameStatePlaying(delta_time);
break;
case State::COMPLETED:
updateGameStateCompleted(deltaTime);
updateGameStateCompleted(delta_time);
break;
case State::GAME_OVER:
updateGameStateGameOver(deltaTime);
updateGameStateGameOver(delta_time);
break;
default:
break;
@@ -937,8 +940,8 @@ void Game::updateGameStates(float deltaTime) {
}
// Actualiza el fondo
void Game::updateBackground(float deltaTime) {
background_->update(deltaTime);
void Game::updateBackground(float delta_time) {
background_->update(delta_time);
}
// Dibuja los elementos de la zona de juego en su textura
@@ -980,10 +983,10 @@ void Game::disableTimeStopItem() {
// Calcula el deltatime en segundos
auto Game::calculateDeltaTime() -> float {
const Uint64 current_time = SDL_GetTicks();
const float delta_time_ms = static_cast<float>(current_time - last_time_);
last_time_ = current_time;
return delta_time_ms / 1000.0f; // Convertir de milisegundos a segundos
const Uint64 CURRENT_TIME = SDL_GetTicks();
const auto DELTA_TIME_MS = static_cast<float>(CURRENT_TIME - last_time_);
last_time_ = CURRENT_TIME;
return DELTA_TIME_MS / 1000.0F; // Convertir de milisegundos a segundos
}
// Bucle para el juego
@@ -991,9 +994,9 @@ void Game::run() {
last_time_ = SDL_GetTicks();
while (Section::name == Section::Name::GAME) {
const float delta_time = calculateDeltaTime();
const float DELTA_TIME = calculateDeltaTime();
checkInput();
update(delta_time);
update(DELTA_TIME);
handleEvents(); // Tiene que ir antes del render
render();
}
@@ -1003,7 +1006,7 @@ void Game::run() {
void Game::initPaths() {
// --- Duración estándar para 80 frames ---
// (Basado en tu ejemplo: 80 frames → 1.333s)
const float DURATION_80F_S = 1.333f;
const float DURATION_80F_S = 1.333F;
// Recorrido para el texto de "Get Ready!" (0,1)
{
@@ -1013,9 +1016,9 @@ void Game::initPaths() {
const int X1 = param.game.play_area.center_x - (W / 2);
const int X2 = param.game.play_area.rect.w;
// Y_base es la LÍNEA CENTRAL. addPath(true) restará H/2
const int Y_base = param.game.play_area.center_y;
paths_.emplace_back(X0, X1, PathType::HORIZONTAL, Y_base, DURATION_80F_S, 0.5f, easeOutQuint);
paths_.emplace_back(X1, X2, PathType::HORIZONTAL, Y_base, DURATION_80F_S, 0.0f, easeInQuint);
const int Y_BASE = param.game.play_area.center_y;
paths_.emplace_back(X0, X1, PathType::HORIZONTAL, Y_BASE, DURATION_80F_S, 0.5F, easeOutQuint);
paths_.emplace_back(X1, X2, PathType::HORIZONTAL, Y_BASE, DURATION_80F_S, 0.0F, easeInQuint);
}
// Recorrido para el texto de "Last Stage!" o de "X stages left" (2,3)
@@ -1026,9 +1029,9 @@ void Game::initPaths() {
const int Y1 = param.game.play_area.center_y - (H / 2);
const int Y2 = -H;
// X_base es la LÍNEA CENTRAL. addPath(true) restará W/2
const int X_base = param.game.play_area.center_x;
paths_.emplace_back(Y0, Y1, PathType::VERTICAL, X_base, DURATION_80F_S, 0.5f, easeOutQuint);
paths_.emplace_back(Y1, Y2, PathType::VERTICAL, X_base, DURATION_80F_S, 0.0f, easeInQuint);
const int X_BASE = param.game.play_area.center_x;
paths_.emplace_back(Y0, Y1, PathType::VERTICAL, X_BASE, DURATION_80F_S, 0.5F, easeOutQuint);
paths_.emplace_back(Y1, Y2, PathType::VERTICAL, X_BASE, DURATION_80F_S, 0.0F, easeInQuint);
}
// Recorrido para el texto de "Congratulations!!" (4,5)
@@ -1040,9 +1043,9 @@ void Game::initPaths() {
const int X1 = param.game.play_area.center_x - (W / 2);
const int X2 = param.game.play_area.rect.w;
// Y_base es la LÍNEA CENTRAL. addPath(true) restará H/2
const int Y_base = param.game.play_area.center_y - (H / 2);
paths_.emplace_back(X0, X1, PathType::HORIZONTAL, Y_base, DURATION_80F_S, 7.0f, easeOutQuint);
paths_.emplace_back(X1, X2, PathType::HORIZONTAL, Y_base, DURATION_80F_S, 0.0f, easeInQuint);
const int Y_BASE = param.game.play_area.center_y - (H / 2);
paths_.emplace_back(X0, X1, PathType::HORIZONTAL, Y_BASE, DURATION_80F_S, 7.0F, easeOutQuint);
paths_.emplace_back(X1, X2, PathType::HORIZONTAL, Y_BASE, DURATION_80F_S, 0.0F, easeInQuint);
}
// Recorrido para el texto de "1.000.000 points!" (6,7)
@@ -1054,9 +1057,9 @@ void Game::initPaths() {
const int X1 = param.game.play_area.center_x - (W / 2);
const int X2 = -W;
// Y_base es la LÍNEA CENTRAL (desplazada PREV_H hacia abajo). addPath(true) restará H/2
const int Y_base = param.game.play_area.center_y + (H / 2);
paths_.emplace_back(X0, X1, PathType::HORIZONTAL, Y_base, DURATION_80F_S, 7.0f, easeOutQuint);
paths_.emplace_back(X1, X2, PathType::HORIZONTAL, Y_base, DURATION_80F_S, 0.0f, easeInQuint);
const int Y_BASE = param.game.play_area.center_y + (H / 2);
paths_.emplace_back(X0, X1, PathType::HORIZONTAL, Y_BASE, DURATION_80F_S, 7.0F, easeOutQuint);
paths_.emplace_back(X1, X2, PathType::HORIZONTAL, Y_BASE, DURATION_80F_S, 0.0F, easeInQuint);
}
// Recorrido para el texto de "New Record!" (8,9)
@@ -1068,9 +1071,9 @@ void Game::initPaths() {
const int X1 = param.game.play_area.center_x - (W / 2); // Destino (no-fijo), está bien
const int X2 = param.game.play_area.rect.w;
// Y_base es la LÍNEA CENTRAL (desplazada 2*H hacia arriba). addPath(true) restará H/2
const int Y_base = param.game.play_area.center_y - (H * 2);
paths_.emplace_back(X0, X1, PathType::HORIZONTAL, Y_base, DURATION_80F_S, 1.0f, easeOutQuint);
paths_.emplace_back(X1, X2, PathType::HORIZONTAL, Y_base, DURATION_80F_S, 0.0f, easeInQuint);
const int Y_BASE = param.game.play_area.center_y - (H * 2);
paths_.emplace_back(X0, X1, PathType::HORIZONTAL, Y_BASE, DURATION_80F_S, 1.0F, easeOutQuint);
paths_.emplace_back(X1, X2, PathType::HORIZONTAL, Y_BASE, DURATION_80F_S, 0.0F, easeInQuint);
}
// Recorrido para el texto de "Game Over" (10,11)
@@ -1081,9 +1084,9 @@ void Game::initPaths() {
const int Y1 = param.game.play_area.center_y - (H / 2); // Destino (no-fijo), está bien
const int Y2 = -H;
// X_base es la LÍNEA CENTRAL. addPath(true) restará W/2
const int X_base = param.game.play_area.center_x;
paths_.emplace_back(Y0, Y1, PathType::VERTICAL, X_base, DURATION_80F_S, 2.0f, easeOutQuint);
paths_.emplace_back(Y1, Y2, PathType::VERTICAL, X_base, DURATION_80F_S, 0.0f, easeInQuint);
const int X_BASE = param.game.play_area.center_x;
paths_.emplace_back(Y0, Y1, PathType::VERTICAL, X_BASE, DURATION_80F_S, 2.0F, easeOutQuint);
paths_.emplace_back(Y1, Y2, PathType::VERTICAL, X_BASE, DURATION_80F_S, 0.0F, easeInQuint);
}
}
@@ -1159,7 +1162,7 @@ void Game::handleEvents() {
}
// Actualiza el marcador
void Game::updateScoreboard(float deltaTime) {
void Game::updateScoreboard(float delta_time) {
for (const auto& player : players_) {
scoreboard_->setScore(player->getScoreBoardPanel(), player->getScore());
scoreboard_->setMult(player->getScoreBoardPanel(), player->getScoreMultiplier());
@@ -1171,7 +1174,7 @@ void Game::updateScoreboard(float deltaTime) {
scoreboard_->setHiScore(hi_score_.score);
scoreboard_->setHiScoreName(hi_score_.name);
scoreboard_->update(deltaTime);
scoreboard_->update(delta_time);
}
// Pone en el marcador el nombre del primer jugador de la tabla
@@ -1207,7 +1210,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;
@@ -1699,7 +1702,7 @@ void Game::stopMusic() const {
}
// Actualiza las variables durante el modo demo
void Game::updateDemo(float deltaTime) {
void Game::updateDemo(float delta_time) {
if (demo_.enabled) {
balloon_manager_->setCreationTimeEnabled(balloon_manager_->getNumBalloons() != 0);
@@ -1708,7 +1711,7 @@ void Game::updateDemo(float deltaTime) {
fade_out_->update();
// Actualiza el contador de tiempo y el índice
demo_.elapsed_s += deltaTime;
demo_.elapsed_s += delta_time;
demo_.index = static_cast<int>(demo_.elapsed_s * 60.0F);
// Activa el fundido antes de acabar con los datos de la demo
@@ -1755,10 +1758,10 @@ void Game::updateRecording(float deltaTime) {
#endif
// Actualiza las variables durante dicho estado
void Game::updateGameStateFadeIn(float deltaTime) {
void Game::updateGameStateFadeIn(float delta_time) {
fade_in_->update();
updateScoreboard(deltaTime);
updateBackground(deltaTime);
updateScoreboard(delta_time);
updateBackground(delta_time);
if (fade_in_->hasEnded()) {
setState(State::ENTERING_PLAYER);
balloon_manager_->createTwoBigBalloons();
@@ -1767,11 +1770,11 @@ void Game::updateGameStateFadeIn(float deltaTime) {
}
// Actualiza las variables durante dicho estado
void Game::updateGameStateEnteringPlayer(float deltaTime) {
balloon_manager_->update(deltaTime);
updatePlayers(deltaTime);
updateScoreboard(deltaTime);
updateBackground(deltaTime);
void Game::updateGameStateEnteringPlayer(float delta_time) {
balloon_manager_->update(delta_time);
updatePlayers(delta_time);
updateScoreboard(delta_time);
updateBackground(delta_time);
for (const auto& player : players_) {
if (player->isPlaying()) {
setState(State::SHOWING_GET_READY_MESSAGE);
@@ -1782,38 +1785,38 @@ void Game::updateGameStateEnteringPlayer(float deltaTime) {
}
// Actualiza las variables durante dicho estado
void Game::updateGameStateShowingGetReadyMessage(float deltaTime) {
updateGameStatePlaying(deltaTime);
void Game::updateGameStateShowingGetReadyMessage(float delta_time) {
updateGameStatePlaying(delta_time);
constexpr float MUSIC_START_S = 1.67F;
static float music_timer = 0.0f;
music_timer += deltaTime;
if (music_timer >= MUSIC_START_S) {
static float music_timer_ = 0.0F;
music_timer_ += delta_time;
if (music_timer_ >= MUSIC_START_S) {
playMusic("playing.ogg");
music_timer = 0.0F;
music_timer_ = 0.0F;
setState(State::PLAYING);
}
}
// Actualiza las variables durante el transcurso normal del juego
void Game::updateGameStatePlaying(float deltaTime) {
void Game::updateGameStatePlaying(float delta_time) {
#ifdef _DEBUG
if (auto_pop_balloons_) {
stage_manager_->addPower(2);
}
#endif
updatePlayers(deltaTime);
updatePlayers(delta_time);
checkPlayersStatusPlaying();
updateScoreboard(deltaTime);
updateBackground(deltaTime);
balloon_manager_->update(deltaTime);
tabe_->update(deltaTime);
bullet_manager_->update(deltaTime);
updateItems(deltaTime);
updateScoreboard(delta_time);
updateBackground(delta_time);
balloon_manager_->update(delta_time);
tabe_->update(delta_time);
bullet_manager_->update(delta_time);
updateItems(delta_time);
updateStage();
updateSmartSprites(deltaTime);
updatePathSprites(deltaTime);
updateTimeStopped(deltaTime);
updateSmartSprites(delta_time);
updatePathSprites(delta_time);
updateTimeStopped(delta_time);
updateHelper();
bullet_manager_->checkCollisions();
updateMenace();
@@ -1916,9 +1919,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);
}
@@ -1929,9 +1932,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);
}
@@ -1957,8 +1960,8 @@ void Game::onPauseStateChanged(bool is_paused) {
// Maneja eventos del juego completado usando flags para triggers únicos
void Game::handleGameCompletedEvents() {
constexpr float START_CELEBRATIONS_S = 6.0f;
constexpr float END_CELEBRATIONS_S = 14.0f;
constexpr float START_CELEBRATIONS_S = 6.0F;
constexpr float END_CELEBRATIONS_S = 14.0F;
// Inicio de celebraciones
if (!game_completed_flags_.start_celebrations_triggered && game_completed_timer_ >= START_CELEBRATIONS_S) {
@@ -1992,8 +1995,8 @@ void Game::handleGameCompletedEvents() {
// Maneja eventos discretos basados en tiempo durante el estado game over
void Game::handleGameOverEvents() {
constexpr float MESSAGE_TRIGGER_S = 1.5f;
constexpr float FADE_TRIGGER_S = GAME_OVER_DURATION_S - 2.5f;
constexpr float MESSAGE_TRIGGER_S = 1.5F;
constexpr float FADE_TRIGGER_S = GAME_OVER_DURATION_S - 2.5F;
// Trigger inicial: fade out de música y sonidos de globos
if (!game_over_flags_.music_fade_triggered) {

View File

@@ -1,23 +1,18 @@
#pragma once
#include <SDL3/SDL.h> // Para SDL_Renderer, SDL_Texture, Uint64, Uint8
#include <SDL3/SDL.h> // Para SDL_Event, SDL_Renderer, SDL_Texture, Uint64
#include <memory> // Para shared_ptr, unique_ptr
#include <string> // Para string
#include <vector> // Para vector
#include "bullet.hpp" // Para Bullet
#include "bullet_manager.hpp" // Para BulletManager
#include "demo.hpp" // Para Demo
#include "hit.hpp" // Para Hit
#include "item.hpp" // Para Item, ItemType
#include "manage_hiscore_table.hpp" // Para HiScoreEntry
#include "options.hpp" // Para Settings, settings
#include "path_sprite.hpp" // Para PathSprite, Path
#include "player.hpp" // Para Player
#include "smart_sprite.hpp" // Para SmartSprite
#include "stage.hpp" // Para StageManager
#include "utils.hpp" // Para otras utilidades
#include "bullet.hpp" // for Bullet
#include "demo.hpp" // for Demo
#include "hit.hpp" // for Hit
#include "item.hpp" // for Item (ptr only), ItemType
#include "manage_hiscore_table.hpp" // for HiScoreEntry
#include "options.hpp" // for Settings, settings
#include "player.hpp" // for Player
class Background;
class Balloon;
@@ -25,11 +20,15 @@ class BalloonManager;
class BulletManager;
class Fade;
class Input;
class PathSprite;
class PauseManager;
class Scoreboard;
class Screen;
class SmartSprite;
class StageManager;
class Tabe;
class Texture;
struct Path;
namespace Difficulty {
enum class Code;
@@ -76,12 +75,12 @@ class Game {
};
// --- Constantes de tiempo (en segundos) ---
static constexpr float HELP_COUNTER_S = 16.667f; // Contador de ayuda (1000 frames a 60fps → segundos)
static constexpr float GAME_COMPLETED_START_FADE_S = 8.333f; // Inicio del fade al completar (500 frames → segundos)
static constexpr float GAME_COMPLETED_END_S = 11.667f; // Fin del juego completado (700 frames → segundos)
static constexpr float GAME_OVER_DURATION_S = 8.5f;
static constexpr float TIME_STOPPED_DURATION_S = 6.0f;
static constexpr float DEMO_FADE_PRE_DURATION_S = 0.5f;
static constexpr float HELP_COUNTER_S = 16.667F; // Contador de ayuda (1000 frames a 60fps → segundos)
static constexpr float GAME_COMPLETED_START_FADE_S = 8.333F; // Inicio del fade al completar (500 frames → segundos)
static constexpr float GAME_COMPLETED_END_S = 11.667F; // Fin del juego completado (700 frames → segundos)
static constexpr float GAME_OVER_DURATION_S = 8.5F;
static constexpr float TIME_STOPPED_DURATION_S = 6.0F;
static constexpr float DEMO_FADE_PRE_DURATION_S = 0.5F;
static constexpr int ITEM_POINTS_1_DISK_ODDS = 10;
static constexpr int ITEM_POINTS_2_GAVINA_ODDS = 6;
static constexpr int ITEM_POINTS_3_PACMAR_ODDS = 3;
@@ -155,11 +154,11 @@ class Game {
Uint64 last_time_ = 0; // Último tiempo registrado para deltaTime
bool coffee_machine_enabled_ = false; // Indica si hay una máquina de café en el terreno de juego
bool hi_score_achieved_ = false; // Indica si se ha superado la puntuación máxima
float difficulty_score_multiplier_ = 1.0f; // Multiplicador de puntos en función de la dificultad
float counter_ = 0.0f; // Contador para el juego
float game_completed_timer_ = 0.0f; // Acumulador de tiempo para el tramo final (milisegundos)
float game_over_timer_ = 0.0f; // Timer para el estado de fin de partida (milisegundos)
float time_stopped_timer_ = 0.0f; // Temporizador para llevar la cuenta del tiempo detenido
float difficulty_score_multiplier_ = 1.0F; // Multiplicador de puntos en función de la dificultad
float counter_ = 0.0F; // Contador para el juego
float game_completed_timer_ = 0.0F; // Acumulador de tiempo para el tramo final (milisegundos)
float game_over_timer_ = 0.0F; // Timer para el estado de fin de partida (milisegundos)
float time_stopped_timer_ = 0.0F; // Temporizador para llevar la cuenta del tiempo detenido
int menace_ = 0; // Nivel de amenaza actual
int menace_threshold_ = 0; // Umbral del nivel de amenaza. Si el nivel de amenaza cae por debajo del umbral, se generan más globos. Si el umbral aumenta, aumenta el número de globos
State state_ = State::FADE_IN; // Estado
@@ -205,7 +204,7 @@ class Game {
#endif
// --- Ciclo principal del juego ---
void update(float deltaTime); // Actualiza la lógica principal del juego
void update(float delta_time); // Actualiza la lógica principal del juego
auto calculateDeltaTime() -> float; // Calcula el deltatime
void render(); // Renderiza todos los elementos del juego
void handleEvents(); // Procesa los eventos del sistema en cola
@@ -214,17 +213,17 @@ class Game {
void cleanVectors(); // Limpia vectores de elementos deshabilitados
// --- Gestión de estados del juego ---
void updateGameStates(float deltaTime); // Actualiza todos los estados del juego
void updateGameStateFadeIn(float deltaTime); // Gestiona el estado de transición de entrada (time-based)
void updateGameStateEnteringPlayer(float deltaTime); // Gestiona el estado de entrada de jugador
void updateGameStateShowingGetReadyMessage(float deltaTime); // Gestiona el estado de mensaje "preparado"
void updateGameStatePlaying(float deltaTime); // Gestiona el estado de juego activo
void updateGameStateCompleted(float deltaTime); // Gestiona el estado de juego completado
void updateGameStateGameOver(float deltaTime); // Gestiona las actualizaciones continuas del estado de fin de partida
void updateGameStates(float delta_time); // Actualiza todos los estados del juego
void updateGameStateFadeIn(float delta_time); // Gestiona el estado de transición de entrada (time-based)
void updateGameStateEnteringPlayer(float delta_time); // Gestiona el estado de entrada de jugador
void updateGameStateShowingGetReadyMessage(float delta_time); // Gestiona el estado de mensaje "preparado"
void updateGameStatePlaying(float delta_time); // Gestiona el estado de juego activo
void updateGameStateCompleted(float delta_time); // Gestiona el estado de juego completado
void updateGameStateGameOver(float delta_time); // Gestiona las actualizaciones continuas del estado de fin de partida
// --- Gestión de jugadores ---
void initPlayers(Player::Id player_id); // Inicializa los datos de los jugadores
void updatePlayers(float deltaTime); // Actualiza las variables y estados de los jugadores
void updatePlayers(float delta_time); // Actualiza las variables y estados de los jugadores
void renderPlayers(); // Renderiza todos los jugadores en pantalla
void sortPlayersByZOrder(); // Reorganiza el orden de dibujado de jugadores
auto getPlayer(Player::Id id) -> std::shared_ptr<Player>; // Obtiene un jugador por su identificador
@@ -269,7 +268,7 @@ class Game {
void processBalloonHit(const std::shared_ptr<Bullet>& bullet, const std::shared_ptr<Balloon>& balloon); // Procesa impacto en globo
// --- Sistema de ítems y power-ups ---
void updateItems(float deltaTime); // Actualiza posición y estado de todos los ítems
void updateItems(float delta_time); // Actualiza posición y estado de todos los ítems
void renderItems(); // Renderiza todos los ítems activos
auto dropItem() -> ItemType; // Determina aleatoriamente qué ítem soltar
void createItem(ItemType type, float x, float y); // Crea un nuevo ítem en posición específica
@@ -277,35 +276,35 @@ class Game {
void destroyAllItems(); // Elimina todos los ítems activos de la pantalla
// --- ítems especiales ---
void enableTimeStopItem(); // Activa el efecto de detener el tiempo
void disableTimeStopItem(); // Desactiva el efecto de detener el tiempo
void updateTimeStopped(float deltaTime); // Actualiza el estado del tiempo detenido
void handleGameCompletedEvents(); // Maneja eventos del juego completado
void handleGameOverEvents(); // Maneja eventos discretos basados en tiempo durante game over
void throwCoffee(int x, int y); // Crea efecto de café arrojado al ser golpeado
void enableTimeStopItem(); // Activa el efecto de detener el tiempo
void disableTimeStopItem(); // Desactiva el efecto de detener el tiempo
void updateTimeStopped(float delta_time); // Actualiza el estado del tiempo detenido
void handleGameCompletedEvents(); // Maneja eventos del juego completado
void handleGameOverEvents(); // Maneja eventos discretos basados en tiempo durante game over
void throwCoffee(int x, int y); // Crea efecto de café arrojado al ser golpeado
// --- Gestión de caída de ítems ---
void handleItemDrop(const std::shared_ptr<Balloon>& balloon, const std::shared_ptr<Player>& player); // Gestiona caída de ítem desde globo
// --- Sprites inteligentes (smartsprites) ---
void updateSmartSprites(float deltaTime); // Actualiza todos los sprites con lógica propia (time-based)
void renderSmartSprites(); // Renderiza todos los sprites inteligentes
void freeSmartSprites(); // Libera memoria de sprites inteligentes
void updateSmartSprites(float delta_time); // Actualiza todos los sprites con lógica propia (time-based)
void renderSmartSprites(); // Renderiza todos los sprites inteligentes
void freeSmartSprites(); // Libera memoria de sprites inteligentes
// --- Sprites por ruta (pathsprites) ---
void updatePathSprites(float deltaTime); // Actualiza sprites que siguen rutas predefinidas
void renderPathSprites(); // Renderiza sprites animados por ruta
void freePathSprites(); // Libera memoria de sprites por ruta
void initPaths(); // Inicializa rutas predefinidas para animaciones
void updatePathSprites(float delta_time); // Actualiza sprites que siguen rutas predefinidas
void renderPathSprites(); // Renderiza sprites animados por ruta
void freePathSprites(); // Libera memoria de sprites por ruta
void initPaths(); // Inicializa rutas predefinidas para animaciones
// --- Creación de sprites especiales ---
void createItemText(int x, const std::shared_ptr<Texture>& texture); // Crea texto animado para ítems
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
@@ -316,20 +315,20 @@ class Game {
void setMenace(); // Calcula y establece amenaza según globos activos
// --- Puntuación y marcador ---
void updateHiScore(); // Actualiza el récord máximo si es necesario
void updateScoreboard(float deltaTime); // Actualiza la visualización del marcador
void updateHiScoreName(); // Pone en el marcador el nombre del primer jugador de la tabla
void initScoreboard(); // Inicializa el sistema de puntuación
void updateHiScore(); // Actualiza el récord máximo si es necesario
void updateScoreboard(float delta_time); // Actualiza la visualización del marcador
void updateHiScoreName(); // Pone en el marcador el nombre del primer jugador de la tabla
void initScoreboard(); // Inicializa el sistema de puntuación
// --- Modo demostración ---
void initDemo(Player::Id player_id); // Inicializa variables para el modo demostración
void updateDemo(float deltaTime); // Actualiza lógica específica del modo demo
void updateDemo(float delta_time); // Actualiza lógica específica del modo demo
// --- Recursos y renderizado ---
void setResources(); // Asigna texturas y animaciones a los objetos
void updateBackground(float deltaTime); // Actualiza elementos del fondo (time-based)
void fillCanvas(); // Renderiza elementos del área de juego en su textura
void updateHelper(); // Actualiza variables auxiliares de renderizado
void setResources(); // Asigna texturas y animaciones a los objetos
void updateBackground(float delta_time); // Actualiza elementos del fondo (time-based)
void fillCanvas(); // Renderiza elementos del área de juego en su textura
void updateHelper(); // Actualiza variables auxiliares de renderizado
// --- Sistema de audio ---
static void playMusic(const std::string& music_file, int loop = -1); // Reproduce la música de fondo

View File

@@ -33,7 +33,7 @@ HiScoreTable::HiScoreTable()
backbuffer_(SDL_CreateTexture(renderer_, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, param.game.width, param.game.height)),
fade_(std::make_unique<Fade>()),
background_(std::make_unique<Background>()),
last_time_(0),
view_area_(SDL_FRect{0, 0, param.game.width, param.game.height}),
fade_mode_(Fade::Mode::IN),
background_fade_color_(Color(0, 0, 0)) {
@@ -75,7 +75,7 @@ void HiScoreTable::render() {
SCREEN->clean(); // Limpia la pantalla
background_->render(); // Pinta el fondo
float counter_equivalent = elapsed_time_ * 60.0f; // Convertir tiempo a equivalente frame para UI
float counter_equivalent = elapsed_time_ * 60.0F; // Convertir tiempo a equivalente frame para UI
view_area_.y = std::max(0.0F, param.game.height - counter_equivalent + 100); // Establece la ventana del backbuffer
SDL_RenderTexture(renderer_, backbuffer_, nullptr, &view_area_); // Copia el backbuffer al renderizador
fade_->render(); // Renderiza el fade
@@ -118,11 +118,11 @@ void HiScoreTable::checkInput() {
}
// Calcula el tiempo transcurrido desde el último frame
float HiScoreTable::calculateDeltaTime() {
const Uint64 current_time = SDL_GetTicks();
const float delta_time = static_cast<float>(current_time - last_time_) / 1000.0f; // Convertir ms a segundos
last_time_ = current_time;
return delta_time;
auto HiScoreTable::calculateDeltaTime() -> float {
const Uint64 CURRENT_TIME = SDL_GetTicks();
const float DELTA_TIME = static_cast<float>(CURRENT_TIME - last_time_) / 1000.0F; // Convertir ms a segundos
last_time_ = CURRENT_TIME;
return DELTA_TIME;
}
// Bucle para la pantalla de instrucciones
@@ -131,10 +131,10 @@ void HiScoreTable::run() {
Audio::get()->playMusic("title.ogg");
while (Section::name == Section::Name::HI_SCORE_TABLE) {
const float delta_time = calculateDeltaTime();
const float DELTA_TIME = calculateDeltaTime();
checkInput();
update(delta_time);
update(DELTA_TIME);
checkEvents(); // Tiene que ir antes del render
render();
}
@@ -262,12 +262,12 @@ void HiScoreTable::createSprites() {
// Actualiza las posiciones de los sprites de texto
void HiScoreTable::updateSprites(float delta_time) {
if (elapsed_time_ >= INIT_DELAY_S) {
const float elapsed_since_init = elapsed_time_ - INIT_DELAY_S;
int index = static_cast<int>(elapsed_since_init / ENTRY_DELAY_S);
const float ELAPSED_SINCE_INIT = elapsed_time_ - INIT_DELAY_S;
int index = static_cast<int>(ELAPSED_SINCE_INIT / ENTRY_DELAY_S);
if (index < static_cast<int>(entry_names_.size()) && index >= 0) {
// Verificar si este índice debe activarse ahora
float expected_time = index * ENTRY_DELAY_S;
if (elapsed_since_init >= expected_time && elapsed_since_init < expected_time + delta_time) {
if (ELAPSED_SINCE_INIT >= expected_time && ELAPSED_SINCE_INIT < expected_time + delta_time) {
entry_names_.at(index)->enable();
}
}
@@ -357,7 +357,7 @@ void HiScoreTable::iniEntryColors() {
// Hace brillar los nombres de la tabla de records
void HiScoreTable::glowEntryNames() {
int color_counter = static_cast<int>(elapsed_time_ * 60.0f / 5.0f); // Convertir tiempo a equivalente frame
int color_counter = static_cast<int>(elapsed_time_ * 60.0F / 5.0F); // Convertir tiempo a equivalente frame
const Color ENTRY_COLOR = getEntryColor(color_counter);
for (const auto& entry_index : Options::settings.glowing_entries) {
if (entry_index != -1) {

View File

@@ -1,17 +1,18 @@
#pragma once
#include <SDL3/SDL.h> // Para Uint16, SDL_FRect, SDL_Renderer, SDL_Texture, Uint64, Uint8
#include <SDL3/SDL.h> // Para SDL_FRect, SDL_Renderer, SDL_Texture, Uint64
#include <memory> // Para unique_ptr, shared_ptr
#include <string> // Para string
#include <vector> // Para vector
#include "color.hpp" // Para Color
#include "fade.hpp" // Para Fade
#include "path_sprite.hpp" // Para Path, PathSprite (ptr only)
#include "color.hpp" // for Color
#include "fade.hpp" // for Fade
class Background;
class PathSprite;
class Sprite;
struct Path;
// --- Clase HiScoreTable: muestra la tabla de puntuaciones más altas ---
// Esta clase gestiona un estado del programa. Se encarga de mostrar la tabla con las puntuaciones
@@ -31,12 +32,12 @@ class HiScoreTable {
private:
// --- Constantes (en segundos) ---
static constexpr float COUNTER_END_S = 800.0f / 60.0f; // Tiempo final (≈13.33s)
static constexpr float INIT_DELAY_S = 190.0f / 60.0f; // Retraso inicial (≈3.17s)
static constexpr float ENTRY_DELAY_S = 16.0f / 60.0f; // Retraso entre entradas (≈0.27s)
static constexpr float BACKGROUND_CHANGE_S = 150.0f / 60.0f; // Tiempo cambio fondo (≈2.5s)
static constexpr float ANIM_DURATION_S = 80.0f / 60.0f; // Duración animación (≈1.33s)
static constexpr float CLOUDS_SPEED = -6.0f; // Velocidad nubes (pixels/s)
static constexpr float COUNTER_END_S = 800.0F / 60.0F; // Tiempo final (≈13.33s)
static constexpr float INIT_DELAY_S = 190.0F / 60.0F; // Retraso inicial (≈3.17s)
static constexpr float ENTRY_DELAY_S = 16.0F / 60.0F; // Retraso entre entradas (≈0.27s)
static constexpr float BACKGROUND_CHANGE_S = 150.0F / 60.0F; // Tiempo cambio fondo (≈2.5s)
static constexpr float ANIM_DURATION_S = 80.0F / 60.0F; // Duración animación (≈1.33s)
static constexpr float CLOUDS_SPEED = -6.0F; // Velocidad nubes (pixels/s)
// --- Objetos y punteros ---
SDL_Renderer* renderer_; // El renderizador de la ventana
@@ -49,7 +50,7 @@ class HiScoreTable {
std::vector<Path> paths_; // Vector con los recorridos precalculados
// --- Variables ---
float elapsed_time_ = 0.0f; // Tiempo transcurrido (segundos)
float elapsed_time_ = 0.0F; // Tiempo transcurrido (segundos)
Uint64 last_time_ = 0; // Último timestamp para calcular delta-time
SDL_FRect view_area_; // Parte de la textura que se muestra en pantalla
Fade::Mode fade_mode_; // Modo de fade a utilizar
@@ -83,5 +84,5 @@ class HiScoreTable {
void iniEntryColors(); // Inicializa los colores de las entradas
void glowEntryNames(); // Hace brillar los nombres de la tabla de records
void updateCounter(); // Gestiona el contador
float calculateDeltaTime(); // Calcula el tiempo transcurrido desde el último frame
auto calculateDeltaTime() -> float; // Calcula el tiempo transcurrido desde el último frame
};

View File

@@ -90,19 +90,19 @@ void Instructions::updateSprites() {
SDL_FRect src_rect = {0, 0, Item::WIDTH, Item::HEIGHT};
// Disquito (desplazamiento 12/60 = 0.2s)
src_rect.y = Item::HEIGHT * (static_cast<int>((elapsed_time_ + 0.2f) / SPRITE_ANIMATION_CYCLE_S) % 2);
src_rect.y = Item::HEIGHT * (static_cast<int>((elapsed_time_ + 0.2F) / SPRITE_ANIMATION_CYCLE_S) % 2);
sprites_[0]->setSpriteClip(src_rect);
// Gavina (desplazamiento 9/60 = 0.15s)
src_rect.y = Item::HEIGHT * (static_cast<int>((elapsed_time_ + 0.15f) / SPRITE_ANIMATION_CYCLE_S) % 2);
src_rect.y = Item::HEIGHT * (static_cast<int>((elapsed_time_ + 0.15F) / SPRITE_ANIMATION_CYCLE_S) % 2);
sprites_[1]->setSpriteClip(src_rect);
// Pacmar (desplazamiento 6/60 = 0.1s)
src_rect.y = Item::HEIGHT * (static_cast<int>((elapsed_time_ + 0.1f) / SPRITE_ANIMATION_CYCLE_S) % 2);
src_rect.y = Item::HEIGHT * (static_cast<int>((elapsed_time_ + 0.1F) / SPRITE_ANIMATION_CYCLE_S) % 2);
sprites_[2]->setSpriteClip(src_rect);
// Time Stopper (desplazamiento 3/60 = 0.05s)
src_rect.y = Item::HEIGHT * (static_cast<int>((elapsed_time_ + 0.05f) / SPRITE_ANIMATION_CYCLE_S) % 2);
src_rect.y = Item::HEIGHT * (static_cast<int>((elapsed_time_ + 0.05F) / SPRITE_ANIMATION_CYCLE_S) % 2);
sprites_[3]->setSpriteClip(src_rect);
// Coffee (sin desplazamiento)
@@ -255,11 +255,11 @@ void Instructions::checkInput() {
}
// Calcula el tiempo transcurrido desde el último frame
float Instructions::calculateDeltaTime() {
const Uint64 current_time = SDL_GetTicks();
const float delta_time = static_cast<float>(current_time - last_time_) / 1000.0f; // Convertir ms a segundos
last_time_ = current_time;
return delta_time;
auto Instructions::calculateDeltaTime() -> float {
const Uint64 CURRENT_TIME = SDL_GetTicks();
const float DELTA_TIME = static_cast<float>(CURRENT_TIME - last_time_) / 1000.0F; // Convertir ms a segundos
last_time_ = CURRENT_TIME;
return DELTA_TIME;
}
// Bucle para la pantalla de instrucciones
@@ -268,10 +268,10 @@ void Instructions::run() {
Audio::get()->playMusic("title.ogg");
while (Section::name == Section::Name::INSTRUCTIONS) {
const float delta_time = calculateDeltaTime();
const float DELTA_TIME = calculateDeltaTime();
checkInput();
update(delta_time);
update(DELTA_TIME);
checkEvents(); // Tiene que ir antes del render
render();
}
@@ -328,7 +328,7 @@ void Instructions::renderLines(SDL_Renderer* renderer, SDL_Texture* texture, con
// Gestiona la textura con los graficos
void Instructions::updateBackbuffer(float delta_time) {
// Establece la ventana del backbuffer (convertir elapsed_time_ a equivalente de counter)
float counter_equivalent = elapsed_time_ * 60.0f; // Convertir segundos a equivalente frame para UI
float counter_equivalent = elapsed_time_ * 60.0F; // Convertir segundos a equivalente frame para UI
view_.y = std::max(0.0F, param.game.height - counter_equivalent + 100);
// Verifica si view_.y == 0 y gestiona el temporizador
@@ -336,7 +336,7 @@ void Instructions::updateBackbuffer(float delta_time) {
if (!start_delay_triggered_) {
// Activa el temporizador si no ha sido activado
start_delay_triggered_ = true;
start_delay_timer_ = 0.0f;
start_delay_timer_ = 0.0F;
} else {
start_delay_timer_ += delta_time;
if (start_delay_timer_ >= START_DELAY_S) {

View File

@@ -1,13 +1,12 @@
#pragma once
#include <SDL3/SDL.h> // Para SDL_Texture, Uint32, SDL_Renderer, SDL_FPoint, SDL_FRect, Uint64
#include <SDL3/SDL.h> // Para SDL_Texture, SDL_Renderer, Uint32, SDL_FPoint, SDL_FRect, Uint64
#include <memory> // Para unique_ptr, shared_ptr
#include <vector> // Para vector
#include "sprite.hpp" // Para Sprite
class Fade;
class Sprite;
class Text;
class Texture;
class TiledBG;
@@ -51,10 +50,10 @@ class Instructions {
private:
// --- Constantes de tiempo (en segundos) ---
static constexpr float SPRITE_ANIMATION_CYCLE_S = 36.0f / 60.0f; // Ciclo de animación sprites (≈0.6s)
static constexpr float START_DELAY_S = 4.0f; // Retraso antes de mover líneas (4s)
static constexpr float LINE_MOVE_DURATION_S = 1.0f; // Duración movimiento líneas (1s)
static constexpr float LINE_START_DELAY_MS = 5.0f; // Retraso entre líneas (5ms)
static constexpr float SPRITE_ANIMATION_CYCLE_S = 36.0F / 60.0F; // Ciclo de animación sprites (≈0.6s)
static constexpr float START_DELAY_S = 4.0F; // Retraso antes de mover líneas (4s)
static constexpr float LINE_MOVE_DURATION_S = 1.0F; // Duración movimiento líneas (1s)
static constexpr float LINE_START_DELAY_MS = 5.0F; // Retraso entre líneas (5ms)
// --- Objetos y punteros ---
SDL_Renderer* renderer_; // El renderizador de la ventana
@@ -68,14 +67,14 @@ class Instructions {
std::unique_ptr<Fade> fade_; // Objeto para renderizar fades
// --- Variables ---
float elapsed_time_ = 0.0f; // Tiempo transcurrido (segundos)
float elapsed_time_ = 0.0F; // Tiempo transcurrido (segundos)
Uint64 last_time_ = 0; // Último timestamp para calcular delta-time
SDL_FRect view_; // Vista del backbuffer que se va a mostrar por pantalla
SDL_FPoint sprite_pos_ = {0, 0}; // Posición del primer sprite en la lista
float item_space_ = 2.0; // Espacio entre los items en pantalla
std::vector<Line> lines_; // Vector que contiene las líneas animadas en la pantalla
bool all_lines_off_screen_ = false; // Indica si todas las líneas han salido de la pantalla
float start_delay_timer_ = 0.0f; // Timer para retraso antes de mover líneas (segundos)
float start_delay_timer_ = 0.0F; // Timer para retraso antes de mover líneas (segundos)
bool start_delay_triggered_ = false; // Bandera para determinar si el retraso ha comenzado
// --- Métodos internos ---
@@ -91,5 +90,5 @@ class Instructions {
static auto moveLines(std::vector<Line>& lines, int width, float duration, Uint32 start_delay) -> bool; // Mueve las líneas (ya usa tiempo real)
static void renderLines(SDL_Renderer* renderer, SDL_Texture* texture, const std::vector<Line>& lines); // Renderiza las líneas
void updateBackbuffer(float delta_time); // Gestiona la textura con los gráficos
float calculateDeltaTime(); // Calcula el tiempo transcurrido desde el último frame
auto calculateDeltaTime() -> float; // Calcula el tiempo transcurrido desde el último frame
};

View File

@@ -1,8 +1,7 @@
#include "intro.hpp"
#include <SDL3/SDL.h> // Para SDL_GetTicks, SDL_SetRenderDrawColor, SDL_FRect, SDL_RenderFillRect, SDL_GetRenderTarget, SDL_RenderClear, SDL_RenderRect, SDL_SetRenderTarget, SDL_BLENDMODE_BLEND, SDL_PixelFormat, SDL_PollEvent, SDL_RenderTexture, SDL_TextureAccess, SDL_Event, Uint32
#include <SDL3/SDL.h> // Para SDL_GetTicks, SDL_SetRenderDrawColor, SDL_FRect, SDL_RenderFillRect, SDL_GetRenderTarget, SDL_RenderClear, SDL_RenderRect, SDL_SetRenderTarget, SDL_BLENDMODE_BLEND, SDL_PixelFormat, SDL_PollEvent, SDL_RenderTexture, SDL_TextureAccess, SDL_Event, Uint64
#include <algorithm> // Para max
#include <array> // Para array
#include <functional> // Para function
#include <string> // Para basic_string, string
@@ -10,7 +9,7 @@
#include "audio.hpp" // Para Audio
#include "color.hpp" // Para Color
#include "global_events.hpp" // Para check
#include "global_events.hpp" // Para handle
#include "global_inputs.hpp" // Para check
#include "input.hpp" // Para Input
#include "lang.hpp" // Para getText
@@ -191,7 +190,7 @@ void Intro::updateScene5() {
// Acaba la ultima imagen
if (card_sprites_.at(5)->hasFinished() && texts_.at(8)->hasFinished()) {
state_ = State::POST;
state_start_time_ = SDL_GetTicks() / 1000.0f;
state_start_time_ = SDL_GetTicks() / 1000.0F;
}
}
@@ -251,11 +250,11 @@ void Intro::render() {
}
// Calcula el tiempo transcurrido desde el último frame
float Intro::calculateDeltaTime() {
const Uint64 current_time = SDL_GetTicks();
const float delta_time = static_cast<float>(current_time - last_time_) / 1000.0f; // Convertir ms a segundos
last_time_ = current_time;
return delta_time;
auto Intro::calculateDeltaTime() -> float {
const Uint64 CURRENT_TIME = SDL_GetTicks();
const float DELTA_TIME = static_cast<float>(CURRENT_TIME - last_time_) / 1000.0F; // Convertir ms a segundos
last_time_ = CURRENT_TIME;
return DELTA_TIME;
}
// Bucle principal
@@ -264,10 +263,10 @@ void Intro::run() {
Audio::get()->playMusic("intro.ogg", 0);
while (Section::name == Section::Name::INTRO) {
const float delta_time = calculateDeltaTime();
const float DELTA_TIME = calculateDeltaTime();
checkInput();
update(delta_time);
update(DELTA_TIME);
checkEvents(); // Tiene que ir antes del render
render();
}
@@ -338,13 +337,13 @@ void Intro::initSprites() {
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 - CARD_OFFSET_MARGIN, X_DEST, PathType::HORIZONTAL, Y_DEST, CARD_ANIM_DURATION_NORMAL, easeInOutExpo, 0.0f);
card_sprites_.at(1)->addPath(param.game.width, X_DEST, PathType::HORIZONTAL, Y_DEST, CARD_ANIM_DURATION_NORMAL, easeOutBounce, 0.0f);
card_sprites_.at(2)->addPath(-CARD_HEIGHT, Y_DEST, PathType::VERTICAL, X_DEST, CARD_ANIM_DURATION_FAST, easeOutQuint, 0.0f);
card_sprites_.at(3)->addPath(param.game.height, Y_DEST, PathType::VERTICAL, X_DEST, CARD_ANIM_DURATION_VERY_SLOW, easeInOutExpo, 0.0f);
card_sprites_.at(4)->addPath(-CARD_HEIGHT, Y_DEST, PathType::VERTICAL, X_DEST, CARD_ANIM_DURATION_MEDIUM, easeOutElastic, 0.0f);
card_sprites_.at(0)->addPath(-CARD_WIDTH - CARD_OFFSET_MARGIN, X_DEST, PathType::HORIZONTAL, Y_DEST, CARD_ANIM_DURATION_NORMAL, easeInOutExpo, 0.0F);
card_sprites_.at(1)->addPath(param.game.width, X_DEST, PathType::HORIZONTAL, Y_DEST, CARD_ANIM_DURATION_NORMAL, easeOutBounce, 0.0F);
card_sprites_.at(2)->addPath(-CARD_HEIGHT, Y_DEST, PathType::VERTICAL, X_DEST, CARD_ANIM_DURATION_FAST, easeOutQuint, 0.0F);
card_sprites_.at(3)->addPath(param.game.height, Y_DEST, PathType::VERTICAL, X_DEST, CARD_ANIM_DURATION_VERY_SLOW, easeInOutExpo, 0.0F);
card_sprites_.at(4)->addPath(-CARD_HEIGHT, Y_DEST, PathType::VERTICAL, X_DEST, CARD_ANIM_DURATION_MEDIUM, easeOutElastic, 0.0F);
card_sprites_.at(5)->addPath(-CARD_HEIGHT, Y_DEST, PathType::VERTICAL, X_DEST, CARD_ANIM_DURATION_SLOW, easeOutQuad, CARD_ANIM_DELAY_LONG_S);
card_sprites_.at(5)->addPath(X_DEST, -CARD_WIDTH, PathType::HORIZONTAL, Y_DEST, CARD_ANIM_DURATION_SHORT, easeInElastic, 0.0f);
card_sprites_.at(5)->addPath(X_DEST, -CARD_WIDTH, PathType::HORIZONTAL, Y_DEST, CARD_ANIM_DURATION_SHORT, easeInElastic, 0.0F);
// Constantes
const float DESP = SHADOW_OFFSET;
@@ -389,13 +388,13 @@ void Intro::initSprites() {
const float S_X_DEST = X_DEST + DESP;
const float S_Y_DEST = Y_DEST + DESP;
shadow_sprites_.at(0)->addPath(param.game.height + CARD_OFFSET_MARGIN, S_Y_DEST, PathType::VERTICAL, S_X_DEST, CARD_ANIM_DURATION_NORMAL, easeInOutExpo, 0.0f);
shadow_sprites_.at(1)->addPath(-SHADOW_SPRITE_HEIGHT, S_Y_DEST, PathType::VERTICAL, S_X_DEST, CARD_ANIM_DURATION_NORMAL, easeOutBounce, 0.0f);
shadow_sprites_.at(2)->addPath(-SHADOW_SPRITE_WIDTH, S_X_DEST, PathType::HORIZONTAL, S_Y_DEST, CARD_ANIM_DURATION_FAST, easeOutQuint, 0.0f);
shadow_sprites_.at(3)->addPath(-SHADOW_SPRITE_HEIGHT, S_Y_DEST, PathType::VERTICAL, S_X_DEST, CARD_ANIM_DURATION_VERY_SLOW, easeInOutExpo, 0.0f);
shadow_sprites_.at(4)->addPath(param.game.height, S_Y_DEST, PathType::VERTICAL, S_X_DEST, CARD_ANIM_DURATION_MEDIUM, easeOutElastic, 0.0f);
shadow_sprites_.at(0)->addPath(param.game.height + CARD_OFFSET_MARGIN, S_Y_DEST, PathType::VERTICAL, S_X_DEST, CARD_ANIM_DURATION_NORMAL, easeInOutExpo, 0.0F);
shadow_sprites_.at(1)->addPath(-SHADOW_SPRITE_HEIGHT, S_Y_DEST, PathType::VERTICAL, S_X_DEST, CARD_ANIM_DURATION_NORMAL, easeOutBounce, 0.0F);
shadow_sprites_.at(2)->addPath(-SHADOW_SPRITE_WIDTH, S_X_DEST, PathType::HORIZONTAL, S_Y_DEST, CARD_ANIM_DURATION_FAST, easeOutQuint, 0.0F);
shadow_sprites_.at(3)->addPath(-SHADOW_SPRITE_HEIGHT, S_Y_DEST, PathType::VERTICAL, S_X_DEST, CARD_ANIM_DURATION_VERY_SLOW, easeInOutExpo, 0.0F);
shadow_sprites_.at(4)->addPath(param.game.height, S_Y_DEST, PathType::VERTICAL, S_X_DEST, CARD_ANIM_DURATION_MEDIUM, easeOutElastic, 0.0F);
shadow_sprites_.at(5)->addPath(param.game.width, S_X_DEST, PathType::HORIZONTAL, S_Y_DEST, CARD_ANIM_DURATION_SLOW, easeOutQuad, CARD_ANIM_DELAY_LONG_S);
shadow_sprites_.at(5)->addPath(S_X_DEST, param.game.width, PathType::HORIZONTAL, S_Y_DEST, CARD_ANIM_DURATION_SHORT, easeInElastic, 0.0f);
shadow_sprites_.at(5)->addPath(S_X_DEST, param.game.width, PathType::HORIZONTAL, S_Y_DEST, CARD_ANIM_DURATION_SHORT, easeInElastic, 0.0F);
}
// Inicializa los textos
@@ -485,7 +484,7 @@ void Intro::renderTexts() {
// Actualiza el estado POST
void Intro::updatePostState() {
const float ELAPSED_TIME = (SDL_GetTicks() / 1000.0f) - state_start_time_;
const float ELAPSED_TIME = (SDL_GetTicks() / 1000.0F) - state_start_time_;
switch (post_state_) {
case PostState::STOP_BG:
@@ -503,7 +502,7 @@ void Intro::updatePostState() {
// Cambia de estado si el fondo se ha detenido y recuperado el color
if (tiled_bg_->isStopped() && bg_color_.IS_EQUAL_TO(param.title.bg_color)) {
post_state_ = PostState::END;
state_start_time_ = SDL_GetTicks() / 1000.0f;
state_start_time_ = SDL_GetTicks() / 1000.0F;
}
break;

View File

@@ -38,32 +38,32 @@ class Intro {
private:
// --- Constantes de tiempo (en segundos) ---
static constexpr float TEXT_DISPLAY_DURATION_S = 3.0f; // Duración de visualización de texto (180 frames a 60fps)
static constexpr float POST_BG_STOP_DELAY_S = 1.0f; // Retraso antes de detener el fondo
static constexpr float POST_END_DELAY_S = 1.0f; // Retraso antes de finalizar intro
static constexpr float TEXT_DISPLAY_DURATION_S = 3.0F; // Duración de visualización de texto (180 frames a 60fps)
static constexpr float POST_BG_STOP_DELAY_S = 1.0F; // Retraso antes de detener el fondo
static constexpr float POST_END_DELAY_S = 1.0F; // Retraso antes de finalizar intro
// --- Constantes de layout ---
static constexpr float CARD_BORDER_SIZE = 2.0f; // Tamaño del borde de tarjetas
static constexpr float SHADOW_OFFSET = 8.0f; // Desplazamiento de sombra
static constexpr float TILED_BG_SPEED = 18.0f; // Velocidad del fondo mosaico (pixels/segundo)
static constexpr float CARD_BORDER_SIZE = 2.0F; // Tamaño del borde de tarjetas
static constexpr float SHADOW_OFFSET = 8.0F; // Desplazamiento de sombra
static constexpr float TILED_BG_SPEED = 18.0F; // Velocidad del fondo mosaico (pixels/segundo)
static constexpr int TEXT_KERNING = -2; // Espaciado entre caracteres
// --- Constantes de velocidades de texto (segundos entre caracteres) ---
static constexpr float TEXT_SPEED_NORMAL = 0.133f; // Velocidad normal (8 frames * 16.67ms = 133ms)
static constexpr float TEXT_SPEED_FAST = 0.2f; // Velocidad rápida (12 frames * 16.67ms = 200ms)
static constexpr float TEXT_SPEED_VERY_SLOW = 0.0167f; // Velocidad muy lenta (1 frame * 16.67ms = 16.7ms)
static constexpr float TEXT_SPEED_VERY_FAST = 0.267f; // Velocidad muy rápida (16 frames * 16.67ms = 267ms)
static constexpr float TEXT_SPEED_SLOW = 0.033f; // Velocidad lenta (2 frames * 16.67ms = 33ms)
static constexpr float TEXT_SPEED_MEDIUM_SLOW = 0.05f; // Velocidad medio-lenta (3 frames * 16.67ms = 50ms)
static constexpr float TEXT_SPEED_ULTRA_FAST = 0.333f; // Velocidad ultra rápida (20 frames * 16.67ms = 333ms)
static constexpr float TEXT_SPEED_NORMAL = 0.133F; // Velocidad normal (8 frames * 16.67ms = 133ms)
static constexpr float TEXT_SPEED_FAST = 0.2F; // Velocidad rápida (12 frames * 16.67ms = 200ms)
static constexpr float TEXT_SPEED_VERY_SLOW = 0.0167F; // Velocidad muy lenta (1 frame * 16.67ms = 16.7ms)
static constexpr float TEXT_SPEED_VERY_FAST = 0.267F; // Velocidad muy rápida (16 frames * 16.67ms = 267ms)
static constexpr float TEXT_SPEED_SLOW = 0.033F; // Velocidad lenta (2 frames * 16.67ms = 33ms)
static constexpr float TEXT_SPEED_MEDIUM_SLOW = 0.05F; // Velocidad medio-lenta (3 frames * 16.67ms = 50ms)
static constexpr float TEXT_SPEED_ULTRA_FAST = 0.333F; // Velocidad ultra rápida (20 frames * 16.67ms = 333ms)
// --- Constantes de animaciones de tarjetas (duraciones en segundos) ---
static constexpr float CARD_ANIM_DURATION_NORMAL = 100.0f / 60.0f; // ≈ 1.6667 s
static constexpr float CARD_ANIM_DURATION_FAST = 40.0f / 60.0f; // ≈ 0.6667 s
static constexpr float CARD_ANIM_DURATION_MEDIUM = 70.0f / 60.0f; // ≈ 1.1667 s
static constexpr float CARD_ANIM_DURATION_SHORT = 80.0f / 60.0f; // ≈ 1.3333 s
static constexpr float CARD_ANIM_DURATION_SLOW = 250.0f / 60.0f; // ≈ 4.1667 s
static constexpr float CARD_ANIM_DURATION_VERY_SLOW = 300.0f / 60.0f; // ≈ 5.0000 s
static constexpr float CARD_ANIM_DURATION_NORMAL = 100.0F / 60.0F; // ≈ 1.6667 s
static constexpr float CARD_ANIM_DURATION_FAST = 40.0F / 60.0F; // ≈ 0.6667 s
static constexpr float CARD_ANIM_DURATION_MEDIUM = 70.0F / 60.0F; // ≈ 1.1667 s
static constexpr float CARD_ANIM_DURATION_SHORT = 80.0F / 60.0F; // ≈ 1.3333 s
static constexpr float CARD_ANIM_DURATION_SLOW = 250.0F / 60.0F; // ≈ 4.1667 s
static constexpr float CARD_ANIM_DURATION_VERY_SLOW = 300.0F / 60.0F; // ≈ 5.0000 s
static constexpr float CARD_ANIM_DELAY_LONG_S = 7.5F; // Retraso largo antes de animación
static constexpr float CARD_OFFSET_MARGIN = 10.0F; // Margen fuera de pantalla
@@ -107,7 +107,7 @@ class Intro {
void renderTexts(); // Dibuja los textos
static void renderTextRect(); // Dibuja el rectangulo de fondo del texto;
void updatePostState(); // Actualiza el estado POST
float calculateDeltaTime(); // Calcula el tiempo transcurrido desde el último frame
auto calculateDeltaTime() -> float; // Calcula el tiempo transcurrido desde el último frame
// --- Métodos para manejar cada escena individualmente ---
void updateScene0();

View File

@@ -1,12 +1,14 @@
#include "logo.hpp"
#include <SDL3/SDL.h> // Para SDL_GetTicks, SDL_PollEvent, SDL_Event, SDL_FRect
#include <SDL3/SDL.h> // Para SDL_GetTicks, SDL_PollEvent, SDL_Event, SDL_FRect, Uint64
#include <cstddef> // Para size_t
#include <string> // Para basic_string
#include <utility> // Para move
#include "audio.hpp" // Para Audio
#include "color.hpp" // Para Color
#include "global_events.hpp" // Para check
#include "global_events.hpp" // Para handle
#include "global_inputs.hpp" // Para check
#include "input.hpp" // Para Input
#include "param.hpp" // Para Param, ParamGame, param
@@ -118,16 +120,16 @@ void Logo::updateJAILGAMES(float delta_time) {
void Logo::updateTextureColors(float delta_time) {
// Manejo de 'sinceTexture'
for (int i = 0; i <= MAX_SINCE_COLOR_INDEX; ++i) {
const float target_time = SHOW_SINCE_SPRITE_TIME_S + COLOR_CHANGE_INTERVAL_S * i;
if (elapsed_time_s_ >= target_time && elapsed_time_s_ - delta_time < target_time) {
const float TARGET_TIME = SHOW_SINCE_SPRITE_TIME_S + (COLOR_CHANGE_INTERVAL_S * i);
if (elapsed_time_s_ >= TARGET_TIME && elapsed_time_s_ - delta_time < TARGET_TIME) {
since_texture_->setColor(color_[i].r, color_[i].g, color_[i].b);
}
}
// Manejo de 'jailTexture' y 'sinceTexture' en el fade
for (int i = 0; i <= MAX_FADE_COLOR_INDEX; ++i) {
const float target_time = INIT_FADE_TIME_S + COLOR_CHANGE_INTERVAL_S * i;
if (elapsed_time_s_ >= target_time && elapsed_time_s_ - delta_time < target_time) {
const float TARGET_TIME = INIT_FADE_TIME_S + (COLOR_CHANGE_INTERVAL_S * i);
if (elapsed_time_s_ >= TARGET_TIME && elapsed_time_s_ - delta_time < TARGET_TIME) {
jail_texture_->setColor(color_[MAX_FADE_COLOR_INDEX - i].r, color_[MAX_FADE_COLOR_INDEX - i].g, color_[MAX_FADE_COLOR_INDEX - i].b);
since_texture_->setColor(color_[MAX_FADE_COLOR_INDEX - i].r, color_[MAX_FADE_COLOR_INDEX - i].g, color_[MAX_FADE_COLOR_INDEX - i].b);
}
@@ -160,11 +162,11 @@ void Logo::render() {
}
// Calcula el tiempo transcurrido desde el último frame
float Logo::calculateDeltaTime() {
const Uint64 current_time = SDL_GetTicks();
const float delta_time = static_cast<float>(current_time - last_time_) / 1000.0f; // Convertir ms a segundos
last_time_ = current_time;
return delta_time;
auto Logo::calculateDeltaTime() -> float {
const Uint64 CURRENT_TIME = SDL_GetTicks();
const float DELTA_TIME = static_cast<float>(CURRENT_TIME - last_time_) / 1000.0F; // Convertir ms a segundos
last_time_ = CURRENT_TIME;
return DELTA_TIME;
}
// Bucle para el logo del juego
@@ -172,10 +174,10 @@ void Logo::run() {
last_time_ = SDL_GetTicks();
while (Section::name == Section::Name::LOGO) {
const float delta_time = calculateDeltaTime();
const float DELTA_TIME = calculateDeltaTime();
checkInput();
update(delta_time);
update(DELTA_TIME);
checkEvents(); // Tiene que ir antes del render
render();
}

View File

@@ -2,12 +2,12 @@
#include <SDL3/SDL.h> // Para SDL_FPoint, Uint64
#include <memory> // Para unique_ptr, shared_ptr
#include <memory> // Para shared_ptr, unique_ptr
#include <vector> // Para vector
#include "color.hpp" // Para Color
#include "sprite.hpp" // Para Sprite
#include "color.hpp" // for Color
class Sprite;
class Texture;
// --- Clase Logo: pantalla de presentación de JAILGAMES con efectos retro ---
@@ -36,13 +36,13 @@ class Logo {
private:
// --- Constantes de tiempo (en segundos) ---
static constexpr float SOUND_TRIGGER_TIME_S = 0.5f; // Tiempo para activar el sonido del logo
static constexpr float SHOW_SINCE_SPRITE_TIME_S = 1.167f; // Tiempo para mostrar el sprite "SINCE 1998"
static constexpr float INIT_FADE_TIME_S = 5.0f; // Tiempo de inicio del fade a negro
static constexpr float END_LOGO_TIME_S = 6.668f; // Tiempo de finalización del logo
static constexpr float POST_LOGO_DURATION_S = 0.333f; // Duración adicional después del fade
static constexpr float LOGO_SPEED_PX_PER_S = 480.0f; // Velocidad de desplazamiento (píxeles por segundo) - 8.0f/16.67f*1000
static constexpr float COLOR_CHANGE_INTERVAL_S = 0.0667f; // Intervalo entre cambios de color (~4 frames a 60fps)
static constexpr float SOUND_TRIGGER_TIME_S = 0.5F; // Tiempo para activar el sonido del logo
static constexpr float SHOW_SINCE_SPRITE_TIME_S = 1.167F; // Tiempo para mostrar el sprite "SINCE 1998"
static constexpr float INIT_FADE_TIME_S = 5.0F; // Tiempo de inicio del fade a negro
static constexpr float END_LOGO_TIME_S = 6.668F; // Tiempo de finalización del logo
static constexpr float POST_LOGO_DURATION_S = 0.333F; // Duración adicional después del fade
static constexpr float LOGO_SPEED_PX_PER_S = 480.0F; // Velocidad de desplazamiento (píxeles por segundo) - 8.0f/16.67f*1000
static constexpr float COLOR_CHANGE_INTERVAL_S = 0.0667F; // Intervalo entre cambios de color (~4 frames a 60fps)
// --- Constantes de layout ---
static constexpr int SINCE_SPRITE_Y_OFFSET = 83; // Posición Y base del sprite "Since 1998"
@@ -73,7 +73,7 @@ class Logo {
// --- Variables ---
std::vector<Color> color_; // Vector con los colores para el fade
float elapsed_time_s_ = 0.0f; // Tiempo transcurrido en segundos
float elapsed_time_s_ = 0.0F; // Tiempo transcurrido en segundos
Uint64 last_time_ = 0; // Último timestamp para calcular delta-time
SDL_FPoint dest_; // Posición donde dibujar el logo
bool sound_triggered_ = false; // Indica si el sonido del logo ya se reprodujo
@@ -87,5 +87,5 @@ class Logo {
void renderJAILGAMES(); // Renderiza el logo de JAILGAMES
void updateTextureColors(float delta_time); // Gestiona el color de las texturas
void handleSound(); // Maneja la reproducción del sonido del logo
float calculateDeltaTime(); // Calcula el tiempo transcurrido desde el último frame
auto calculateDeltaTime() -> float; // Calcula el tiempo transcurrido desde el último frame
};

View File

@@ -1,16 +1,16 @@
#include "title.hpp"
#include <SDL3/SDL.h> // Para SDL_GetTicks, Uint32, SDL_Event, SDL_PollEvent, SDL_EventType
#include <SDL3/SDL.h> // Para SDL_GetTicks, SDL_Event, SDL_Keycode, SDL_PollEvent, SDLK_A, SDLK_C, SDLK_D, SDLK_F, SDLK_S, SDLK_V, SDLK_X, SDLK_Z, SDL_EventType, Uint64
#include <algorithm> // Para max, find_if
#include <string> // Para operator+, char_traits, to_string, string, basic_string
#include <vector> // Para vector
#include <ranges> // Para __find_if_fn, find_if
#include <string> // Para basic_string, char_traits, operator+, to_string, string
#include <vector> // Para vector
#include "audio.hpp" // Para Audio
#include "color.hpp" // Para Colors::NO_COLOR_MOD, Colors::TITLE_SHADOW_TEXT
#include "fade.hpp" // Para Fade, FadeType
#include "color.hpp" // Para Color, NO_COLOR_MOD, TITLE_SHADOW_TEXT
#include "fade.hpp" // Para Fade
#include "game_logo.hpp" // Para GameLogo
#include "global_events.hpp" // Para check
#include "global_events.hpp" // Para handle
#include "global_inputs.hpp" // Para check
#include "input.hpp" // Para Input
#include "input_types.hpp" // Para InputAction
@@ -31,8 +31,8 @@
class Texture;
#ifdef _DEBUG
#include <iomanip> // Para operator<<, setfill, setw
#include <iostream>
#include <iomanip> // Para operator<<, setfill, setw
#include <iostream> // Para basic_ostream, basic_ostream::operator<<, operator<<, cout, hex
#endif
// Constructor
@@ -84,23 +84,23 @@ Title::~Title() {
}
// Actualiza las variables del objeto
void Title::update(float deltaTime) {
void Title::update(float delta_time) {
static auto* const SCREEN = Screen::get();
SCREEN->update(deltaTime); // Actualiza el objeto screen
Audio::update(); // Actualiza el objeto audio
SCREEN->update(delta_time); // Actualiza el objeto screen
Audio::update(); // Actualiza el objeto audio
updateFade();
updateState(deltaTime);
updateStartPrompt(deltaTime);
updatePlayers(deltaTime);
updateState(delta_time);
updateStartPrompt(delta_time);
updatePlayers(delta_time);
}
// Calcula el tiempo transcurrido desde el último frame
float Title::calculateDeltaTime() {
const Uint64 current_time = SDL_GetTicks();
const float delta_time = static_cast<float>(current_time - last_time_) / 1000.0f; // Convert ms to seconds
last_time_ = current_time;
return delta_time;
auto Title::calculateDeltaTime() -> float {
const Uint64 CURRENT_TIME = SDL_GetTicks();
const float DELTA_TIME = static_cast<float>(CURRENT_TIME - last_time_) / 1000.0F; // Convert ms to seconds
last_time_ = CURRENT_TIME;
return DELTA_TIME;
}
// Dibuja el objeto en pantalla
@@ -145,7 +145,7 @@ void Title::handleKeyDownEvent(const SDL_Event& event) {
void Title::handleDebugColorKeys(SDL_Keycode key) {
adjustColorComponent(key, debug_color_);
counter_time_ = 0.0f;
counter_time_ = 0.0F;
tiled_bg_->setColor(debug_color_);
printColorValue(debug_color_);
}
@@ -299,7 +299,7 @@ void Title::processPlayer2Start() {
void Title::activatePlayerAndSetState(Player::Id player_id) {
getPlayer(player_id)->setPlayingState(Player::State::TITLE_ANIMATION);
setState(State::START_HAS_BEEN_PRESSED);
counter_time_ = 0.0f;
counter_time_ = 0.0F;
}
// Bucle para el titulo del juego
@@ -307,17 +307,17 @@ void Title::run() {
last_time_ = SDL_GetTicks();
while (Section::name == Section::Name::TITLE) {
const float delta_time = calculateDeltaTime();
const float DELTA_TIME = calculateDeltaTime();
checkInput();
update(delta_time);
update(DELTA_TIME);
checkEvents(); // Tiene que ir antes del render
render();
}
}
// Reinicia el contador interno
void Title::resetCounter() { counter_time_ = 0.0f; }
void Title::resetCounter() { counter_time_ = 0.0F; }
// Intercambia la asignación de mandos a los jugadores
void Title::swapControllers() {
@@ -379,9 +379,9 @@ void Title::updateFade() {
}
// Actualiza el estado
void Title::updateState(float deltaTime) {
game_logo_->update(deltaTime);
tiled_bg_->update(deltaTime);
void Title::updateState(float delta_time) {
game_logo_->update(delta_time);
tiled_bg_->update(delta_time);
// Establece la lógica según el estado
switch (state_) {
@@ -392,7 +392,7 @@ void Title::updateState(float deltaTime) {
break;
}
case State::LOGO_FINISHED: {
counter_time_ += deltaTime;
counter_time_ += delta_time;
if (counter_time_ >= param.title.title_duration) {
// El menu ha hecho time out
@@ -403,7 +403,7 @@ void Title::updateState(float deltaTime) {
break;
}
case State::START_HAS_BEEN_PRESSED: {
counter_time_ += deltaTime;
counter_time_ += delta_time;
if (counter_time_ >= START_PRESSED_DELAY_S) {
fade_->activate();
@@ -416,12 +416,12 @@ void Title::updateState(float deltaTime) {
}
}
void Title::updateStartPrompt(float deltaTime) {
blink_accumulator_ += deltaTime;
void Title::updateStartPrompt(float delta_time) {
blink_accumulator_ += delta_time;
bool condition_met = false;
float period = 0.0f;
float on_time = 0.0f;
float period = 0.0F;
float on_time = 0.0F;
switch (state_) {
case State::LOGO_FINISHED:
@@ -438,7 +438,7 @@ void Title::updateStartPrompt(float deltaTime) {
break;
}
if (period > 0.0f) {
if (period > 0.0F) {
// Reset accumulator when it exceeds the period
if (blink_accumulator_ >= period) {
blink_accumulator_ -= period;
@@ -494,11 +494,11 @@ void Title::setState(State state) {
case State::LOGO_FINISHED:
Audio::get()->playMusic("title.ogg");
tiled_bg_->changeSpeedTo(60.0F, 0.5F);
blink_accumulator_ = 0.0f; // Resetea el timer para empezar el parpadeo desde el inicio
blink_accumulator_ = 0.0F; // Resetea el timer para empezar el parpadeo desde el inicio
break;
case State::START_HAS_BEEN_PRESSED:
Audio::get()->fadeOutMusic(MUSIC_FADE_OUT_LONG_MS);
blink_accumulator_ = 0.0f; // Resetea el timer para empezar el parpadeo desde el inicio
blink_accumulator_ = 0.0F; // Resetea el timer para empezar el parpadeo desde el inicio
break;
}
}
@@ -568,9 +568,9 @@ void Title::initPlayers() {
}
// Actualiza los jugadores
void Title::updatePlayers(float deltaTime) {
void Title::updatePlayers(float delta_time) {
for (auto& player : players_) {
player->update(deltaTime);
player->update(delta_time);
}
}

View File

@@ -1,13 +1,15 @@
#pragma once
#include <SDL3/SDL.h> // Para SDL_Event, Uint64
#include <SDL3/SDL.h> // Para SDL_Keycode, SDL_Event, Uint64
#include <cstdint> // Para uint8_t
#include <memory> // Para shared_ptr, unique_ptr
#include <string_view> // Para string_view
#include <vector> // Para vector
#include "player.hpp" // Para Player
#include "section.hpp" // Para Options, Name (ptr only)
#include "color.hpp" // for Color
#include "player.hpp" // for Player
#include "section.hpp" // for Options, Name (ptr only)
class Fade;
class GameLogo;
@@ -46,15 +48,15 @@ class Title {
private:
// --- Constantes de tiempo (en segundos) ---
static constexpr float START_PRESSED_DELAY_S = 1666.67f / 1000.0f; // Tiempo antes de fade tras pulsar start (100 frames a 60fps)
static constexpr float START_PRESSED_DELAY_S = 1666.67F / 1000.0F; // Tiempo antes de fade tras pulsar start (100 frames a 60fps)
static constexpr int MUSIC_FADE_OUT_LONG_MS = 1500; // Fade out largo de música
static constexpr int MUSIC_FADE_OUT_SHORT_MS = 300; // Fade out corto de música
// --- Constantes de parpadeo (en segundos) ---
static constexpr float LOGO_BLINK_PERIOD_S = 833.0f / 1000.0f; // Período de parpadeo del logo (833ms)
static constexpr float LOGO_BLINK_ON_TIME_S = 583.0f / 1000.0f; // Tiempo encendido del logo (583ms)
static constexpr float START_BLINK_PERIOD_S = 167.0f / 1000.0f; // Período de parpadeo del start (167ms)
static constexpr float START_BLINK_ON_TIME_S = 83.0f / 1000.0f; // Tiempo encendido del start (83ms)
static constexpr float LOGO_BLINK_PERIOD_S = 833.0F / 1000.0F; // Período de parpadeo del logo (833ms)
static constexpr float LOGO_BLINK_ON_TIME_S = 583.0F / 1000.0F; // Tiempo encendido del logo (583ms)
static constexpr float START_BLINK_PERIOD_S = 167.0F / 1000.0F; // Período de parpadeo del start (167ms)
static constexpr float START_BLINK_ON_TIME_S = 83.0F / 1000.0F; // Tiempo encendido del start (83ms)
// --- Constantes de layout ---
static constexpr int MINI_LOGO_Y_DIVISOR = 5; // Divisor para posición Y del mini logo
@@ -92,8 +94,8 @@ class Title {
Section::Options selection_ = Section::Options::TITLE_TIME_OUT; // Opción elegida en el título
State state_; // Estado actual de la sección
Uint64 last_time_ = 0; // Último timestamp para calcular delta-time
float counter_time_ = 0.0f; // Temporizador para la pantalla de título (en segundos)
float blink_accumulator_ = 0.0f; // Acumulador para el parpadeo (en segundos)
float counter_time_ = 0.0F; // Temporizador para la pantalla de título (en segundos)
float blink_accumulator_ = 0.0F; // Acumulador para el parpadeo (en segundos)
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
@@ -104,11 +106,11 @@ class Title {
#endif
// --- Ciclo de vida del título ---
void update(float deltaTime); // Actualiza las variables del objeto
float calculateDeltaTime(); // Calcula el tiempo transcurrido desde el último frame
void updateState(float deltaTime); // Actualiza el estado actual del título
void setState(State state); // Cambia el estado del título
void resetCounter(); // Reinicia el contador interno
void update(float delta_time); // Actualiza las variables del objeto
auto calculateDeltaTime() -> float; // Calcula el tiempo transcurrido desde el último frame
void updateState(float delta_time); // Actualiza el estado actual del título
void setState(State state); // Cambia el estado del título
void resetCounter(); // Reinicia el contador interno
// --- Entrada de usuario ---
void checkEvents(); // Comprueba los eventos
@@ -125,16 +127,16 @@ class Title {
// --- Gestión de jugadores ---
void initPlayers(); // Inicializa los jugadores
void updatePlayers(float deltaTime); // Actualiza los jugadores
void updatePlayers(float delta_time); // Actualiza los jugadores
void renderPlayers(); // Renderiza los jugadores
auto getPlayer(Player::Id id) -> std::shared_ptr<Player>; // Obtiene un jugador a partir de su "id"
// --- Visualización / Renderizado ---
void render(); // Dibuja el objeto en pantalla
void updateFade(); // Actualiza el efecto de fundido (fade in/out)
void updateStartPrompt(float deltaTime); // Actualiza el mensaje de "Pulsa Start"
void renderStartPrompt(); // Dibuja el mensaje de "Pulsa Start" en pantalla
void renderCopyright(); // Dibuja el aviso de copyright
void render(); // Dibuja el objeto en pantalla
void updateFade(); // Actualiza el efecto de fundido (fade in/out)
void updateStartPrompt(float delta_time); // Actualiza el mensaje de "Pulsa Start"
void renderStartPrompt(); // Dibuja el mensaje de "Pulsa Start" en pantalla
void renderCopyright(); // Dibuja el aviso de copyright
// --- Utilidades estáticas ---
static void swapControllers(); // Intercambia la asignación de mandos a los jugadores

View File

@@ -1,16 +1,16 @@
#include "shutdown.hpp"
#include <array>
#include <iostream>
#include <vector>
#include <sys/types.h> // Para pid_t
#include <cstdlib> // Para WEXITSTATUS
#include <iostream> // Para char_traits, basic_ostream, operator<<, cerr
#include <vector> // Para vector
#ifdef _WIN32
#include <windows.h>
#else
#include <sys/wait.h>
#include <unistd.h>
#include <string>
#include <sys/wait.h> // Para waitpid
#include <unistd.h> // Para _exit, execvp, fork
#endif
namespace SystemShutdown {

View File

@@ -3,11 +3,11 @@
#include "moving_sprite.hpp" // Para MovingSprite
// Actualiza la posición y comprueba si ha llegado a su destino (time-based)
void SmartSprite::update(float deltaTime) {
void SmartSprite::update(float delta_time) {
if (enabled_) {
MovingSprite::update(deltaTime);
MovingSprite::update(delta_time);
checkMove();
checkFinished(deltaTime);
checkFinished(delta_time);
}
}
@@ -72,15 +72,15 @@ void SmartSprite::checkMove() {
}
// Comprueba si ha terminado (time-based)
void SmartSprite::checkFinished(float deltaTime) {
void SmartSprite::checkFinished(float delta_time) {
// Comprueba si ha llegado a su destino
on_destination_ = (getPosX() == dest_x_ && getPosY() == dest_y_);
if (on_destination_) {
if (finished_delay_ms_ == 0.0f) {
if (finished_delay_ms_ == 0.0F) {
finished_ = true;
} else {
finished_timer_ += deltaTime;
finished_timer_ += delta_time;
if (finished_timer_ >= finished_delay_ms_) {
finished_ = true;
}

View File

@@ -16,8 +16,8 @@ class SmartSprite : public AnimatedSprite {
~SmartSprite() override = default;
// --- Métodos principales ---
void update(float deltaTime) override; // Actualiza la posición y comprueba si ha llegado a su destino (time-based)
void render() override; // Dibuja el sprite
void update(float delta_time) override; // Actualiza la posición y comprueba si ha llegado a su destino (time-based)
void render() override; // Dibuja el sprite
// --- Getters ---
auto getDestX() const -> int { return dest_x_; } // Obtiene la posición de destino en X
@@ -35,13 +35,13 @@ class SmartSprite : public AnimatedSprite {
// --- Variables de estado ---
int dest_x_ = 0; // Posición de destino en el eje X
int dest_y_ = 0; // Posición de destino en el eje Y
float finished_delay_ms_ = 0.0f; // Retraso para deshabilitarlo (ms)
float finished_timer_ = 0.0f; // Timer acumulado (ms)
float finished_delay_ms_ = 0.0F; // Retraso para deshabilitarlo (ms)
float finished_timer_ = 0.0F; // Timer acumulado (ms)
bool on_destination_ = false; // Indica si está en el destino
bool finished_ = false; // Indica si ya ha terminado
bool enabled_ = false; // Indica si el objeto está habilitado
// --- Métodos internos ---
void checkFinished(float deltaTime); // Comprueba si ha terminado (time-based)
void checkMove(); // Comprueba el movimiento
void checkFinished(float delta_time); // Comprueba si ha terminado (time-based)
void checkMove(); // Comprueba el movimiento
};

View File

@@ -1,9 +1,10 @@
#include "stage.hpp"
#include <algorithm>
#include <fstream>
#include <sstream>
#include <utility>
#include <algorithm> // Para max, min
#include <exception> // Para exception
#include <fstream> // Para basic_istream, basic_ifstream, ifstream, stringstream
#include <sstream> // Para basic_stringstream
#include <utility> // Para move
// Implementación de StageData
StageData::StageData(int power_to_complete, int min_menace, int max_menace, std::string name)

View File

@@ -1,11 +1,12 @@
#pragma once
#include <cstddef> // Para size_t
#include <functional> // Para function
#include <optional> // Para optional
#include <string> // Para string
#include <string> // Para basic_string, string
#include <vector> // Para vector
#include "stage_interface.hpp" // Para IStageInfo
#include "stage_interface.hpp" // for IStageInfo
// --- Enums ---
enum class PowerCollectionState {

View File

@@ -1,10 +1,9 @@
#include "system_utils.hpp"
#include <sys/stat.h>
#include <sys/stat.h> // Para stat, mkdir, S_ISDIR
#include <cerrno>
#include <cstdlib>
#include <iostream>
#include <cerrno> // Para EACCES, EEXIST, ENAMETOOLONG, errno
#include <cstdlib> // Para getenv, size_t
#ifdef _WIN32
#include <direct.h>
@@ -15,8 +14,8 @@
#undef ERROR_ALREADY_EXISTS
#endif
#else
#include <pwd.h>
#include <unistd.h>
#include <pwd.h> // Para getpwuid, passwd
#include <unistd.h> // Para getuid
#endif
namespace SystemUtils {

View File

@@ -6,9 +6,10 @@
#include <algorithm> // Para max
#include <array> // Para array
#include <cstdlib> // Para rand, abs
#include <string> // Para basic_string
#include "audio.hpp" // Para Audio
#include "param.hpp" // Para Param, ParamGame, param
#include "param.hpp" // Para Param, param, ParamGame, ParamTabe
#include "resource.hpp" // Para Resource
#include "utils.hpp" // Para Zone
@@ -18,11 +19,11 @@ Tabe::Tabe()
timer_(Timer(param.tabe.min_spawn_time, param.tabe.max_spawn_time)) {}
// Actualiza la lógica (time-based)
void Tabe::update(float deltaTime) {
void Tabe::update(float delta_time) {
if (enabled_ && !timer_.is_paused) {
sprite_->update(deltaTime);
move(deltaTime);
updateState(deltaTime);
sprite_->update(delta_time);
move(delta_time);
updateState(delta_time);
}
timer_.update();
@@ -39,10 +40,10 @@ void Tabe::render() {
}
// Mueve el objeto (time-based)
void Tabe::move(float deltaTime) {
void Tabe::move(float delta_time) {
const int X = static_cast<int>(x_);
speed_ += accel_ * deltaTime;
x_ += speed_ * deltaTime;
speed_ += accel_ * delta_time;
x_ += speed_ * delta_time;
fly_distance_ -= std::abs(X - static_cast<int>(x_));
// Comprueba si sale por los bordes
@@ -77,8 +78,8 @@ void Tabe::move(float deltaTime) {
if (fly_distance_ <= 0) {
if (waiting_counter_ > 0) {
accel_ = speed_ = 0.0F;
waiting_counter_ -= deltaTime;
if (waiting_counter_ < 0) waiting_counter_ = 0;
waiting_counter_ -= delta_time;
waiting_counter_ = std::max<float>(waiting_counter_, 0);
} else {
constexpr int CHOICES = 4;
const std::array<Direction, CHOICES> LEFT = {
@@ -129,22 +130,22 @@ void Tabe::enable() {
void Tabe::setRandomFlyPath(Direction direction, int length) {
direction_ = direction;
fly_distance_ = length;
waiting_counter_ = 0.083f + (rand() % 15) * 0.0167f; // 5-20 frames converted to seconds (5/60 to 20/60)
waiting_counter_ = 0.083F + (rand() % 15) * 0.0167F; // 5-20 frames converted to seconds (5/60 to 20/60)
Audio::get()->playSound("tabe.wav");
constexpr float SPEED = 120.0f; // 2 pixels/frame * 60fps = 120 pixels/second
constexpr float SPEED = 120.0F; // 2 pixels/frame * 60fps = 120 pixels/second
switch (direction) {
case Direction::TO_THE_LEFT: {
speed_ = -1.0F * SPEED;
accel_ = -1.0F * (1 + rand() % 10) * 2.0f; // Converted from frame-based to seconds
accel_ = -1.0F * (1 + rand() % 10) * 2.0F; // Converted from frame-based to seconds
sprite_->setFlip(SDL_FLIP_NONE);
break;
}
case Direction::TO_THE_RIGHT: {
speed_ = SPEED;
accel_ = (1 + rand() % 10) * 2.0f; // Converted from frame-based to seconds
accel_ = (1 + rand() % 10) * 2.0F; // Converted from frame-based to seconds
sprite_->setFlip(SDL_FLIP_HORIZONTAL);
break;
}
@@ -166,7 +167,7 @@ void Tabe::setState(State state) {
case State::HIT:
sprite_->setCurrentAnimation("hit");
hit_counter_ = 0.083f; // 5 frames converted to seconds (5/60)
hit_counter_ = 0.083F; // 5 frames converted to seconds (5/60)
++number_of_hits_;
break;
@@ -177,9 +178,9 @@ void Tabe::setState(State state) {
}
// Actualiza el estado (time-based)
void Tabe::updateState(float deltaTime) {
void Tabe::updateState(float delta_time) {
if (state_ == State::HIT) {
hit_counter_ -= deltaTime;
hit_counter_ -= delta_time;
if (hit_counter_ <= 0) {
setState(State::FLY);
}

View File

@@ -26,14 +26,14 @@ class Tabe {
~Tabe() = default;
// --- Métodos principales ---
void update(float deltaTime); // Actualiza la lógica (time-based)
void render(); // Dibuja el objeto
void enable(); // Habilita el objeto
void setState(State state); // Establece el estado
auto tryToGetBonus() -> bool; // Intenta obtener el bonus
void pauseTimer(bool value); // Detiene/activa el timer
void disableSpawning(); // Deshabilita el spawning permanentemente
void enableSpawning(); // Habilita el spawning nuevamente
void update(float delta_time); // Actualiza la lógica (time-based)
void render(); // Dibuja el objeto
void enable(); // Habilita el objeto
void setState(State state); // Establece el estado
auto tryToGetBonus() -> bool; // Intenta obtener el bonus
void pauseTimer(bool value); // Detiene/activa el timer
void disableSpawning(); // Deshabilita el spawning permanentemente
void enableSpawning(); // Habilita el spawning nuevamente
// --- Getters ---
auto getCollider() -> SDL_FRect& { return sprite_->getRect(); } // Obtiene el área de colisión
@@ -141,10 +141,10 @@ class Tabe {
Timer timer_; // Temporizador para gestionar la aparición
// --- Métodos internos ---
void move(float deltaTime); // Mueve el objeto (time-based)
void move(float delta_time); // Mueve el objeto (time-based)
void shiftSprite() { sprite_->setPos(x_, y_); } // Actualiza la posición del sprite
void setRandomFlyPath(Direction direction, int length); // Establece un vuelo aleatorio
void updateState(float deltaTime); // Actualiza el estado (time-based)
void updateState(float delta_time); // Actualiza el estado (time-based)
void updateTimer(); // Actualiza el temporizador
void disable(); // Deshabilita el objeto
};

View File

@@ -1,20 +1,21 @@
#include "text.hpp"
#include <SDL3/SDL.h> // Para Uint8, SDL_GetRenderTarget, SDL_RenderClear, SDL_SetRenderDrawColor, SDL_SetRenderTarget, SDL_FRect, SDL_BLENDMODE_BLEND, SDL_PixelFormat, SDL_TextureAccess
#include <SDL3/SDL.h> // Para SDL_FRect, Uint8, SDL_GetRenderTarget, SDL_RenderClear, SDL_SetRenderDrawColor, SDL_SetRenderTarget, SDL_BLENDMODE_BLEND, SDL_PixelFormat, SDL_TextureAccess, SDL_GetTextureAlphaMod
#include <fstream> // Para basic_ifstream, basic_istream, basic_ostream, operator<<, endl, ifstream
#include <fstream> // Para basic_ifstream, basic_istream, basic_ostream, operator<<, istream, ifstream, istringstream
#include <iostream> // Para cerr
#include <sstream> // Para istringstream
#include <sstream> // Para basic_istringstream
#include <stdexcept> // Para runtime_error
#include <string_view> // Para string_view
#include <vector> // Para vector
#include "color.hpp" // Para Color
#include "resource_helper.hpp" // Para ResourceHelper
#include "resource_helper.hpp" // Para loadFile
#include "screen.hpp" // Para Screen
#include "sprite.hpp" // Para Sprite
#include "texture.hpp" // Para Texture
#include "utils.hpp" // Para getFileName, printWithDots
#include "ui/logger.hpp"
#include "ui/logger.hpp" // Para dots
#include "utils.hpp" // Para getFileName
// Constructor
Text::Text(const std::shared_ptr<Texture>& texture, const std::string& text_file) {

View File

@@ -16,8 +16,8 @@
#include "external/gif.hpp" // Para Gif
#include "resource_helper.hpp" // Para ResourceHelper
#include "stb_image.h" // Para stbi_image_free, stbi_load, STBI_rgb_alpha
#include "utils.hpp"
#include "ui/logger.hpp"
#include "utils.hpp"
// Constructor
Texture::Texture(SDL_Renderer* renderer, std::string path)

View File

@@ -2,11 +2,12 @@
#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, pow
#include <cstdlib> // Para rand
#include <memory> // Para allocator, unique_ptr, make_unique
#include <numbers> // Para pi
#include <algorithm> // Para max
#include <cmath> // Para cos, pow, sin
#include <cstdlib> // Para rand
#include <memory> // Para unique_ptr, make_unique
#include <numbers> // Para pi
#include <string> // Para basic_string
#include "resource.hpp" // Para Resource
#include "screen.hpp" // Para Screen
@@ -92,10 +93,10 @@ void TiledBG::update(float delta_time) {
}
case TiledBGMode::CIRCLE: {
// El tileado de fondo se desplaza en circulo
const float angle_rad = (desp_ * std::numbers::pi / 180.0F);
const float ANGLE_RAD = (desp_ * std::numbers::pi / 180.0F);
window_.x = 128 + static_cast<int>(std::cos(angle_rad) * 128);
window_.y = 128 + static_cast<int>(std::sin(-angle_rad) * 96);
window_.x = 128 + static_cast<int>(std::cos(ANGLE_RAD) * 128);
window_.y = 128 + static_cast<int>(std::sin(-ANGLE_RAD) * 96);
break;
}
default:
@@ -129,7 +130,7 @@ void TiledBG::updateStop(float delta_time) {
// Cambia la velocidad gradualmente en X segundos
void TiledBG::changeSpeedTo(float target_speed, float duration_s) {
if (duration_s <= 0.0f) {
if (duration_s <= 0.0F) {
// Si la duración es 0 o negativa, cambia inmediatamente
speed_ = target_speed;
changing_speed_ = false;
@@ -141,7 +142,7 @@ void TiledBG::changeSpeedTo(float target_speed, float duration_s) {
initial_speed_ = speed_;
target_speed_ = target_speed;
change_duration_s_ = duration_s;
change_timer_s_ = 0.0f;
change_timer_s_ = 0.0F;
}
// Actualiza el cambio gradual de velocidad (time-based)

View File

@@ -39,9 +39,9 @@ class TiledBG {
// --- Constantes ---
static constexpr int TILE_WIDTH = 64; // Ancho del tile
static constexpr int TILE_HEIGHT = 64; // Alto del tile
static constexpr float STOP_THRESHOLD_FACTOR = 20.0f; // Factor para umbral de parada
static constexpr float DECELERATION_FACTOR = 1.05f; // Factor de desaceleración
static constexpr float MIN_SPEED = 0.1f; // Velocidad mínima
static constexpr float STOP_THRESHOLD_FACTOR = 20.0F; // Factor para umbral de parada
static constexpr float DECELERATION_FACTOR = 1.05F; // Factor de desaceleración
static constexpr float MIN_SPEED = 0.1F; // Velocidad mínima
// --- Objetos y punteros ---
SDL_Renderer* renderer_; // El renderizador de la ventana

View File

@@ -44,7 +44,7 @@ inline void error(const std::string& msg) {
}
// CR
inline void CR() {
inline void cr() {
std::cout << "\n";
}
@@ -52,7 +52,7 @@ inline void CR() {
inline void dots(const std::string& prefix,
const std::string& middle,
const std::string& suffix,
const std::string& suffixColor = GREEN) {
const std::string& suffix_color = GREEN) {
size_t field_width = TOTAL_WIDTH > (prefix.size() + suffix.size())
? TOTAL_WIDTH - prefix.size() - suffix.size()
: 0;
@@ -65,7 +65,7 @@ inline void dots(const std::string& prefix,
}
std::cout << " " << prefix << field_text
<< suffixColor << suffix << RESET
<< suffix_color << suffix << RESET
<< "\n";
}

View File

@@ -1,8 +1,8 @@
#include "menu_option.hpp"
#include <algorithm> // Para find
#include <algorithm> // Para max
#include <iterator> // Para distance
#include <memory> // Para allocator
#include <ranges> // Para __find_fn, find
#include "text.hpp" // Para Text

View File

@@ -69,7 +69,7 @@ void Notifier::processNotification(int index, float delta_time) {
void Notifier::playNotificationSoundIfNeeded(const Notification& notification) {
// Hace sonar la notificación al inicio
if (notification.timer <= 0.016f &&
if (notification.timer <= 0.016F &&
param.notification.sound &&
notification.state == State::RISING) {
Audio::get()->playSound("notify.wav", Audio::Group::INTERFACE);
@@ -99,7 +99,7 @@ void Notifier::handleRisingState(int index, float delta_time) {
const float PIXELS_TO_MOVE = ANIMATION_SPEED_PX_PER_S * delta_time;
const float PROGRESS = notification.timer * ANIMATION_SPEED_PX_PER_S / notification.travel_dist;
const int ALPHA = static_cast<int>(255 * std::min(PROGRESS, 1.0f));
const int ALPHA = static_cast<int>(255 * std::min(PROGRESS, 1.0F));
moveNotificationVertically(notification, param.notification.pos_v == Position::TOP ? PIXELS_TO_MOVE : -PIXELS_TO_MOVE);
notification.texture->setAlpha(ALPHA);
@@ -115,7 +115,7 @@ void Notifier::handleStayState(int index) {
if (notification.timer >= STAY_DURATION_S) {
notification.state = State::VANISHING;
notification.timer = 0.0f;
notification.timer = 0.0F;
}
}
@@ -124,12 +124,12 @@ void Notifier::handleVanishingState(int index, float delta_time) {
const float PIXELS_TO_MOVE = ANIMATION_SPEED_PX_PER_S * delta_time;
const float PROGRESS = notification.timer * ANIMATION_SPEED_PX_PER_S / notification.travel_dist;
const int ALPHA = static_cast<int>(255 * (1 - std::min(PROGRESS, 1.0f)));
const int ALPHA = static_cast<int>(255 * (1 - std::min(PROGRESS, 1.0F)));
moveNotificationVertically(notification, param.notification.pos_v == Position::TOP ? -PIXELS_TO_MOVE : PIXELS_TO_MOVE);
notification.texture->setAlpha(ALPHA);
if (PROGRESS >= 1.0f) {
if (PROGRESS >= 1.0F) {
notification.state = State::FINISHED;
}
}
@@ -143,7 +143,7 @@ void Notifier::transitionToStayState(int index) {
notification.state = State::STAY;
notification.texture->setAlpha(255);
notification.rect.y = static_cast<float>(notification.y); // Asegurar posición exacta
notification.timer = 0.0f;
notification.timer = 0.0F;
}
// Elimina las notificaciones finalizadas

View File

@@ -42,8 +42,8 @@ class Notifier {
private:
// --- Constantes de tiempo (en segundos) ---
static constexpr float STAY_DURATION_S = 2.5f; // Tiempo que se ve la notificación (150 frames @ 60fps)
static constexpr float ANIMATION_SPEED_PX_PER_S = 60.0f; // Velocidad de animación (1 pixel/frame @ 60fps)
static constexpr float STAY_DURATION_S = 2.5F; // Tiempo que se ve la notificación (150 frames @ 60fps)
static constexpr float ANIMATION_SPEED_PX_PER_S = 60.0F; // Velocidad de animación (1 pixel/frame @ 60fps)
// --- Enums privados ---
enum class State {
@@ -67,7 +67,7 @@ class Notifier {
std::string code; // Código identificador de la notificación
State state{State::RISING}; // Estado de la notificación
Shape shape{Shape::SQUARED}; // Forma de la notificación
float timer{0.0f}; // Timer en segundos
float timer{0.0F}; // Timer en segundos
int y{0}; // Posición vertical
int travel_dist{0}; // Distancia a recorrer

View File

@@ -4,13 +4,14 @@
#include <cstddef> // Para size_t
#include <functional> // Para function
#include <iterator> // Para pair
#include <memory> // Para unique_ptr
#include <string> // Para string
#include <string> // Para basic_string, string
#include <utility> // Para pair
#include <vector> // Para vector
#include "define_buttons.hpp" // Para DefineButtons
#include "ui_message.hpp" // Para UIMessage
#include "define_buttons.hpp" // for DefineButtons
#include "ui_message.hpp" // for UIMessage
class MenuOption;
class MenuRenderer;

View File

@@ -1,5 +1,6 @@
#include "ui_message.hpp"
#include <algorithm>
#include <cmath> // Para pow
#include <utility>
@@ -20,7 +21,7 @@ void UIMessage::show() {
start_y_ = DESP; // Empieza 8 píxeles arriba de la posición base
target_y_ = 0.0F; // La posición final es la base
y_offset_ = start_y_;
animation_timer_ = 0.0f;
animation_timer_ = 0.0F;
animating_ = true;
visible_ = true;
}
@@ -33,7 +34,7 @@ void UIMessage::hide() {
start_y_ = y_offset_; // Comienza desde la posición actual
target_y_ = DESP; // Termina 8 píxeles arriba de la base
animation_timer_ = 0.0f;
animation_timer_ = 0.0F;
animating_ = true;
}
@@ -50,9 +51,7 @@ void UIMessage::updateAnimation(float delta_time) {
float t = animation_timer_ / ANIMATION_DURATION_S;
// Clamp t entre 0 y 1
if (t > 1.0f) {
t = 1.0f;
}
t = std::min(t, 1.0f);
if (target_y_ > start_y_) {
// Animación de entrada (ease out cubic)
@@ -67,7 +66,7 @@ void UIMessage::updateAnimation(float delta_time) {
if (animation_timer_ >= ANIMATION_DURATION_S) {
y_offset_ = target_y_;
animating_ = false;
animation_timer_ = 0.0f; // Reset timer
animation_timer_ = 0.0F; // Reset timer
if (target_y_ < 0.0F) {
visible_ = false;
}

View File

@@ -48,7 +48,7 @@ class UIMessage {
float start_y_ = 0.0F; // Posición Y inicial de la animación
float target_y_ = 0.0F; // Posición Y objetivo de la animación
float animation_timer_ = 0.0F; // Timer actual de la animación en segundos
static constexpr float ANIMATION_DURATION_S = 0.133f; // Duración total de la animación (8 frames @ 60fps)
static constexpr float ANIMATION_DURATION_S = 0.133F; // Duración total de la animación (8 frames @ 60fps)
static constexpr float DESP = -8.0F; // Distancia a desplazarse
// Actualiza la interpolación de la animación (ease out/in cubic)

View File

@@ -1,19 +1,17 @@
#define _USE_MATH_DEFINES
#include "utils.hpp"
#include <SDL3/SDL.h> // Para SDL_RenderPoint, SDL_FRect, SDL_FPoint, SDL_CloseIO, SDL_IOFromFile, SDL_LogCategory, SDL_LogError, SDL_LogInfo, SDL_ReadIO, SDL_Renderer
#include <SDL3/SDL.h> // Para SDL_RenderPoint, SDL_FRect, SDL_FPoint, SDL_Renderer
#include <algorithm> // Para clamp, find_if_not, find, transform
#include <algorithm> // Para clamp, __transform_fn, transform
#include <cctype> // Para tolower, isspace
#include <cmath> // Para pow, sin, M_PI, cos, sqrt
#include <compare> // Para operator<, __synth3way_t
#include <compare> // Para operator<
#include <filesystem> // Para path
#include <ranges>
#include <stdexcept> // Para runtime_error
#include <string> // Para basic_string, allocator, string, operator==, operator+, char_traits
#include <ranges> // Para __find_if_not_fn, find_if_not, reverse_view, __find_fn, find, ref_view
#include <string> // Para basic_string, string, allocator, char_traits, operator==, operator+
#include "lang.hpp" // Para getText
#include "resource_helper.hpp" // Para ResourceHelper
#include "lang.hpp" // Para getText
// Variables
Overrides overrides = Overrides();

View File

@@ -83,8 +83,8 @@ auto easeOutCubic(double time) -> double;
auto easeInCubic(double time) -> double;
// Utilidades varias
auto stringInVector(const std::vector<std::string>& vec, const std::string& str) -> bool; // Comprueba si un vector contiene una cadena
auto truncateWithEllipsis(const std::string& input, size_t length) -> std::string; // Trunca un string y le añade puntos suspensivos
auto stringInVector(const std::vector<std::string>& vec, const std::string& str) -> bool; // Comprueba si un vector contiene una cadena
auto truncateWithEllipsis(const std::string& input, size_t length) -> std::string; // Trunca un string y le añade puntos suspensivos
// Ficheros y rutas
auto getFileName(const std::string& path) -> std::string; // Obtiene el nombre de un fichero a partir de una ruta

View File

@@ -10,7 +10,7 @@ void Writer::update(float delta_time) {
writing_timer_ += delta_time;
if (writing_timer_ >= speed_interval_) {
index_++;
writing_timer_ = 0.0f;
writing_timer_ = 0.0F;
}
if (index_ == length_) {
@@ -27,7 +27,7 @@ void Writer::update(float delta_time) {
// Actualiza el objeto (delta_time en segundos)
void Writer::updateS(float delta_time) {
// Convierte segundos a milisegundos y usa la lógica normal
update(delta_time * 1000.0f);
update(delta_time * 1000.0F);
}
// Dibuja el objeto en pantalla
@@ -61,16 +61,16 @@ void Writer::setCaption(const std::string& text) {
// Establece el valor de la variable (frames)
void Writer::setSpeed(int value) {
// Convierte frames a milisegundos (frames * 16.67ms)
constexpr float FRAME_TIME_MS = 16.67f;
constexpr float FRAME_TIME_MS = 16.67F;
speed_interval_ = static_cast<float>(value) * FRAME_TIME_MS;
writing_timer_ = 0.0f;
writing_timer_ = 0.0F;
}
// Establece la velocidad en segundos entre caracteres
void Writer::setSpeedS(float value) {
// Convierte segundos a milisegundos para consistencia interna
speed_interval_ = value * 1000.0f;
writing_timer_ = 0.0f;
speed_interval_ = value * 1000.0F;
writing_timer_ = 0.0F;
}
// Establece el valor de la variable
@@ -86,13 +86,13 @@ auto Writer::isEnabled() const -> bool {
// Establece el temporizador para deshabilitar el objeto (en milisegundos)
void Writer::setFinishedTimerMs(float time_ms) {
enabled_timer_target_ = time_ms;
enabled_timer_ = 0.0f;
enabled_timer_ = 0.0F;
}
// Establece el temporizador para deshabilitar el objeto (en segundos)
void Writer::setFinishedTimerS(float time_s) {
enabled_timer_target_ = time_s * 1000.0f; // Convertir segundos a milisegundos
enabled_timer_ = 0.0f;
enabled_timer_target_ = time_s * 1000.0F; // Convertir segundos a milisegundos
enabled_timer_ = 0.0F;
}
// Centra la cadena de texto a un punto X

View File

@@ -45,12 +45,12 @@ class Writer {
int pos_x_ = 0; // Posición en el eje X donde empezar a escribir el texto
int pos_y_ = 0; // Posición en el eje Y donde empezar a escribir el texto
int kerning_ = 0; // Kerning del texto, es decir, espaciado entre caracteres
float speed_interval_ = 0.0f; // Intervalo entre caracteres (ms para compatibilidad)
float writing_timer_ = 0.0f; // Temporizador de escritura para cada caracter
float speed_interval_ = 0.0F; // Intervalo entre caracteres (ms para compatibilidad)
float writing_timer_ = 0.0F; // Temporizador de escritura para cada caracter
int index_ = 0; // Posición del texto que se está escribiendo
int length_ = 0; // Longitud de la cadena a escribir
float enabled_timer_ = 0.0f; // Temporizador para deshabilitar el objeto
float enabled_timer_target_ = 0.0f; // Tiempo objetivo para deshabilitar el objeto
float enabled_timer_ = 0.0F; // Temporizador para deshabilitar el objeto
float enabled_timer_target_ = 0.0F; // Tiempo objetivo para deshabilitar el objeto
bool completed_ = false; // Indica si se ha escrito todo el texto
bool enabled_ = false; // Indica si el objeto está habilitado
bool finished_ = false; // Indica si ya ha terminado