Files
coffee_crisis_arcade_edition/source/path_sprite.cpp

110 lines
2.6 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 path 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 path horizontal
void PathSprite::addHorizontalPath(SDL_Point start, SDL_Point end, int steps, int waiting_counter)
{
paths_.emplace_back(createHorizontalPath(start, end, steps), waiting_counter);
}
// Devuelve un vector con los puntos que conforman la ruta
std::vector<SDL_Point> PathSprite::createVerticalPath(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.y) + (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;
}
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;
}
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_;
}