migrades les clases Sprite a time based

This commit is contained in:
2025-10-28 09:48:58 +01:00
parent 70b76edcbf
commit da65777a5b
6 changed files with 141 additions and 20 deletions

View File

@@ -63,20 +63,72 @@ auto SurfaceAnimatedSprite::getIndex(const std::string& name) -> int {
return -1;
}
// Calcula el frame correspondiente a la animación
void SurfaceAnimatedSprite::animate() {
if (animations_[current_animation_].speed == 0) {
// Calcula el frame correspondiente a la animación (time-based)
void SurfaceAnimatedSprite::animate(float delta_time) {
if (animations_[current_animation_].speed <= 0.0F) {
return;
}
// Calcula el frame actual a partir del contador
animations_[current_animation_].current_frame = animations_[current_animation_].counter / animations_[current_animation_].speed;
// Acumula el tiempo transcurrido
animations_[current_animation_].accumulated_time += delta_time;
// Calcula el frame actual a partir del tiempo acumulado
const int TARGET_FRAME = static_cast<int>(
animations_[current_animation_].accumulated_time /
animations_[current_animation_].speed
);
// Si alcanza el final de la animación, maneja el loop
if (TARGET_FRAME >= static_cast<int>(animations_[current_animation_].frames.size())) {
if (animations_[current_animation_].loop == -1) {
// Si no hay loop, congela en el último frame
animations_[current_animation_].current_frame =
static_cast<int>(animations_[current_animation_].frames.size()) - 1;
animations_[current_animation_].completed = true;
// Establece el clip del último frame
if (animations_[current_animation_].current_frame >= 0) {
setClip(animations_[current_animation_].frames[animations_[current_animation_].current_frame]);
}
} else {
// Si hay loop, vuelve al frame indicado
animations_[current_animation_].accumulated_time =
static_cast<float>(animations_[current_animation_].loop) *
animations_[current_animation_].speed;
animations_[current_animation_].current_frame = animations_[current_animation_].loop;
// Establece el clip del frame de loop
setClip(animations_[current_animation_].frames[animations_[current_animation_].current_frame]);
}
} else {
// Actualiza el frame actual
animations_[current_animation_].current_frame = TARGET_FRAME;
// Establece el clip del frame actual
if (animations_[current_animation_].current_frame >= 0 &&
animations_[current_animation_].current_frame <
static_cast<int>(animations_[current_animation_].frames.size())) {
setClip(animations_[current_animation_].frames[animations_[current_animation_].current_frame]);
}
}
}
// Calcula el frame correspondiente a la animación (frame-based, deprecated)
void SurfaceAnimatedSprite::animate() {
if (animations_[current_animation_].speed == 0.0F) {
return;
}
// Calcula el frame actual a partir del contador (sistema antiguo)
animations_[current_animation_].current_frame =
static_cast<int>(animations_[current_animation_].counter / animations_[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 (animations_[current_animation_].current_frame >= static_cast<int>(animations_[current_animation_].frames.size())) {
if (animations_[current_animation_].loop == -1) { // Si no hay loop, deja el último frame
animations_[current_animation_].current_frame = animations_[current_animation_].frames.size();
animations_[current_animation_].current_frame =
static_cast<int>(animations_[current_animation_].frames.size()) - 1;
animations_[current_animation_].completed = true;
} else { // Si hay loop, vuelve al frame indicado
animations_[current_animation_].counter = 0;
@@ -104,7 +156,8 @@ void SurfaceAnimatedSprite::setCurrentAnimation(const std::string& name) {
if (current_animation_ != NEW_ANIMATION) {
current_animation_ = NEW_ANIMATION;
animations_[current_animation_].current_frame = 0;
animations_[current_animation_].counter = 0;
animations_[current_animation_].accumulated_time = 0.0F; // Time-based
animations_[current_animation_].counter = 0; // Frame-based (deprecated)
animations_[current_animation_].completed = false;
setClip(animations_[current_animation_].frames[animations_[current_animation_].current_frame]);
}
@@ -116,13 +169,20 @@ void SurfaceAnimatedSprite::setCurrentAnimation(int index) {
if (current_animation_ != NEW_ANIMATION) {
current_animation_ = NEW_ANIMATION;
animations_[current_animation_].current_frame = 0;
animations_[current_animation_].counter = 0;
animations_[current_animation_].accumulated_time = 0.0F; // Time-based
animations_[current_animation_].counter = 0; // Frame-based (deprecated)
animations_[current_animation_].completed = false;
setClip(animations_[current_animation_].frames[animations_[current_animation_].current_frame]);
}
}
// Actualiza las variables del objeto
// Actualiza las variables del objeto (time-based)
void SurfaceAnimatedSprite::update(float delta_time) {
animate(delta_time);
SurfaceMovingSprite::update(delta_time);
}
// Actualiza las variables del objeto (frame-based, deprecated)
void SurfaceAnimatedSprite::update() {
animate();
SurfaceMovingSprite::update();
@@ -131,7 +191,8 @@ void SurfaceAnimatedSprite::update() {
// Reinicia la animación
void SurfaceAnimatedSprite::resetAnimation() {
animations_[current_animation_].current_frame = 0;
animations_[current_animation_].counter = 0;
animations_[current_animation_].accumulated_time = 0.0F; // Time-based
animations_[current_animation_].counter = 0; // Frame-based (deprecated)
animations_[current_animation_].completed = false;
}
@@ -183,7 +244,8 @@ auto parseAnimationParameter(const std::string& key, const std::string& value, A
return true;
}
if (key == "speed") {
animation.speed = std::stoi(value);
// Soporta tanto float (segundos) como int (compatibilidad con sistema antiguo)
animation.speed = std::stof(value);
return true;
}
if (key == "loop") {

View File

@@ -13,11 +13,14 @@ class Surface; // lines 9-9
struct AnimationData {
std::string name; // Nombre de la animacion
std::vector<SDL_FRect> frames; // Cada uno de los frames que componen la animación
int speed{5}; // Velocidad de la animación
float speed{0.083F}; // Velocidad de la animación (segundos por frame)
int loop{0}; // Indica a que frame vuelve la animación al terminar. -1 para que no vuelva
bool completed{false}; // Indica si ha finalizado la animación
int current_frame{0}; // Frame actual
int counter{0}; // Contador para las animaciones
float accumulated_time{0.0F}; // Tiempo acumulado para las animaciones (time-based)
// DEPRECATED: Mantener compatibilidad con sistema antiguo
int counter{0}; // Contador para las animaciones (frame-based, deprecated)
AnimationData()
@@ -35,7 +38,10 @@ class SurfaceAnimatedSprite : public SurfaceMovingSprite {
std::vector<AnimationData> animations_; // Vector con las diferentes animaciones
int current_animation_ = 0; // Animacion activa
// Calcula el frame correspondiente a la animación actual
// Calcula el frame correspondiente a la animación actual (time-based)
void animate(float delta_time);
// Calcula el frame correspondiente a la animación actual (frame-based, deprecated)
void animate();
// Carga la animación desde un vector de cadenas
@@ -51,7 +57,11 @@ class SurfaceAnimatedSprite : public SurfaceMovingSprite {
// Destructor
~SurfaceAnimatedSprite() override = default;
// Actualiza las variables del objeto
// Actualiza las variables del objeto (time-based)
void update(float delta_time) override;
// Actualiza las variables del objeto (frame-based, deprecated)
[[deprecated("Use update(float delta_time) instead")]]
void update() override;
// Comprueba si ha terminado la animación

View File

@@ -39,8 +39,26 @@ void SurfaceMovingSprite::clear() {
SurfaceSprite::clear();
}
// Mueve el sprite
// Mueve el sprite (time-based)
// Nota: vx_, vy_ ahora se interpretan como pixels/segundo
// Nota: ax_, ay_ ahora se interpretan como pixels/segundo²
void SurfaceMovingSprite::move(float delta_time) {
// Aplica aceleración a velocidad (time-based)
vx_ += ax_ * delta_time;
vy_ += ay_ * delta_time;
// Aplica velocidad a posición (time-based)
x_ += vx_ * delta_time;
y_ += vy_ * delta_time;
// Actualiza posición entera para renderizado
pos_.x = static_cast<int>(x_);
pos_.y = static_cast<int>(y_);
}
// Mueve el sprite (frame-based, deprecated)
void SurfaceMovingSprite::move() {
// Versión antigua: suma directa sin delta_time
x_ += vx_;
y_ += vy_;
@@ -51,7 +69,12 @@ void SurfaceMovingSprite::move() {
pos_.y = static_cast<int>(y_);
}
// Actualiza las variables internas del objeto
// Actualiza las variables internas del objeto (time-based)
void SurfaceMovingSprite::update(float delta_time) {
move(delta_time);
}
// Actualiza las variables internas del objeto (frame-based, deprecated)
void SurfaceMovingSprite::update() {
move();
}

View File

@@ -22,7 +22,10 @@ class SurfaceMovingSprite : public SurfaceSprite {
SDL_FlipMode flip_; // Indica como se voltea el sprite
// Mueve el sprite
// Mueve el sprite (time-based)
void move(float delta_time);
// Mueve el sprite (frame-based, deprecated)
void move();
public:
@@ -34,8 +37,12 @@ class SurfaceMovingSprite : public SurfaceSprite {
// Destructor
~SurfaceMovingSprite() override = default;
// Actualiza las variables internas del objeto
virtual void update();
// Actualiza las variables internas del objeto (time-based)
void update(float delta_time) override;
// Actualiza las variables internas del objeto (frame-based, deprecated)
[[deprecated("Use update(float delta_time) instead")]]
void update() override;
// Reinicia todas las variables a cero
void clear() override;

View File

@@ -46,3 +46,15 @@ void SurfaceSprite::clear() {
pos_ = {.x = 0, .y = 0, .w = 0, .h = 0};
clip_ = {.x = 0, .y = 0, .w = 0, .h = 0};
}
// Actualiza el estado del sprite (time-based)
void SurfaceSprite::update(float delta_time) {
// Base implementation does nothing (static sprites)
(void)delta_time; // Evita warning de parámetro no usado
}
// Actualiza el estado del sprite (frame-based, deprecated)
void SurfaceSprite::update() {
// Llama a la versión time-based con 0.0f para compatibilidad
update(0.0F);
}

View File

@@ -23,6 +23,13 @@ class SurfaceSprite {
// Destructor
virtual ~SurfaceSprite() = default;
// Actualiza el estado del sprite (time-based)
virtual void update(float delta_time);
// Actualiza el estado del sprite (frame-based, deprecated)
[[deprecated("Use update(float delta_time) instead")]]
virtual void update();
// Muestra el sprite por pantalla
virtual void render();
virtual void render(Uint8 source_color, Uint8 target_color);