124 lines
3.2 KiB
C++
124 lines
3.2 KiB
C++
#include "path_sprite.h"
|
|
#include "utils.h"
|
|
class Texture;
|
|
|
|
// Constructor
|
|
PathSprite::PathSprite(std::shared_ptr<Texture> 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<SDL_Point> spots, int waiting_counter)
|
|
{
|
|
paths_.emplace_back(spots, waiting_counter);
|
|
}
|
|
|
|
std::vector<SDL_Point> PathSprite::createVerticalPath(const SDL_Point& start, const SDL_Point& end, int steps) {
|
|
std::vector<SDL_Point> v;
|
|
v.reserve(steps);
|
|
|
|
for (int i = 0; i < steps; ++i) {
|
|
double t = static_cast<double>(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<int>(value)});
|
|
}
|
|
|
|
return v;
|
|
}
|
|
|
|
|
|
// Devuelve un vector con los puntos que conforman la ruta
|
|
std::vector<SDL_Point> PathSprite::createHorizontalPath(SDL_Point start, SDL_Point end, int steps)
|
|
{
|
|
std::vector<SDL_Point> v;
|
|
v.reserve(steps);
|
|
|
|
for (int i = 0; i < steps; ++i)
|
|
{
|
|
double t = static_cast<double>(i) / steps;
|
|
double value = static_cast<double>(start.x) + (end.x - start.x) * easeOutQuint(t);
|
|
v.emplace_back(SDL_Point{static_cast<int>(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<int>(path.spots.size()))
|
|
{
|
|
path.on_destination = true;
|
|
path.counter = static_cast<int>(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<int>(paths_.size()))
|
|
enabled_ = false;
|
|
}
|
|
|
|
// Indica si ha terminado todos los recorridos
|
|
bool PathSprite::hasFinished()
|
|
{
|
|
return !enabled_;
|
|
} |