fixos en la plataforma mobil
This commit is contained in:
@@ -1,39 +1,181 @@
|
||||
#include "game/entities/moving_platform.hpp"
|
||||
|
||||
#include <cmath> // Para std::sqrt
|
||||
#include <cstdlib> // Para rand
|
||||
|
||||
#include "core/rendering/sprite/animated_sprite.hpp" // Para AnimatedSprite
|
||||
#include "core/resources/resource_cache.hpp" // Para Resource
|
||||
#include "utils/easing_functions.hpp" // Para Easing::*
|
||||
|
||||
// Resuelve el nombre de un easing a su función
|
||||
auto MovingPlatform::resolveEasing(const std::string& name) -> EasingFunc {
|
||||
if (name == "quadIn") { return Easing::quadIn; }
|
||||
if (name == "quadOut") { return Easing::quadOut; }
|
||||
if (name == "quadInOut") { return Easing::quadInOut; }
|
||||
if (name == "cubicIn") { return Easing::cubicIn; }
|
||||
if (name == "cubicOut") { return Easing::cubicOut; }
|
||||
if (name == "cubicInOut") { return Easing::cubicInOut; }
|
||||
if (name == "sineIn") { return Easing::sineIn; }
|
||||
if (name == "sineOut") { return Easing::sineOut; }
|
||||
if (name == "sineInOut") { return Easing::sineInOut; }
|
||||
return Easing::linear;
|
||||
}
|
||||
|
||||
// Constructor
|
||||
MovingPlatform::MovingPlatform(const Data& data)
|
||||
: sprite_(std::make_shared<AnimatedSprite>(Resource::Cache::get()->getAnimationData(data.animation_path))),
|
||||
x1_(data.x1),
|
||||
x2_(data.x2),
|
||||
y1_(data.y1),
|
||||
y2_(data.y2) {
|
||||
sprite_->setPosX(data.x);
|
||||
sprite_->setPosY(data.y);
|
||||
sprite_->setVelX(data.vx);
|
||||
sprite_->setVelY(data.vy);
|
||||
path_(data.path),
|
||||
speed_(data.speed),
|
||||
loop_mode_(data.loop),
|
||||
easing_(resolveEasing(data.easing)) {
|
||||
// Colocar el sprite en el primer waypoint
|
||||
if (!path_.empty()) {
|
||||
sprite_->setPosX(path_[0].x);
|
||||
sprite_->setPosY(path_[0].y);
|
||||
}
|
||||
|
||||
collider_ = getRect();
|
||||
|
||||
// Coloca un frame al azar o el designado
|
||||
// Frame inicial
|
||||
sprite_->setCurrentAnimationFrame((data.frame == -1) ? (rand() % sprite_->getCurrentAnimationSize()) : data.frame);
|
||||
|
||||
// Calcular longitud del primer segmento
|
||||
recalcSegmentLength();
|
||||
}
|
||||
|
||||
// Actualiza posición, calcula desplazamiento real del frame
|
||||
// Índice del waypoint origen del segmento actual
|
||||
auto MovingPlatform::getSegmentFrom() const -> int {
|
||||
if (direction_ == 1) {
|
||||
return current_segment_;
|
||||
}
|
||||
// Pingpong retrocediendo: segmento N va de path[N+1] a path[N]
|
||||
return current_segment_ + 1;
|
||||
}
|
||||
|
||||
// Índice del waypoint destino del segmento actual
|
||||
auto MovingPlatform::getSegmentTo() const -> int {
|
||||
if (direction_ == 1) {
|
||||
if (loop_mode_ == LoopMode::CIRCULAR) {
|
||||
return (current_segment_ + 1) % static_cast<int>(path_.size());
|
||||
}
|
||||
return current_segment_ + 1;
|
||||
}
|
||||
// Pingpong retrocediendo
|
||||
return current_segment_;
|
||||
}
|
||||
|
||||
// Recalcula la longitud del segmento actual
|
||||
void MovingPlatform::recalcSegmentLength() {
|
||||
if (path_.size() < 2) {
|
||||
segment_length_ = 0.0F;
|
||||
return;
|
||||
}
|
||||
|
||||
int from = getSegmentFrom();
|
||||
int to = getSegmentTo();
|
||||
|
||||
float dx = path_[to].x - path_[from].x;
|
||||
float dy = path_[to].y - path_[from].y;
|
||||
segment_length_ = std::sqrt(dx * dx + dy * dy);
|
||||
}
|
||||
|
||||
// Avanza al siguiente segmento
|
||||
void MovingPlatform::advanceSegment() {
|
||||
int path_size = static_cast<int>(path_.size());
|
||||
|
||||
if (loop_mode_ == LoopMode::PINGPONG) {
|
||||
if (direction_ == 1) {
|
||||
if (current_segment_ + 1 >= path_size - 1) {
|
||||
// Llegamos al final, invertir dirección
|
||||
direction_ = -1;
|
||||
current_segment_ = path_size - 2;
|
||||
} else {
|
||||
current_segment_++;
|
||||
}
|
||||
} else {
|
||||
if (current_segment_ <= 0) {
|
||||
// Llegamos al inicio, invertir dirección
|
||||
direction_ = 1;
|
||||
current_segment_ = 0;
|
||||
} else {
|
||||
current_segment_--;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// CIRCULAR
|
||||
current_segment_ = (current_segment_ + 1) % path_size;
|
||||
}
|
||||
|
||||
segment_progress_ = 0.0F;
|
||||
recalcSegmentLength();
|
||||
}
|
||||
|
||||
// Actualiza posición de la plataforma siguiendo la ruta
|
||||
void MovingPlatform::update(float delta_time) {
|
||||
sprite_->animate(delta_time);
|
||||
|
||||
if (path_.size() < 2) {
|
||||
last_dx_ = 0.0F;
|
||||
last_dy_ = 0.0F;
|
||||
return;
|
||||
}
|
||||
|
||||
float old_x = sprite_->getPosX();
|
||||
float old_y = sprite_->getPosY();
|
||||
|
||||
sprite_->update(delta_time);
|
||||
checkPath();
|
||||
// Si estamos esperando en un waypoint
|
||||
if (waiting_) {
|
||||
wait_timer_ -= delta_time;
|
||||
if (wait_timer_ <= 0.0F) {
|
||||
waiting_ = false;
|
||||
advanceSegment();
|
||||
} else {
|
||||
last_dx_ = 0.0F;
|
||||
last_dy_ = 0.0F;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Avanzar por el segmento
|
||||
if (segment_length_ > 0.0F) {
|
||||
float distance = speed_ * delta_time;
|
||||
float delta_progress = distance / segment_length_;
|
||||
segment_progress_ += delta_progress;
|
||||
} else {
|
||||
// Segmento de longitud 0: saltar al siguiente
|
||||
segment_progress_ = 1.0F;
|
||||
}
|
||||
|
||||
// Comprobar si llegamos al final del segmento
|
||||
if (segment_progress_ >= 1.0F) {
|
||||
segment_progress_ = 1.0F;
|
||||
|
||||
// Colocar en el waypoint destino exacto
|
||||
int to = getSegmentTo();
|
||||
sprite_->setPosX(path_[to].x);
|
||||
sprite_->setPosY(path_[to].y);
|
||||
|
||||
// Comprobar si hay espera en este waypoint
|
||||
if (path_[to].wait > 0.0F) {
|
||||
waiting_ = true;
|
||||
wait_timer_ = path_[to].wait;
|
||||
} else {
|
||||
advanceSegment();
|
||||
}
|
||||
} else {
|
||||
// Interpolar posición con easing
|
||||
float t = easing_(segment_progress_);
|
||||
int from = getSegmentFrom();
|
||||
int to = getSegmentTo();
|
||||
|
||||
float new_x = path_[from].x + (path_[to].x - path_[from].x) * t;
|
||||
float new_y = path_[from].y + (path_[to].y - path_[from].y) * t;
|
||||
sprite_->setPosX(new_x);
|
||||
sprite_->setPosY(new_y);
|
||||
}
|
||||
|
||||
last_dx_ = sprite_->getPosX() - old_x;
|
||||
last_dy_ = sprite_->getPosY() - old_y;
|
||||
|
||||
collider_ = getRect();
|
||||
}
|
||||
|
||||
@@ -50,17 +192,24 @@ void MovingPlatform::updateAnimation(float delta_time) {
|
||||
|
||||
// Resetea la plataforma a su posición inicial (para editor)
|
||||
void MovingPlatform::resetToInitialPosition(const Data& data) {
|
||||
sprite_->setPosX(data.x);
|
||||
sprite_->setPosY(data.y);
|
||||
sprite_->setVelX(data.vx);
|
||||
sprite_->setVelY(data.vy);
|
||||
path_ = data.path;
|
||||
speed_ = data.speed;
|
||||
loop_mode_ = data.loop;
|
||||
easing_ = resolveEasing(data.easing);
|
||||
|
||||
x1_ = data.x1;
|
||||
x2_ = data.x2;
|
||||
y1_ = data.y1;
|
||||
y2_ = data.y2;
|
||||
current_segment_ = 0;
|
||||
direction_ = 1;
|
||||
segment_progress_ = 0.0F;
|
||||
waiting_ = false;
|
||||
wait_timer_ = 0.0F;
|
||||
|
||||
if (!path_.empty()) {
|
||||
sprite_->setPosX(path_[0].x);
|
||||
sprite_->setPosY(path_[0].y);
|
||||
}
|
||||
|
||||
collider_ = getRect();
|
||||
recalcSegmentLength();
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -73,24 +222,3 @@ auto MovingPlatform::getRect() -> SDL_FRect {
|
||||
auto MovingPlatform::getCollider() -> SDL_FRect& {
|
||||
return collider_;
|
||||
}
|
||||
|
||||
// Comprueba los límites del recorrido para invertir dirección
|
||||
void MovingPlatform::checkPath() { // NOLINT(readability-make-member-function-const)
|
||||
if (sprite_->getPosX() > x2_ || sprite_->getPosX() < x1_) {
|
||||
if (sprite_->getPosX() > x2_) {
|
||||
sprite_->setPosX(x2_);
|
||||
} else {
|
||||
sprite_->setPosX(x1_);
|
||||
}
|
||||
sprite_->setVelX(sprite_->getVelX() * (-1));
|
||||
}
|
||||
|
||||
if (sprite_->getPosY() > y2_ || sprite_->getPosY() < y1_) {
|
||||
if (sprite_->getPosY() > y2_) {
|
||||
sprite_->setPosY(y2_);
|
||||
} else {
|
||||
sprite_->setPosY(y1_);
|
||||
}
|
||||
sprite_->setVelY(sprite_->getVelY() * (-1));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user