time-based: migrada escena Intro (dual-API a MovingSprite/SmartSprite/Writer, constants a 60Hz)

This commit is contained in:
2026-05-18 22:46:41 +02:00
parent f1a6636222
commit 2b57bfa4dd
8 changed files with 218 additions and 90 deletions
+21
View File
@@ -53,6 +53,21 @@ void MovingSprite::move() {
}
}
// Time-based: vx_/vy_ en px/s, ax_/ay_ en px/s^2. Integració d'Euler
// senzilla — suficient per a moviments sense col·lisions sensibles.
void MovingSprite::move(float dt_s) {
if (enabled_) {
x_prev_ = x_;
y_prev_ = y_;
x_ += vx_ * dt_s;
y_ += vy_ * dt_s;
vx_ += ax_ * dt_s;
vy_ += ay_ * dt_s;
}
}
// Muestra el sprite por pantalla
void MovingSprite::render() {
if (enabled_) {
@@ -226,6 +241,12 @@ void MovingSprite::update() {
}
}
// Time-based: nomes move(dt). La rotacio time-based s'integrara quan
// migrem la escena que la requereix (Game/PowerBall).
void MovingSprite::update(float dt_s) {
move(dt_s);
}
// Cambia el sentido de la rotación
void MovingSprite::switchRotate() {
rotate_amount_ *= -1;
+7 -5
View File
@@ -10,11 +10,13 @@ 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
void rotate(); // Rota el sprite
virtual void update(); // Actualiza las variables internas del objeto
void clear(); // Reinicia todas las variables
void render() override; // Muestra el sprite por pantalla
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 clear(); // Reinicia todas las variables
void render() override; // Muestra el sprite por pantalla
// cppcheck-suppress duplInheritedMember ; shadow intencional: Sprite::getPosX retorna int (sprites estàtics), MovingSprite::getPosX retorna float (sub-pixel). No s'accedeix via Sprite*: la jerarquia de joc treballa amb el tipus concret
[[nodiscard]] auto getPosX() const -> float; // Obten el valor de la variable
+34
View File
@@ -38,6 +38,18 @@ void SmartSprite::update() {
}
}
// 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().
void SmartSprite::update(float dt_s) {
if (enabled_) {
// NOLINTNEXTLINE(bugprone-parent-virtual-call): vegeu update() per al motiu del salt
MovingSprite::update(dt_s);
checkMove();
checkFinishedTimeBased(dt_s);
}
}
// Pinta el objeto en pantalla
void SmartSprite::render() {
if (enabled_) {
@@ -56,6 +68,15 @@ void SmartSprite::setEnabledCounter(int value) {
enabled_counter_ = value;
}
// Time-based: temps de visibilitat post-arribada
void SmartSprite::setRemainingTime(float seconds) {
remaining_time_s_ = seconds;
}
auto SmartSprite::getRemainingTime() const -> float {
return remaining_time_s_;
}
// Establece el valor de la variable
void SmartSprite::setDestX(int x) {
dest_x_ = x;
@@ -143,6 +164,19 @@ void SmartSprite::checkFinished() {
}
}
// Time-based: decrementa el temps restant cada crida si està al destí
void SmartSprite::checkFinishedTimeBased(float dt_s) {
on_destination_ = getPosX() == dest_x_ && getPosY() == dest_y_;
if (on_destination_) {
if (remaining_time_s_ <= 0.0F) {
finished_ = true;
} else {
remaining_time_s_ -= dt_s;
}
}
}
// Obtiene el valor de la variable
auto SmartSprite::isOnDestination() const -> bool {
return on_destination_;
+23 -18
View File
@@ -10,27 +10,32 @@ class SmartSprite : public AnimatedSprite {
public:
SmartSprite(Texture *texture, SDL_Renderer *renderer); // Constructor
void init(); // Inicializa el objeto
void update() override; // Actualiza la posición y comprueba si ha llegado a su destino
void render() override; // Pinta el objeto en pantalla
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 render() override; // Pinta el objeto en pantalla
[[nodiscard]] auto getEnabledCounter() const -> int; // Obtiene el valor de la variable
void setEnabledCounter(int value); // Establece el valor de la variable
void setDestX(int x); // Establece el valor de la variable
void setDestY(int y); // Establece el valor de la variable
[[nodiscard]] auto getDestX() const -> int; // Obtiene el valor de la variable
[[nodiscard]] auto getDestY() const -> int; // Obtiene el valor de la variable
[[nodiscard]] auto isOnDestination() const -> bool; // Obtiene el valor de la variable
[[nodiscard]] auto hasFinished() const -> bool; // Obtiene el valor de la variable
[[nodiscard]] auto getEnabledCounter() const -> int; // Obtiene el valor de la variable
void setEnabledCounter(int value); // Establece el valor de la variable
void setRemainingTime(float seconds); // Time-based: temps que es queda visible despres d'arribar al desti
[[nodiscard]] auto getRemainingTime() const -> float; // Time-based: temps restant
void setDestX(int x); // Establece el valor de la variable
void setDestY(int y); // Establece el valor de la variable
[[nodiscard]] auto getDestX() const -> int; // Obtiene el valor de la variable
[[nodiscard]] auto getDestY() const -> int; // Obtiene el valor de la variable
[[nodiscard]] auto isOnDestination() const -> bool; // Obtiene el valor de la variable
[[nodiscard]] auto hasFinished() const -> bool; // Obtiene el valor de la variable
private:
// Variables
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 para deshabilitarlo
bool finished_; // Indica si ya ha terminado
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)
bool finished_; // Indica si ya ha terminado
void checkMove(); // Comprueba el movimiento
void checkFinished(); // Comprueba si 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)
};
+40
View File
@@ -35,6 +35,31 @@ void Writer::update() {
}
}
// Time-based: avanca 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; }
if (!completed_) {
char_timer_s_ += dt_s;
while (char_timer_s_ >= seconds_per_char_ && index_ < length_) {
char_timer_s_ -= seconds_per_char_;
++index_;
}
if (index_ >= length_) {
completed_ = true;
}
}
if (completed_) {
if (remaining_time_s_ <= 0.0F) {
finished_ = true;
} else {
remaining_time_s_ -= dt_s;
}
}
}
// Dibuja el objeto en pantalla
void Writer::render() {
if (enabled_) {
@@ -69,6 +94,12 @@ void Writer::setSpeed(int value) {
writing_counter_ = value;
}
// Time-based: 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;
}
// Establece el valor de la variable
void Writer::setEnabled(bool value) {
enabled_ = value;
@@ -89,6 +120,15 @@ auto Writer::getEnabledCounter() const -> int {
return enabled_counter_;
}
// Time-based: temps que es mante visible despres de completar el text.
void Writer::setRemainingTime(float seconds) {
remaining_time_s_ = seconds;
}
auto Writer::getRemainingTime() const -> float {
return remaining_time_s_;
}
// Centra la cadena de texto a un punto X
void Writer::center(int x) {
setPosX(x - (text_->lenght(caption_, kerning_) / 2));
+24 -17
View File
@@ -8,19 +8,23 @@ class Writer {
public:
explicit Writer(Text *text); // Constructor
void update(); // Actualiza el objeto
void render(); // Dibuja el objeto en pantalla
void update(); // Actualiza el objeto (frame-based)
void update(float dt_s); // Actualiza el objeto (time-based)
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
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 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
[[nodiscard]] auto getEnabledCounter() const -> int; // 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 center(int x); // Centra la cadena de texto a un punto X
[[nodiscard]] auto hasFinished() const -> bool; // Obtiene el valor de la variable
@@ -30,16 +34,19 @@ class Writer {
Text *text_; // Objeto encargado de escribir el texto
// Variables
int pos_x_{0}; // Posicion en el eje X donde empezar a escribir el texto
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 de escritura
int writing_counter_{0}; // 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
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 para deshabilitar el objeto
bool finished_{false}; // Indica si ya ha terminado
int pos_x_{0}; // Posicion en el eje X donde empezar a escribir el texto
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
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)
bool finished_{false}; // Indica si ya ha terminado
};