From b558ea0b4c8cb8d36042d6ee4c843244b7249ee8 Mon Sep 17 00:00:00 2001 From: Sergio Valor Date: Tue, 19 May 2026 18:38:57 +0200 Subject: [PATCH] cleanup time-based: elimina base classes frame-based (MovingSprite/SmartSprite/AnimatedSprite/Writer/Fade), MovingSprite::update(dt_s) integra rotacio --- source/core/rendering/animatedsprite.cpp | 42 +------------------ source/core/rendering/animatedsprite.h | 6 +-- source/core/rendering/fade.cpp | 17 ++------ source/core/rendering/fade.h | 3 +- source/core/rendering/movingsprite.cpp | 48 ++++------------------ source/core/rendering/movingsprite.h | 12 ++---- source/core/rendering/smartsprite.cpp | 41 +++---------------- source/core/rendering/smartsprite.h | 12 +++--- source/core/rendering/writer.cpp | 52 ++---------------------- source/core/rendering/writer.h | 21 ++++------ 10 files changed, 44 insertions(+), 210 deletions(-) diff --git a/source/core/rendering/animatedsprite.cpp b/source/core/rendering/animatedsprite.cpp index 37a9a7c..1425e68 100644 --- a/source/core/rendering/animatedsprite.cpp +++ b/source/core/rendering/animatedsprite.cpp @@ -211,39 +211,7 @@ auto AnimatedSprite::getIndex(const std::string &name) -> int { return -1; } -// Calcula el frame correspondiente a la animación -void AnimatedSprite::animate() { - if (!enabled_ || animation_[current_animation_].speed == 0) { - return; - } - - // Calcula el frame actual a partir del contador - animation_[current_animation_].current_frame = animation_[current_animation_].counter / animation_[current_animation_].speed; - - // Si alcanza el final de la animación, reinicia el contador de la animación - // en función de la variable loop y coloca el nuevo frame - if (animation_[current_animation_].current_frame >= (int)animation_[current_animation_].frames.size()) { - if (animation_[current_animation_].loop == -1) { // Si no hay loop, deja el último frame - animation_[current_animation_].current_frame = animation_[current_animation_].frames.size(); - animation_[current_animation_].completed = true; - } else { // Si hay loop, vuelve al frame indicado - animation_[current_animation_].counter = 0; - animation_[current_animation_].current_frame = animation_[current_animation_].loop; - } - } - // En caso contrario - else { - // Escoge el frame correspondiente de la animación - setSpriteClip(animation_[current_animation_].frames[animation_[current_animation_].current_frame]); - - // Incrementa el contador de la animacion - animation_[current_animation_].counter++; - } -} - -// Time-based: avança l'acumulador i calcula el frame actual a partir de -// `step_duration_s`. La lògica de loop/completed és la mateixa que la -// variant frame-based. +// Avança l'acumulador i calcula el frame actual a partir de `step_duration_s`. void AnimatedSprite::animate(float dt_s) { Animation &anim = animation_[current_animation_]; if (!enabled_ || anim.step_duration_s <= 0.0F) { @@ -376,13 +344,7 @@ void AnimatedSprite::setCurrentAnimation(int index) { } } -// Actualiza las variables del objeto -void AnimatedSprite::update() { - animate(); - MovingSprite::update(); -} - -// Time-based: animate(dt) + move(dt) +// animate(dt) + MovingSprite::update(dt) (move + rotació) void AnimatedSprite::update(float dt_s) { animate(dt_s); MovingSprite::update(dt_s); diff --git a/source/core/rendering/animatedsprite.h b/source/core/rendering/animatedsprite.h index b087f8c..eaaf1fa 100644 --- a/source/core/rendering/animatedsprite.h +++ b/source/core/rendering/animatedsprite.h @@ -39,8 +39,7 @@ class AnimatedSprite : public MovingSprite { ~AnimatedSprite() override; // Destructor - void animate(); // Calcula el frame correspondiente a la animación actual (frame-based) - void animate(float dt_s); // Calcula el frame correspondiente a la animación actual (time-based) + void animate(float dt_s); // Calcula el frame correspondiente a la animación actual auto getNumFrames() -> int; // Obtiene el numero de frames de la animación actual void setCurrentFrame(int num); // Establece el frame actual de la animación void setAnimationCounter(const std::string &name, int num); // Establece el valor del contador @@ -65,8 +64,7 @@ class AnimatedSprite : public MovingSprite { void setCurrentAnimation(const std::string &name = "default"); // Establece la animacion actual void setCurrentAnimation(int index = 0); - void update() override; // Actualiza las variables del objeto (frame-based) - void update(float dt_s) override; // Actualiza las variables del objeto (time-based) + void update(float dt_s) override; // Actualiza las variables del objeto void setAnimationFrames(Uint8 index_animation, Uint8 index_frame, int x, int y, int w, int h); // OLD - Establece el rectangulo para un frame de una animación void setAnimationCounter(int value); // OLD - Establece el contador para todas las animaciones diff --git a/source/core/rendering/fade.cpp b/source/core/rendering/fade.cpp index 7d9d665..f0f183f 100644 --- a/source/core/rendering/fade.cpp +++ b/source/core/rendering/fade.cpp @@ -156,19 +156,10 @@ void Fade::renderFadeRandomSquare() { } } -// Actualiza las variables internas -void Fade::update() { - if (enabled_) { - counter_++; - } -} - -// Time-based. Per a no haver de refactoritzar `render()` tot d'un cop -// (encara hi ha codi frame-based que també escriu counter_), aquí derivem -// `counter_` a partir de `elapsed_s_` usant la cadència de referència de la -// versió antiga (60 Hz). Així el comportament visual del fade és idèntic. -// Quan tot el codi sigui time-based, render passarà a usar elapsed_s_ amb -// constants en segons i counter_ desapareixerà. +// Actualiza les variables internes. `counter_` (Uint16, frames a la cadència +// de referència 60Hz) es deriva de `elapsed_s_` perquè els helpers de +// `render()` (renderFadeFullscreen / Center / RandomSquare) segueixin +// llegint-lo igual que abans. void Fade::update(float dt_s) { if (!enabled_) { return; } elapsed_s_ += dt_s; diff --git a/source/core/rendering/fade.h b/source/core/rendering/fade.h index 108b24e..bb4b9d2 100644 --- a/source/core/rendering/fade.h +++ b/source/core/rendering/fade.h @@ -18,8 +18,7 @@ class Fade { void init(Uint8 r, Uint8 g, Uint8 b); // Inicializa las variables void render(); // Pinta una transición en pantalla - void update(); // Actualiza las variables internas (frame-based) - void update(float dt_s); // Actualiza las variables internas (time-based) + void update(float dt_s); // Actualiza las variables internas void activateFade(); // Activa el fade [[nodiscard]] auto hasEnded() const -> bool; // Comprueba si ha terminado la transicion diff --git a/source/core/rendering/movingsprite.cpp b/source/core/rendering/movingsprite.cpp index 6325ef2..a0cfe0a 100644 --- a/source/core/rendering/movingsprite.cpp +++ b/source/core/rendering/movingsprite.cpp @@ -34,26 +34,11 @@ void MovingSprite::clear() { center_ = nullptr; rotate_speed_ = 0; rotate_amount_ = 0.0; - counter_ = 0; current_flip_ = SDL_FLIP_NONE; } -// Mueve el sprite -void MovingSprite::move() { - if (enabled_) { - x_prev_ = x_; - y_prev_ = y_; - - x_ += vx_; - y_ += vy_; - - vx_ += ax_; - vy_ += ay_; - } -} - -// Time-based: vx_/vy_ en px/s, ax_/ay_ en px/s^2. Integració d'Euler +// Mueve el sprite. vx_/vy_ en px/s, ax_/ay_ en px/s². Integració d'Euler // senzilla — suficient per a moviments sense col·lisions sensibles. void MovingSprite::move(float dt_s) { if (enabled_) { @@ -195,17 +180,6 @@ auto MovingSprite::getRotateSpeed() const -> Uint16 { return rotate_speed_; } -// Establece la rotacion -void MovingSprite::rotate() { - if (enabled_) { - if (rotate_enabled_) { - if (counter_ % rotate_speed_ == 0) { - incAngle(rotate_amount_); - } - } - } -} - // Establece el valor de la variable void MovingSprite::setRotate(bool value) { rotate_enabled_ = value; @@ -231,20 +205,16 @@ void MovingSprite::disableRotate() { angle_ = (double)0; } -// Actualiza las variables internas del objeto -void MovingSprite::update() { - move(); - rotate(); - - if (enabled_) { - ++counter_ %= 60000; - } -} - -// Time-based: nomes move(dt). La rotacio time-based s'integrara quan -// migrem la escena que la requereix (Game/PowerBall). +// Actualiza les variables internes (move + rotació integrada). La rotació +// frame-based original era `incAngle(rotate_amount_)` cada `rotate_speed_` +// frames a 60Hz, equivalent a velocitat angular constant +// = rotate_amount_ * 60 / rotate_speed_ graus/s. void MovingSprite::update(float dt_s) { move(dt_s); + if (enabled_ && rotate_enabled_) { + const double ANGULAR_VELOCITY_DEG_PER_S = rotate_amount_ * 60.0 / static_cast(rotate_speed_); + incAngle(ANGULAR_VELOCITY_DEG_PER_S * dt_s); + } } // Cambia el sentido de la rotación diff --git a/source/core/rendering/movingsprite.h b/source/core/rendering/movingsprite.h index 08b96ef..b97d2b4 100644 --- a/source/core/rendering/movingsprite.h +++ b/source/core/rendering/movingsprite.h @@ -10,11 +10,8 @@ class MovingSprite : public Sprite { public: explicit MovingSprite(float x = 0, float y = 0, int w = 0, int h = 0, float velx = 0, float vely = 0, float accelx = 0, float accely = 0, Texture *texture = nullptr, SDL_Renderer *renderer = nullptr); // Constructor - void move(); // Mueve el sprite (frame-based, depreca) - void move(float dt_s); // Mueve el sprite (time-based: vx/vy/ax/ay en px/s i px/s^2) - void rotate(); // Rota el sprite (frame-based, depreca) - virtual void update(); // Actualiza las variables internas del objeto (frame-based) - virtual void update(float dt_s); // Actualiza les variables internes (time-based, només move; rotate per migrar al seu torn) + void move(float dt_s); // Mueve el sprite (vx/vy/ax/ay en px/s i px/s^2) + virtual void update(float dt_s); // Actualiza les variables internes (move + rotació integrada) void clear(); // Reinicia todas las variables void render() override; // Muestra el sprite por pantalla @@ -85,9 +82,8 @@ class MovingSprite : public Sprite { double angle_{0.0}; // Angulo para dibujarlo bool rotate_enabled_{false}; // Indica si ha de rotar - int rotate_speed_{0}; // Velocidad de giro - double rotate_amount_{0.0}; // Cantidad de grados a girar en cada iteración - int counter_{0}; // Contador interno + int rotate_speed_{0}; // Velocidad de giro (frames per pas de rotació al ritme de referència 60Hz) + double rotate_amount_{0.0}; // Cantidad de grados a girar en cada pas SDL_Point *center_{nullptr}; // Centro de rotación SDL_FlipMode current_flip_{SDL_FLIP_NONE}; // Indica como se voltea el sprite }; diff --git a/source/core/rendering/smartsprite.cpp b/source/core/rendering/smartsprite.cpp index fb969b6..84ae5f2 100644 --- a/source/core/rendering/smartsprite.cpp +++ b/source/core/rendering/smartsprite.cpp @@ -20,33 +20,18 @@ void SmartSprite::init() { on_destination_ = false; dest_x_ = 0; dest_y_ = 0; - counter_ = 0; finished_ = false; } -// Actualiza la posición y comprueba si ha llegado a su destino -void SmartSprite::update() { - if (enabled_) { - // NOLINTNEXTLINE(bugprone-parent-virtual-call): salt deliberat a l'avi — SmartSprite hereta d'AnimatedSprite només per reutilitzar API, però no usa animació de frames, així que es salta AnimatedSprite::update() (que cridaria animate()) - MovingSprite::update(); - - // Comprueba el movimiento - checkMove(); - - // Comprueba si ha terminado - checkFinished(); - } -} - -// Time-based: la velocitat i acceleració són en px/s i px/s^2; el temps de -// permanència després d'arribar al destí ve donat per setRemainingTime(). +// La velocitat i acceleració són en px/s i px/s²; el temps de permanència +// després d'arribar al destí ve donat per setRemainingTime(). void SmartSprite::update(float dt_s) { if (enabled_) { - // NOLINTNEXTLINE(bugprone-parent-virtual-call): vegeu update() per al motiu del salt + // NOLINTNEXTLINE(bugprone-parent-virtual-call): salt deliberat a l'avi — SmartSprite hereta d'AnimatedSprite només per reutilitzar API, però no usa animació de frames, així que es salta AnimatedSprite::update() (que cridaria animate()) MovingSprite::update(dt_s); checkMove(); - checkFinishedTimeBased(dt_s); + checkFinished(dt_s); } } @@ -150,22 +135,8 @@ void SmartSprite::checkMove() { } } -// Comprueba si ha terminado -void SmartSprite::checkFinished() { - // Comprueba si ha llegado a su destino - on_destination_ = getPosX() == dest_x_ && getPosY() == dest_y_; - - if (on_destination_) { // Si esta en el destino comprueba su contador - if (enabled_counter_ == 0) { // Si ha llegado a cero, deshabilita el objeto y lo marca como finalizado - finished_ = true; - } else { // Si no ha llegado a cero, decrementa el contador - enabled_counter_--; - } - } -} - -// Time-based: decrementa el temps restant cada crida si està al destí -void SmartSprite::checkFinishedTimeBased(float dt_s) { +// Decrementa el temps restant cada crida si està al destí +void SmartSprite::checkFinished(float dt_s) { on_destination_ = getPosX() == dest_x_ && getPosY() == dest_y_; if (on_destination_) { diff --git a/source/core/rendering/smartsprite.h b/source/core/rendering/smartsprite.h index 01286cd..8179bb3 100644 --- a/source/core/rendering/smartsprite.h +++ b/source/core/rendering/smartsprite.h @@ -11,8 +11,7 @@ class SmartSprite : public AnimatedSprite { SmartSprite(Texture *texture, SDL_Renderer *renderer); // Constructor void init(); // Inicializa el objeto - void update() override; // Actualiza la posicion (frame-based) - void update(float dt_s) override; // Actualiza la posicion (time-based) + void update(float dt_s) override; // Actualiza la posicion void render() override; // Pinta el objeto en pantalla [[nodiscard]] auto getEnabledCounter() const -> int; // Obtiene el valor de la variable @@ -31,11 +30,10 @@ class SmartSprite : public AnimatedSprite { bool on_destination_; // Indica si está en el destino int dest_x_; // Posicion de destino en el eje X int dest_y_; // Posicion de destino en el eje Y - int enabled_counter_; // Contador per a deshabilitar-lo (frame-based) - float remaining_time_s_{0.0F}; // Temps restant per a deshabilitar-lo (time-based) + int enabled_counter_; // Contador (frames, derivat de remaining_time_s_ * 60) + float remaining_time_s_{0.0F}; // Temps restant per a deshabilitar-lo bool finished_; // Indica si ya ha terminado - void checkMove(); // Comprueba el movimiento - void checkFinished(); // Comprueba si ha terminado (frame-based) - void checkFinishedTimeBased(float dt_s); // Comprueba si ha terminado (time-based) + void checkMove(); // Comprueba el movimiento + void checkFinished(float dt_s); // Comprueba si ha terminado }; diff --git a/source/core/rendering/writer.cpp b/source/core/rendering/writer.cpp index 28fd2e7..a16a8a6 100644 --- a/source/core/rendering/writer.cpp +++ b/source/core/rendering/writer.cpp @@ -7,36 +7,8 @@ Writer::Writer(Text *text) : text_(text) { } -// Actualiza el objeto -void Writer::update() { - if (enabled_) { - if (!completed_) { // No completado - if (writing_counter_ > 0) { - writing_counter_--; - } - - else if (writing_counter_ == 0) { - index_++; - writing_counter_ = speed_; - } - - if (index_ == length_) { - completed_ = true; - } - } - - if (completed_) { // Completado - if (enabled_counter_ > 0) { - enabled_counter_--; - } else if (enabled_counter_ == 0) { - finished_ = true; - } - } - } -} - -// Time-based: avanca un caracter cada `seconds_per_char_` i un cop completat -// es queda visible `remaining_time_s_` segons abans de finalitzar. +// Avança un caracter cada `seconds_per_char_` i un cop completat es queda +// visible `remaining_time_s_` segons abans de finalitzar. void Writer::update(float dt_s) { if (!enabled_) { return; } @@ -88,13 +60,7 @@ void Writer::setCaption(const std::string &text) { length_ = text.length(); } -// Establece el valor de la variable -void Writer::setSpeed(int value) { - speed_ = value; - writing_counter_ = value; -} - -// Time-based: segons per caracter. Quan s'usa, l'update(dt) avança index. +// Segons per caracter. Quan s'usa, l'update(dt) avança index. void Writer::setSecondsPerChar(float seconds) { seconds_per_char_ = seconds; char_timer_s_ = 0.0F; @@ -110,17 +76,7 @@ auto Writer::isEnabled() const -> bool { return enabled_; } -// Establece el valor de la variable -void Writer::setEnabledCounter(int time) { - enabled_counter_ = time; -} - -// Obtiene el valor de la variable -auto Writer::getEnabledCounter() const -> int { - return enabled_counter_; -} - -// Time-based: temps que es mante visible despres de completar el text. +// Temps que es mante visible despres de completar el text. void Writer::setRemainingTime(float seconds) { remaining_time_s_ = seconds; } diff --git a/source/core/rendering/writer.h b/source/core/rendering/writer.h index 8da0400..dda5bc8 100644 --- a/source/core/rendering/writer.h +++ b/source/core/rendering/writer.h @@ -8,23 +8,19 @@ class Writer { public: explicit Writer(Text *text); // Constructor - void update(); // Actualiza el objeto (frame-based) - void update(float dt_s); // Actualiza el objeto (time-based) + void update(float dt_s); // Actualiza el objeto void render(); // Dibuja el objeto en pantalla void setPosX(int value); // Establece el valor de la variable void setPosY(int value); // Establece el valor de la variable void setKerning(int value); // Establece el valor de la variable void setCaption(const std::string &text); // Establece el valor de la variable - void setSpeed(int value); // Establece el valor de la variable (frame-based: frames per caracter) - void setSecondsPerChar(float seconds); // Time-based: segons per caracter + void setSecondsPerChar(float seconds); // Segons per caracter void setEnabled(bool value); // Establece el valor de la variable [[nodiscard]] auto isEnabled() const -> bool; // Obtiene el valor de la variable - void setEnabledCounter(int time); // Establece el valor de la variable (frame-based) - [[nodiscard]] auto getEnabledCounter() const -> int; // Obtiene el valor de la variable - void setRemainingTime(float seconds); // Time-based: temps despres de completar - [[nodiscard]] auto getRemainingTime() const -> float; // Time-based: temps restant + void setRemainingTime(float seconds); // Temps despres de completar + [[nodiscard]] auto getRemainingTime() const -> float; // Temps restant void center(int x); // Centra la cadena de texto a un punto X [[nodiscard]] auto hasFinished() const -> bool; // Obtiene el valor de la variable @@ -38,15 +34,12 @@ class Writer { int pos_y_{0}; // Posicion en el eje Y donde empezar a escribir el texto int kerning_{0}; // Kerning del texto, es decir, espaciado entre caracteres std::string caption_; // El texto para escribir - int speed_{0}; // Velocidad d'escriptura (frame-based: frames per caracter) - int writing_counter_{0}; // Temporizador d'escriptura per cada caracter (frame-based) - float seconds_per_char_{0.0F}; // Time-based: segons per caracter - float char_timer_s_{0.0F}; // Time-based: acumulador d'avanç de caracter + float seconds_per_char_{0.0F}; // Segons per caracter + float char_timer_s_{0.0F}; // Acumulador d'avanç de caracter int index_{0}; // Posición del texto que se está escribiendo int length_{0}; // Longitud de la cadena a escribir bool completed_{false}; // Indica si se ha escrito todo el texto bool enabled_{false}; // Indica si el objeto está habilitado - int enabled_counter_{0}; // Temporizador per a deshabilitar el objecte (frame-based) - float remaining_time_s_{0.0F}; // Temps restant per a deshabilitar (time-based) + float remaining_time_s_{0.0F}; // Temps restant per a deshabilitar bool finished_{false}; // Indica si ya ha terminado };