#include "path_sprite.h" #include "utils.h" class Texture; // Constructor PathSprite::PathSprite(std::shared_ptr texture) : AnimatedSprite(texture) {} // Actualiza la posición y comprueba si ha llegado a su destino void PathSprite::update() { if (enabled_) { moveThroughCurrentPath(); goToNextPathOrDie(); } } // Añade un recorrido vertical void PathSprite::addVerticalPath(SDL_Point start, SDL_Point end, int steps, int waiting_counter) { paths_.emplace_back(createVerticalPath(start, end, steps), waiting_counter); } // Añade un recorrido horizontal void PathSprite::addHorizontalPath(SDL_Point start, SDL_Point end, int steps, int waiting_counter) { paths_.emplace_back(createHorizontalPath(start, end, steps), waiting_counter); } // Añade un recorrido desde un vector void PathSprite::addPath(std::vector spots, int waiting_counter) { paths_.emplace_back(spots, waiting_counter); } std::vector PathSprite::createVerticalPath(const SDL_Point& start, const SDL_Point& end, int steps) { std::vector v; v.reserve(steps); for (int i = 0; i < steps; ++i) { double t = static_cast(i) / steps; double value = start.y + (end.y - start.y) * easeOutQuint(t); // Ajusta el valor si los puntos tienen signos diferentes if (start.y > 0 && end.y < 0) { value = start.y - std::abs(end.y - start.y) * easeOutQuint(t); } else if (start.y < 0 && end.y > 0) { value = start.y + std::abs(end.y - start.y) * easeOutQuint(t); } v.emplace_back(SDL_Point{start.x, static_cast(value)}); } return v; } // Devuelve un vector con los puntos que conforman la ruta std::vector PathSprite::createHorizontalPath(SDL_Point start, SDL_Point end, int steps) { std::vector v; v.reserve(steps); for (int i = 0; i < steps; ++i) { double t = static_cast(i) / steps; double value = static_cast(start.x) + (end.x - start.x) * easeOutQuint(t); v.emplace_back(SDL_Point{static_cast(value), start.y}); } return v; } // Habilita el objeto void PathSprite::enable() { enabled_ = true; } // Coloca el sprite en los diferentes puntos del recorrido void PathSprite::moveThroughCurrentPath() { auto &path = paths_.at(current_path_); // Establece la posición const SDL_Point p = path.spots.at(path.counter); MovingSprite::setPos(p.x, p.y); // Comprobar si ha terminado el recorrido if (!path.on_destination) { ++path.counter; if (path.counter >= static_cast(path.spots.size())) { path.on_destination = true; path.counter = static_cast(path.spots.size()) - 1; } } // Comprobar si ha terminado la espera if (path.waiting_counter == 0) path.finished = true; else if (path.on_destination) --path.waiting_counter; } // Cambia de recorrido o finaliza void PathSprite::goToNextPathOrDie() { // Comprueba si ha terminado el recorrdo actual if (paths_.at(current_path_).finished) ++current_path_; // Comprueba si quedan mas recorridos if (current_path_ >= static_cast(paths_.size())) enabled_ = false; } // Indica si ha terminado todos los recorridos bool PathSprite::hasFinished() { return !enabled_; }