diff --git a/source/animated_sprite.cpp b/source/animated_sprite.cpp index c4e2005..0b57ce2 100644 --- a/source/animated_sprite.cpp +++ b/source/animated_sprite.cpp @@ -122,8 +122,8 @@ void AnimatedSprite::animate(float deltaTime) { return; } - // Convertir speed (frames) a tiempo: speed frames = speed/60 segundos a 60fps - float frameTime = static_cast(animations_[current_animation_].speed) / 60.0f; + // Convertir speed (frames) a tiempo: speed frames = speed * (1000ms/60fps) milisegundos + float frameTime = static_cast(animations_[current_animation_].speed) * (1000.0f / 60.0f); // Acumular tiempo transcurrido animations_[current_animation_].time_accumulator += deltaTime; diff --git a/source/director.cpp b/source/director.cpp index 65ed1a2..3dc6a53 100644 --- a/source/director.cpp +++ b/source/director.cpp @@ -42,7 +42,7 @@ Director::Director(int argc, std::span argv) { Section::name = Section::Name::GAME; Section::options = Section::Options::GAME_PLAY_1P; #elif _DEBUG - Section::name = Section::Name::INSTRUCTIONS; + Section::name = Section::Name::LOGO; Section::options = Section::Options::GAME_PLAY_1P; #else // NORMAL GAME Section::name = Section::Name::LOGO; diff --git a/source/game_logo.cpp b/source/game_logo.cpp index b14c820..c4c4484 100644 --- a/source/game_logo.cpp +++ b/source/game_logo.cpp @@ -243,8 +243,8 @@ void GameLogo::handleArcadeEditionMoving() { } void GameLogo::handleArcadeEditionMoving(float deltaTime) { - // Convertir 0.1F * ZOOM_FACTOR por frame a por segundo (asumiendo 60fps) - zoom_ -= (0.1F * ZOOM_FACTOR * 60.0F) * deltaTime; + // Convertir 0.1F * ZOOM_FACTOR por frame a por milisegundo (asumiendo 60fps) + zoom_ -= (0.1F * ZOOM_FACTOR) * deltaTime / (1000.0F / 60.0F); arcade_edition_sprite_->setZoom(zoom_); if (zoom_ <= 1.0F) { @@ -285,8 +285,8 @@ void GameLogo::processShakeEffect(SmartSprite* primary_sprite, SmartSprite* seco } void GameLogo::processShakeEffect(SmartSprite* primary_sprite, SmartSprite* secondary_sprite, float deltaTime) { - // Convertir delay (frames) a tiempo: delay frames = delay/60 segundos a 60fps - float delayTime = static_cast(shake_.delay) / 60.0f; + // Convertir delay (frames) a tiempo: delay frames = delay * (1000ms/60fps) + float delayTime = static_cast(shake_.delay) * (1000.0f / 60.0f); shake_.time_accumulator += deltaTime; @@ -313,8 +313,8 @@ void GameLogo::processArcadeEditionShake() { } void GameLogo::processArcadeEditionShake(float deltaTime) { - // Convertir delay (frames) a tiempo: delay frames = delay/60 segundos a 60fps - float delayTime = static_cast(shake_.delay) / 60.0f; + // Convertir delay (frames) a tiempo: delay frames = delay * (1000ms/60fps) + float delayTime = static_cast(shake_.delay) * (1000.0f / 60.0f); shake_.time_accumulator += deltaTime; @@ -374,8 +374,8 @@ void GameLogo::updatePostFinishedCounter(float deltaTime) { arcade_edition_status_ == Status::FINISHED && post_finished_counter_ > 0) { - // Convertir 1 frame a tiempo: 1 frame = 1/60 segundos a 60fps - float frameTime = 1.0f / 60.0f; + // Convertir 1 frame a tiempo: 1 frame = 1000ms/60fps = 16.67ms + float frameTime = 1000.0f / 60.0f; post_finished_time_accumulator_ += deltaTime; diff --git a/source/moving_sprite.cpp b/source/moving_sprite.cpp index 76cc63f..b605dea 100644 --- a/source/moving_sprite.cpp +++ b/source/moving_sprite.cpp @@ -67,11 +67,14 @@ void MovingSprite::move() { // Mueve el sprite (time-based) void MovingSprite::move(float deltaTime) { - x_ += vx_ * deltaTime; - y_ += vy_ * deltaTime; + // Convertir deltaTime (milisegundos) a factor de frame (asumiendo 60fps) + float frameFactor = deltaTime / (1000.0f / 60.0f); + + x_ += vx_ * frameFactor; + y_ += vy_ * frameFactor; - vx_ += ax_ * deltaTime; - vy_ += ay_ * deltaTime; + vx_ += ax_ * frameFactor; + vy_ += ay_ * frameFactor; pos_.x = static_cast(x_); pos_.y = static_cast(y_); @@ -106,9 +109,9 @@ void MovingSprite::rotate() { // Establece la rotacion (time-based) void MovingSprite::rotate(float deltaTime) { if (rotate_.enabled) { - // Convertir speed (frames) a tiempo: speed frames = speed/60 segundos a 60fps - float rotationSpeed = static_cast(rotate_.speed) / 60.0f; - rotate_.angle += rotate_.amount * (deltaTime / rotationSpeed); + // Convertir speed (frames) a tiempo: speed frames = speed * (1000ms/60fps) milisegundos + float rotationFrameTime = static_cast(rotate_.speed) * (1000.0f / 60.0f); + rotate_.angle += rotate_.amount * (deltaTime / rotationFrameTime); } } diff --git a/source/player.cpp b/source/player.cpp index bd07256..e34453c 100644 --- a/source/player.cpp +++ b/source/player.cpp @@ -237,7 +237,7 @@ void Player::handlePlayingMovement() { // Fase 1: Movimiento time-based durante el juego void Player::handlePlayingMovement(float deltaTime) { // Mueve el jugador a derecha o izquierda (time-based) - pos_x_ += vel_x_ * 60.0f * deltaTime; + pos_x_ += vel_x_ * deltaTime / (1000.0f / 60.0f); // Si el jugador abandona el area de juego por los laterales, restaura su posición const float MIN_X = play_area_.x - 5; @@ -388,7 +388,7 @@ void Player::handleCreditsMovement() { // Fase 4: Movimiento general en la pantalla de créditos (time-based) void Player::handleCreditsMovement(float deltaTime) { - pos_x_ += (vel_x_ / 2.0F) * 60.0f * deltaTime; // Convert frame-based movement to time-based + pos_x_ += (vel_x_ / 2.0F) * deltaTime / (1000.0f / 60.0f); // Convert frame-based movement to time-based if (vel_x_ > 0) { handleCreditsRightMovement(); @@ -425,7 +425,7 @@ void Player::handleWaitingMovement() { // Fase 4: Controla la animación del jugador saludando (time-based) void Player::handleWaitingMovement(float deltaTime) { waiting_time_accumulator_ += deltaTime; - float waiting_duration = static_cast(WAITING_COUNTER) / 60.0f; // Convert frames to seconds + float waiting_duration = static_cast(WAITING_COUNTER) * (1000.0f / 60.0f); // Convert frames to milliseconds if (waiting_time_accumulator_ >= waiting_duration) { waiting_time_accumulator_ = 0.0f; player_sprite_->resetAnimation(); diff --git a/source/sections/title.cpp b/source/sections/title.cpp index e43ede2..2c46f90 100644 --- a/source/sections/title.cpp +++ b/source/sections/title.cpp @@ -77,10 +77,10 @@ Title::~Title() { Options::gamepad_manager.clearPlayers(); } -// Actualiza las variables del objeto +// Actualiza las variables del objeto (frame-based) void Title::update() { - if (SDL_GetTicks() - ticks_ > param.game.speed) { - ticks_ = SDL_GetTicks(); + if (SDL_GetTicks() - last_time_ > param.game.speed) { + last_time_ = SDL_GetTicks(); Screen::get()->update(); updateFade(); @@ -92,6 +92,28 @@ void Title::update() { Audio::update(); } +// Actualiza las variables del objeto (time-based) +void Title::update(float deltaTime) { + Screen::get()->update(); + updateFade(); + updateState(deltaTime); + updateStartPrompt(); + + for (auto& player : players_) { + player->update(deltaTime); // deltaTime ya está en segundos + } + + Audio::update(); +} + +// Calcula el tiempo transcurrido desde el último frame +float Title::calculateDeltaTime() { + const Uint64 current_time = SDL_GetTicks(); + const float delta_time = static_cast(current_time - last_time_); + last_time_ = current_time; + return delta_time; +} + // Dibuja el objeto en pantalla void Title::render() { static auto* const SCREEN = Screen::get(); @@ -136,7 +158,7 @@ void Title::handleDebugColorKeys(SDL_Keycode key) { adjustColorComponent(key, color_); - counter_ = 0; + counter_time_ = 0.0f; tiled_bg_->setColor(color_); printColorValue(color_); } @@ -290,21 +312,25 @@ void Title::processPlayer2Start() { void Title::activatePlayerAndSetState(Player::Id player_id) { getPlayer(player_id)->setPlayingState(Player::State::TITLE_ANIMATION); setState(TitleState::START_HAS_BEEN_PRESSED); - counter_ = 0; + counter_time_ = 0.0f; } // Bucle para el titulo del juego void Title::run() { + last_time_ = SDL_GetTicks(); + while (Section::name == Section::Name::TITLE) { + const float delta_time = calculateDeltaTime(); + checkInput(); - update(); + update(delta_time); checkEvents(); // Tiene que ir antes del render render(); } } // Reinicia el contador interno -void Title::resetCounter() { counter_ = 0; } +void Title::resetCounter() { counter_time_ = 0.0f; } // Intercambia la asignación de mandos a los jugadores void Title::swapControllers() { @@ -370,18 +396,55 @@ void Title::updateState() { // Establece la lógica según el estado switch (state_) { case TitleState::LOGO_ANIMATING: { - game_logo_->update(); + game_logo_->update(); // Mantener frame-based para consistencia del estado if (game_logo_->hasFinished()) { setState(TitleState::LOGO_FINISHED); } break; } case TitleState::LOGO_FINISHED: { - ++counter_; // Incrementa el contador - game_logo_->update(); // Actualiza el logo con el título del juego - tiled_bg_->update(); // Actualiza el mosaico de fondo + // Ya no se usa counter_ aquí, se usa updateState(deltaTime) + game_logo_->update(); + tiled_bg_->update(); - if (counter_ == param.title.title_duration) { + // Esta lógica se movió a updateState(deltaTime) + break; + } + case TitleState::START_HAS_BEEN_PRESSED: { + // Ya no se usa counter_ aquí, se usa updateState(deltaTime) + game_logo_->update(); + tiled_bg_->update(); + + // Esta lógica se movió a updateState(deltaTime) + break; + } + + default: + break; + } +} + +// Actualiza el estado (time-based) +void Title::updateState(float deltaTime) { + // deltaTime ya está en segundos desde calculateDeltaTime() + game_logo_->update(deltaTime); + tiled_bg_->update(deltaTime); + + // Establece la lógica según el estado + switch (state_) { + case TitleState::LOGO_ANIMATING: { + if (game_logo_->hasFinished()) { + setState(TitleState::LOGO_FINISHED); + } + break; + } + case TitleState::LOGO_FINISHED: { + counter_time_ += deltaTime; // deltaTime está en milisegundos + + // param.title.title_duration está en frames (60fps), convertir a ms: frames * (1000ms/60fps) + float duration_ms = static_cast(param.title.title_duration) * (1000.0f / 60.0f); + + if (counter_time_ >= duration_ms) { // El menu ha hecho time out fade_->setPostDuration(0); fade_->activate(); @@ -390,11 +453,10 @@ void Title::updateState() { break; } case TitleState::START_HAS_BEEN_PRESSED: { - ++counter_; // Incrementa el contador - game_logo_->update(); // Actualiza el logo con el título del juego - tiled_bg_->update(); // Actualiza el mosaico de fondo - - if (counter_ == 100) { + counter_time_ += deltaTime; // deltaTime está en milisegundos + + // 100 frames a 60fps convertir a ms: 100 * (1000/60) = 1666.67 ms + if (counter_time_ >= (100.0f * 1000.0f / 60.0f)) { fade_->activate(); } break; @@ -544,7 +606,7 @@ void Title::initPlayers() { } } -// Actualza los jugadores +// Actualiza los jugadores void Title::updatePlayers() { for (auto& player : players_) { player->update(); diff --git a/source/sections/title.h b/source/sections/title.h index 589245e..8fdcb8c 100644 --- a/source/sections/title.h +++ b/source/sections/title.h @@ -60,16 +60,19 @@ class Title { Section::Name next_section_; // Siguiente sección a cargar Section::Options selection_ = Section::Options::TITLE_TIME_OUT; // Opción elegida en el título TitleState state_; // Estado actual de la sección - Uint64 ticks_ = 0; // Contador de ticks para ajustar la velocidad - int counter_ = 0; // Temporizador para la pantalla de título + Uint64 last_time_ = 0; // Último timestamp para calcular delta-time + float counter_time_ = 0.0f; // Temporizador para la pantalla de título (en milisegundos) int num_controllers_; // Número de mandos conectados bool should_render_start_prompt_ = false; // Indica si se muestra el texto de PRESS START BUTTON TO PLAY bool player1_start_pressed_ = false; // Indica si se ha pulsado el botón de empezar para el jugador 1 bool player2_start_pressed_ = false; // Indica si se ha pulsado el botón de empezar para el jugador 2 // --- Ciclo de vida del título --- - void update(); // Actualiza las variables del objeto - void updateState(); // Actualiza el estado actual del título + void update(); // Actualiza las variables del objeto (frame-based) + void update(float deltaTime); // Actualiza las variables del objeto (time-based) + float calculateDeltaTime(); // Calcula el tiempo transcurrido desde el último frame + void updateState(); // Actualiza el estado actual del título (frame-based) + void updateState(float deltaTime); // Actualiza el estado actual del título (time-based) void setState(TitleState state); // Cambia el estado del título void resetCounter(); // Reinicia el contador interno diff --git a/source/tiled_bg.cpp b/source/tiled_bg.cpp index 596fd92..d5547fd 100644 --- a/source/tiled_bg.cpp +++ b/source/tiled_bg.cpp @@ -161,8 +161,8 @@ void TiledBG::updateStop(float delta_time) { // Desacelerar si estamos cerca de completar el ciclo (ventana a punto de regresar a 0) if (window_.x >= TILE_WIDTH - UMBRAL) { - // Convertir 1.05F por frame a por segundo: (1.05^60) per second - float deceleration_factor = std::pow(1.05F, 60.0F * delta_time); + // Convertir 1.05F por frame a por milisegundo: (1.05^(60*delta_time/1000)) + float deceleration_factor = std::pow(1.05F, 60.0F * delta_time / 1000.0F); speed_ /= deceleration_factor; // Asegura que no baje demasiado diff --git a/source/tiled_bg.h b/source/tiled_bg.h index db7c6b8..c33d5a1 100644 --- a/source/tiled_bg.h +++ b/source/tiled_bg.h @@ -57,7 +57,7 @@ class TiledBG { // --- Métodos internos --- void fillTexture(); // Rellena la textura con el contenido void updateDesp() { desp_ += speed_; } // Actualiza el desplazamiento (frame-based) - void updateDesp(float delta_time) { desp_ += speed_ * 60.0f * delta_time; } // Actualiza el desplazamiento (time-based) + void updateDesp(float delta_time) { desp_ += speed_ * delta_time / (1000.0f / 60.0f); } // Actualiza el desplazamiento (time-based) void updateStop(); // Detiene el desplazamiento de forma ordenada (frame-based) void updateStop(float delta_time); // Detiene el desplazamiento de forma ordenada (time-based) }; \ No newline at end of file