delta-time: game_logo.cpp

delta-time: smart_sprite.cpp
This commit is contained in:
2025-09-16 17:19:05 +02:00
parent 3d9ffe356e
commit dfa66b0e95
5 changed files with 188 additions and 29 deletions

1
.gitignore vendored
View File

@@ -1,4 +1,5 @@
.vscode .vscode
.claude
build/ build/
data/config/config.txt data/config/config.txt
*.DS_Store *.DS_Store

View File

@@ -45,6 +45,7 @@ void GameLogo::init() {
arcade_edition_status_ = Status::DISABLED; arcade_edition_status_ = Status::DISABLED;
shake_.init(1, 2, 8, XP); shake_.init(1, 2, 8, XP);
zoom_ = 3.0F * ZOOM_FACTOR; zoom_ = 3.0F * ZOOM_FACTOR;
post_finished_time_accumulator_ = 0.0f;
// Inicializa el bitmap de 'Coffee' // Inicializa el bitmap de 'Coffee'
coffee_sprite_->setPosX(XP); coffee_sprite_->setPosX(XP);
@@ -112,13 +113,20 @@ void GameLogo::render() {
} }
} }
// Actualiza la lógica de la clase // Actualiza la lógica de la clase (frame-based)
void GameLogo::update() { void GameLogo::update() {
updateCoffeeCrisis(); updateCoffeeCrisis();
updateArcadeEdition(); updateArcadeEdition();
updatePostFinishedCounter(); updatePostFinishedCounter();
} }
// Actualiza la lógica de la clase (time-based)
void GameLogo::update(float deltaTime) {
updateCoffeeCrisis(deltaTime);
updateArcadeEdition(deltaTime);
updatePostFinishedCounter(deltaTime);
}
void GameLogo::updateCoffeeCrisis() { void GameLogo::updateCoffeeCrisis() {
switch (coffee_crisis_status_) { switch (coffee_crisis_status_) {
case Status::MOVING: case Status::MOVING:
@@ -135,6 +143,22 @@ void GameLogo::updateCoffeeCrisis() {
} }
} }
void GameLogo::updateCoffeeCrisis(float deltaTime) {
switch (coffee_crisis_status_) {
case Status::MOVING:
handleCoffeeCrisisMoving(deltaTime);
break;
case Status::SHAKING:
handleCoffeeCrisisShaking(deltaTime);
break;
case Status::FINISHED:
handleCoffeeCrisisFinished(deltaTime);
break;
default:
break;
}
}
void GameLogo::updateArcadeEdition() { void GameLogo::updateArcadeEdition() {
switch (arcade_edition_status_) { switch (arcade_edition_status_) {
case Status::MOVING: case Status::MOVING:
@@ -148,6 +172,19 @@ void GameLogo::updateArcadeEdition() {
} }
} }
void GameLogo::updateArcadeEdition(float deltaTime) {
switch (arcade_edition_status_) {
case Status::MOVING:
handleArcadeEditionMoving(deltaTime);
break;
case Status::SHAKING:
handleArcadeEditionShaking(deltaTime);
break;
default:
break;
}
}
void GameLogo::handleCoffeeCrisisMoving() { void GameLogo::handleCoffeeCrisisMoving() {
coffee_sprite_->update(); coffee_sprite_->update();
crisis_sprite_->update(); crisis_sprite_->update();
@@ -158,6 +195,16 @@ void GameLogo::handleCoffeeCrisisMoving() {
} }
} }
void GameLogo::handleCoffeeCrisisMoving(float deltaTime) {
coffee_sprite_->update(deltaTime);
crisis_sprite_->update(deltaTime);
if (coffee_sprite_->hasFinished() && crisis_sprite_->hasFinished()) {
coffee_crisis_status_ = Status::SHAKING;
playTitleEffects();
}
}
void GameLogo::handleCoffeeCrisisShaking() { void GameLogo::handleCoffeeCrisisShaking() {
if (shake_.remaining > 0) { if (shake_.remaining > 0) {
processShakeEffect(coffee_sprite_.get(), crisis_sprite_.get()); processShakeEffect(coffee_sprite_.get(), crisis_sprite_.get());
@@ -168,10 +215,24 @@ void GameLogo::handleCoffeeCrisisShaking() {
updateDustSprites(); updateDustSprites();
} }
void GameLogo::handleCoffeeCrisisShaking(float deltaTime) {
if (shake_.remaining > 0) {
processShakeEffect(coffee_sprite_.get(), crisis_sprite_.get(), deltaTime);
} else {
finishCoffeeCrisisShaking();
}
updateDustSprites(deltaTime);
}
void GameLogo::handleCoffeeCrisisFinished() { void GameLogo::handleCoffeeCrisisFinished() {
updateDustSprites(); updateDustSprites();
} }
void GameLogo::handleCoffeeCrisisFinished(float deltaTime) {
updateDustSprites(deltaTime);
}
void GameLogo::handleArcadeEditionMoving() { void GameLogo::handleArcadeEditionMoving() {
zoom_ -= 0.1F * ZOOM_FACTOR; zoom_ -= 0.1F * ZOOM_FACTOR;
arcade_edition_sprite_->setZoom(zoom_); arcade_edition_sprite_->setZoom(zoom_);
@@ -181,6 +242,16 @@ 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;
arcade_edition_sprite_->setZoom(zoom_);
if (zoom_ <= 1.0F) {
finishArcadeEditionMoving();
}
}
void GameLogo::handleArcadeEditionShaking() { void GameLogo::handleArcadeEditionShaking() {
if (shake_.remaining > 0) { if (shake_.remaining > 0) {
processArcadeEditionShake(); processArcadeEditionShake();
@@ -190,6 +261,15 @@ void GameLogo::handleArcadeEditionShaking() {
} }
} }
void GameLogo::handleArcadeEditionShaking(float deltaTime) {
if (shake_.remaining > 0) {
processArcadeEditionShake(deltaTime);
} else {
arcade_edition_sprite_->setX(shake_.origin);
arcade_edition_status_ = Status::FINISHED;
}
}
void GameLogo::processShakeEffect(SmartSprite* primary_sprite, SmartSprite* secondary_sprite) { void GameLogo::processShakeEffect(SmartSprite* primary_sprite, SmartSprite* secondary_sprite) {
if (shake_.counter > 0) { if (shake_.counter > 0) {
shake_.counter--; shake_.counter--;
@@ -204,6 +284,23 @@ 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<float>(shake_.delay) / 60.0f;
shake_.time_accumulator += deltaTime;
if (shake_.time_accumulator >= delayTime) {
shake_.time_accumulator -= delayTime;
const auto DISPLACEMENT = calculateShakeDisplacement();
primary_sprite->setPosX(shake_.origin + DISPLACEMENT);
if (secondary_sprite != nullptr) {
secondary_sprite->setPosX(shake_.origin + DISPLACEMENT + 15);
}
shake_.remaining--;
}
}
void GameLogo::processArcadeEditionShake() { void GameLogo::processArcadeEditionShake() {
if (shake_.counter > 0) { if (shake_.counter > 0) {
shake_.counter--; shake_.counter--;
@@ -215,6 +312,20 @@ void GameLogo::processArcadeEditionShake() {
} }
} }
void GameLogo::processArcadeEditionShake(float deltaTime) {
// Convertir delay (frames) a tiempo: delay frames = delay/60 segundos a 60fps
float delayTime = static_cast<float>(shake_.delay) / 60.0f;
shake_.time_accumulator += deltaTime;
if (shake_.time_accumulator >= delayTime) {
shake_.time_accumulator -= delayTime;
const auto DISPLACEMENT = calculateShakeDisplacement();
arcade_edition_sprite_->setX(shake_.origin + DISPLACEMENT);
shake_.remaining--;
}
}
auto GameLogo::calculateShakeDisplacement() const -> int { auto GameLogo::calculateShakeDisplacement() const -> int {
return shake_.remaining % 2 == 0 ? shake_.desp * (-1) : shake_.desp; return shake_.remaining % 2 == 0 ? shake_.desp * (-1) : shake_.desp;
} }
@@ -245,6 +356,11 @@ void GameLogo::updateDustSprites() {
dust_left_sprite_->update(); dust_left_sprite_->update();
} }
void GameLogo::updateDustSprites(float deltaTime) {
dust_right_sprite_->update(deltaTime);
dust_left_sprite_->update(deltaTime);
}
void GameLogo::updatePostFinishedCounter() { void GameLogo::updatePostFinishedCounter() {
if (coffee_crisis_status_ == Status::FINISHED && if (coffee_crisis_status_ == Status::FINISHED &&
arcade_edition_status_ == Status::FINISHED && arcade_edition_status_ == Status::FINISHED &&
@@ -253,6 +369,23 @@ void GameLogo::updatePostFinishedCounter() {
} }
} }
void GameLogo::updatePostFinishedCounter(float deltaTime) {
if (coffee_crisis_status_ == Status::FINISHED &&
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;
post_finished_time_accumulator_ += deltaTime;
if (post_finished_time_accumulator_ >= frameTime) {
post_finished_time_accumulator_ -= frameTime;
--post_finished_counter_;
}
}
}
// Activa la clase // Activa la clase
void GameLogo::enable() { void GameLogo::enable() {
init(); init();

View File

@@ -16,9 +16,10 @@ class GameLogo {
~GameLogo() = default; ~GameLogo() = default;
// --- Métodos principales --- // --- Métodos principales ---
void render(); // Pinta la clase en pantalla void render(); // Pinta la clase en pantalla
void update(); // Actualiza la lógica de la clase void update(); // Actualiza la lógica de la clase (frame-based)
void enable(); // Activa la clase void update(float deltaTime); // Actualiza la lógica de la clase (time-based)
void enable(); // Activa la clase
// --- Getters --- // --- Getters ---
[[nodiscard]] auto hasFinished() const -> bool; // Indica si ha terminado la animación [[nodiscard]] auto hasFinished() const -> bool; // Indica si ha terminado la animación
@@ -34,12 +35,13 @@ class GameLogo {
// --- Estructuras privadas --- // --- Estructuras privadas ---
struct Shake { struct Shake {
int desp = 1; // Pixels de desplazamiento para agitar la pantalla en el eje x int desp = 1; // Pixels de desplazamiento para agitar la pantalla en el eje x
int delay = 2; // Retraso entre cada desplazamiento de la pantalla al agitarse int delay = 2; // Retraso entre cada desplazamiento de la pantalla al agitarse (frame-based)
int length = 8; // Cantidad de desplazamientos a realizar int length = 8; // Cantidad de desplazamientos a realizar
int remaining = length; // Cantidad de desplazamientos pendientes a realizar int remaining = length; // Cantidad de desplazamientos pendientes a realizar
int counter = delay; // Contador para el retraso int counter = delay; // Contador para el retraso (frame-based)
int origin = 0; // Valor inicial de la pantalla para dejarla igual tras el desplazamiento 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; Shake() = default;
Shake(int d, int de, int l, int o) Shake(int d, int de, int l, int o)
@@ -56,6 +58,7 @@ class GameLogo {
length = l; length = l;
remaining = l; remaining = l;
counter = de; counter = de;
time_accumulator = 0.0f;
origin = o; origin = o;
} }
}; };
@@ -79,32 +82,44 @@ class GameLogo {
float x_; // Posición X del logo float x_; // Posición X del logo
float y_; // Posición Y del logo float y_; // Posición Y del logo
float zoom_ = 1.0F; // Zoom aplicado al texto "ARCADE EDITION" float zoom_ = 1.0F; // Zoom aplicado al texto "ARCADE EDITION"
int post_finished_counter_ = 1; // Contador final tras animaciones int post_finished_counter_ = 1; // Contador final tras animaciones (frame-based)
float post_finished_time_accumulator_ = 0.0f; // Acumulador de tiempo para post_finished_counter
// --- Inicialización --- // --- Inicialización ---
void init(); // Inicializa las variables void init(); // Inicializa las variables
[[nodiscard]] auto getInitialVerticalDesp() const -> int; // Calcula el desplazamiento vertical inicial [[nodiscard]] auto getInitialVerticalDesp() const -> int; // Calcula el desplazamiento vertical inicial
// --- Actualización de estados específicos --- // --- Actualización de estados específicos ---
void updateCoffeeCrisis(); // Actualiza el estado de "Coffee Crisis" void updateCoffeeCrisis(); // Actualiza el estado de "Coffee Crisis" (frame-based)
void updateArcadeEdition(); // Actualiza el estado de "Arcade Edition" void updateCoffeeCrisis(float deltaTime); // Actualiza el estado de "Coffee Crisis" (time-based)
void updatePostFinishedCounter(); // Actualiza el contador tras finalizar una animación void updateArcadeEdition(); // Actualiza el estado de "Arcade Edition" (frame-based)
void updateArcadeEdition(float deltaTime); // Actualiza el estado de "Arcade Edition" (time-based)
void updatePostFinishedCounter(); // Actualiza el contador tras finalizar una animación (frame-based)
void updatePostFinishedCounter(float deltaTime); // Actualiza el contador tras finalizar una animación (time-based)
// --- Efectos visuales: movimiento y sacudidas --- // --- Efectos visuales: movimiento y sacudidas ---
void handleCoffeeCrisisMoving(); // Maneja el movimiento de "Coffee Crisis" void handleCoffeeCrisisMoving(); // Maneja el movimiento de "Coffee Crisis" (frame-based)
void handleCoffeeCrisisShaking(); // Maneja la sacudida de "Coffee Crisis" void handleCoffeeCrisisMoving(float deltaTime); // Maneja el movimiento de "Coffee Crisis" (time-based)
void handleArcadeEditionMoving(); // Maneja el movimiento de "Arcade Edition" void handleCoffeeCrisisShaking(); // Maneja la sacudida de "Coffee Crisis" (frame-based)
void handleArcadeEditionShaking(); // Maneja la sacudida de "Arcade Edition" void handleCoffeeCrisisShaking(float deltaTime); // Maneja la sacudida de "Coffee Crisis" (time-based)
void processShakeEffect(SmartSprite* primary_sprite, SmartSprite* secondary_sprite = nullptr); // Procesa el efecto de sacudida en sprites void handleArcadeEditionMoving(); // Maneja el movimiento de "Arcade Edition" (frame-based)
void processArcadeEditionShake(); // Procesa la sacudida específica de "Arcade Edition" void handleArcadeEditionMoving(float deltaTime); // Maneja el movimiento de "Arcade Edition" (time-based)
[[nodiscard]] auto calculateShakeDisplacement() const -> int; // Calcula el desplazamiento de la sacudida void handleArcadeEditionShaking(); // Maneja la sacudida de "Arcade Edition" (frame-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(); // Procesa la sacudida específica de "Arcade Edition" (frame-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
// --- Gestión de finalización de efectos --- // --- Gestión de finalización de efectos ---
void handleCoffeeCrisisFinished(); // Maneja el final de la animación "Coffee Crisis" void handleCoffeeCrisisFinished(); // Maneja el final de la animación "Coffee Crisis" (frame-based)
void finishCoffeeCrisisShaking(); // Finaliza la sacudida de "Coffee Crisis" void handleCoffeeCrisisFinished(float deltaTime); // Maneja el final de la animación "Coffee Crisis" (time-based)
void finishArcadeEditionMoving(); // Finaliza el movimiento de "Arcade Edition" void finishCoffeeCrisisShaking(); // Finaliza la sacudida de "Coffee Crisis"
void finishArcadeEditionMoving(); // Finaliza el movimiento de "Arcade Edition"
// --- Utilidades --- // --- Utilidades ---
static void playTitleEffects(); // Reproduce efectos visuales/sonoros del título static void playTitleEffects(); // Reproduce efectos visuales/sonoros del título
void updateDustSprites(); // Actualiza los sprites de polvo void updateDustSprites(); // Actualiza los sprites de polvo (frame-based)
void updateDustSprites(float deltaTime); // Actualiza los sprites de polvo (time-based)
}; };

View File

@@ -2,7 +2,7 @@
#include "moving_sprite.h" // Para MovingSprite #include "moving_sprite.h" // Para MovingSprite
// Actualiza la posición y comprueba si ha llegado a su destino // Actualiza la posición y comprueba si ha llegado a su destino (frame-based)
void SmartSprite::update() { void SmartSprite::update() {
if (enabled_) { if (enabled_) {
MovingSprite::update(); MovingSprite::update();
@@ -11,6 +11,15 @@ void SmartSprite::update() {
} }
} }
// Actualiza la posición y comprueba si ha llegado a su destino (time-based)
void SmartSprite::update(float deltaTime) {
if (enabled_) {
MovingSprite::update(deltaTime);
checkMove();
checkFinished();
}
}
// Dibuja el sprite // Dibuja el sprite
void SmartSprite::render() { void SmartSprite::render() {
if (enabled_) { if (enabled_) {

View File

@@ -16,8 +16,9 @@ class SmartSprite : public AnimatedSprite {
~SmartSprite() override = default; ~SmartSprite() override = default;
// --- Métodos principales --- // --- Métodos principales ---
void update() override; // Actualiza la posición y comprueba si ha llegado a su destino void update() override; // Actualiza la posición y comprueba si ha llegado a su destino (frame-based)
void render() override; // Dibuja el sprite 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
// --- Getters --- // --- Getters ---
auto getDestX() const -> int { return dest_x_; } // Obtiene la posición de destino en X auto getDestX() const -> int { return dest_x_; } // Obtiene la posición de destino en X