delta-time: animated_sprite.cpp

This commit is contained in:
2025-09-16 16:51:31 +02:00
parent 26e0fd7247
commit 19768cb72b
2 changed files with 57 additions and 6 deletions

View File

@@ -43,6 +43,10 @@ auto loadAnimationsFromFile(const std::string& file_path) -> AnimationsFileBuffe
std::vector<std::string> buffer;
std::string line;
while (std::getline(input_stream, line)) {
// Eliminar caracteres de retorno de carro (\r) al final de la línea
if (!line.empty() && line.back() == '\r') {
line.pop_back();
}
if (!line.empty()) {
buffer.push_back(line);
}
@@ -82,7 +86,7 @@ auto AnimatedSprite::getAnimationIndex(const std::string& name) -> int {
return -1;
}
// Calcula el frame correspondiente a la animación
// Calcula el frame correspondiente a la animación (frame-based)
void AnimatedSprite::animate() {
if (animations_[current_animation_].speed == 0 || animations_[current_animation_].paused) {
return;
@@ -112,6 +116,39 @@ void AnimatedSprite::animate() {
}
}
// Calcula el frame correspondiente a la animación (time-based)
void AnimatedSprite::animate(float deltaTime) {
if (animations_[current_animation_].speed == 0 || animations_[current_animation_].paused) {
return;
}
// Convertir speed (frames) a tiempo: speed frames = speed/60 segundos a 60fps
float frameTime = static_cast<float>(animations_[current_animation_].speed) / 60.0f;
// Acumular tiempo transcurrido
animations_[current_animation_].time_accumulator += deltaTime;
// Verificar si es momento de cambiar frame
if (animations_[current_animation_].time_accumulator >= frameTime) {
animations_[current_animation_].time_accumulator -= frameTime;
animations_[current_animation_].current_frame++;
// Si alcanza el final de la animación
if (animations_[current_animation_].current_frame >= 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() - 1;
animations_[current_animation_].completed = true;
} else { // Si hay loop, vuelve al frame indicado
animations_[current_animation_].time_accumulator = 0.0f;
animations_[current_animation_].current_frame = animations_[current_animation_].loop;
}
}
// Actualizar el sprite clip
updateSpriteClip();
}
}
// Comprueba si ha terminado la animación
auto AnimatedSprite::animationIsCompleted() -> bool {
return animations_[current_animation_].completed;
@@ -126,10 +163,12 @@ void AnimatedSprite::setCurrentAnimation(const std::string& name, bool reset) {
if (reset) {
animations_[current_animation_].current_frame = 0;
animations_[current_animation_].counter = 0;
animations_[current_animation_].time_accumulator = 0.0f;
animations_[current_animation_].completed = false;
} else {
animations_[current_animation_].current_frame = std::min(animations_[OLD_ANIMATION].current_frame, animations_[current_animation_].frames.size() - 1);
animations_[current_animation_].counter = animations_[OLD_ANIMATION].counter;
animations_[current_animation_].time_accumulator = animations_[OLD_ANIMATION].time_accumulator;
animations_[current_animation_].completed = animations_[OLD_ANIMATION].completed;
}
updateSpriteClip();
@@ -145,26 +184,35 @@ void AnimatedSprite::setCurrentAnimation(int index, bool reset) {
if (reset) {
animations_[current_animation_].current_frame = 0;
animations_[current_animation_].counter = 0;
animations_[current_animation_].time_accumulator = 0.0f;
animations_[current_animation_].completed = false;
} else {
animations_[current_animation_].current_frame = std::min(animations_[OLD_ANIMATION].current_frame, animations_[current_animation_].frames.size());
animations_[current_animation_].counter = animations_[OLD_ANIMATION].counter;
animations_[current_animation_].time_accumulator = animations_[OLD_ANIMATION].time_accumulator;
animations_[current_animation_].completed = animations_[OLD_ANIMATION].completed;
}
updateSpriteClip();
}
}
// Actualiza las variables del objeto
// Actualiza las variables del objeto (frame-based)
void AnimatedSprite::update() {
animate();
MovingSprite::update();
}
// Actualiza las variables del objeto (time-based)
void AnimatedSprite::update(float deltaTime) {
animate(deltaTime);
MovingSprite::update(deltaTime);
}
// Reinicia la animación
void AnimatedSprite::resetAnimation() {
animations_[current_animation_].current_frame = 0;
animations_[current_animation_].counter = 0;
animations_[current_animation_].time_accumulator = 0.0f;
animations_[current_animation_].completed = false;
animations_[current_animation_].paused = false;
updateSpriteClip();

View File

@@ -21,11 +21,12 @@ struct Animation {
std::string name; // Nombre de la animación
std::vector<SDL_FRect> frames; // Frames que componen la animación
int speed{DEFAULT_SPEED}; // Velocidad de reproducción
int speed{DEFAULT_SPEED}; // Velocidad de reproducción (frame-based)
int loop{0}; // Frame de vuelta al terminar (-1 para no repetir)
bool completed{false}; // Indica si la animación ha finalizado
size_t current_frame{0}; // Frame actual en reproducción
int counter{0}; // Contador para la animación
int counter{0}; // Contador para la animación (frame-based)
float time_accumulator{0.0f}; // Acumulador de tiempo para animaciones time-based
bool paused{false}; // La animación no avanza
Animation() = default;
@@ -55,7 +56,8 @@ class AnimatedSprite : public MovingSprite {
~AnimatedSprite() override = default;
// --- Métodos principales ---
void update() override; // Actualiza la animación
void update() override; // Actualiza la animación (frame-based)
void update(float deltaTime); // Actualiza la animación (time-based)
// --- Control de animaciones ---
void setCurrentAnimation(const std::string& name = "default", bool reset = true); // Establece la animación por nombre
@@ -78,7 +80,8 @@ class AnimatedSprite : public MovingSprite {
int current_animation_ = 0; // Índice de la animación activa
// --- Métodos internos ---
void animate(); // Calcula el frame correspondiente a la animación
void animate(); // Calcula el frame correspondiente a la animación (frame-based)
void animate(float deltaTime); // Calcula el frame correspondiente a la animación (time-based)
void loadFromAnimationsFileBuffer(const AnimationsFileBuffer& source); // Carga la animación desde un vector de cadenas
void processConfigLine(const std::string& line, AnimationConfig& config); // Procesa una línea de configuración
void updateFrameCalculations(AnimationConfig& config); // Actualiza los cálculos basados en las dimensiones del frame