aproximant-se

This commit is contained in:
2026-04-03 18:24:58 +02:00
parent 43de2c0b35
commit 6f31751d42
4 changed files with 100 additions and 53 deletions

View File

@@ -5,7 +5,7 @@
#include <utility> // Para move
#include "texture.hpp" // Para Texture
#include "utils.hpp" // Para easeOutBounce
#include "utils.hpp" // Para easeOutBounce, easeOutCubic
// Constructor
CardSprite::CardSprite(std::shared_ptr<Texture> texture)
@@ -20,9 +20,10 @@ void CardSprite::enable() {
state_ = CardState::ENTERING;
entry_elapsed_ = 0.0F;
first_touch_ = false;
// Posición fija en el punto de aterrizaje
setPos(landing_x_, landing_y_);
// Posición inicial (borde de pantalla)
setPos(entry_start_x_, entry_start_y_);
// Zoom inicial grande (como si estuviera cerca de la cámara)
horizontal_zoom_ = start_zoom_;
@@ -70,7 +71,7 @@ void CardSprite::update(float delta_time) {
}
}
// Animación de entrada: interpola zoom y ángulo con easing
// Animación de entrada: interpola posición, zoom y ángulo
void CardSprite::updateEntering(float delta_time) {
entry_elapsed_ += delta_time;
@@ -85,15 +86,26 @@ void CardSprite::updateEntering(float delta_time) {
// Ángulo: de start_angle_ a 0 con rebote
rotate_.angle = start_angle_ * (1.0 - eased);
// Offset de sombra escalado con el zoom (perspectiva)
// (se aplica en renderShadow)
// Posición: de entry_start a landing con easing suave (sin rebote)
// Usamos easeOutCubic para que el desplazamiento sea fluido
double pos_eased = easeOutCubic(static_cast<double>(progress));
auto current_x = static_cast<float>(entry_start_x_ + (landing_x_ - entry_start_x_) * pos_eased);
auto current_y = static_cast<float>(entry_start_y_ + (landing_y_ - entry_start_y_) * pos_eased);
setPos(current_x, current_y);
// Transición a LANDED cuando termina la animación
// Detecta el primer toque (cuando el easing alcanza ~1.0 por primera vez)
if (!first_touch_ && eased >= FIRST_TOUCH_THRESHOLD) {
first_touch_ = true;
}
// Transición a LANDED cuando termina la animación completa
if (progress >= 1.0F) {
horizontal_zoom_ = 1.0F;
vertical_zoom_ = 1.0F;
rotate_.angle = 0.0;
setPos(landing_x_, landing_y_);
state_ = CardState::LANDED;
first_touch_ = true;
}
}
@@ -122,18 +134,23 @@ void CardSprite::render() {
MovingSprite::render();
}
// Renderiza la sombra con el mismo zoom y rotación que la tarjeta
// Renderiza la sombra con efecto de perspectiva
// Cuanto más alta la tarjeta (zoom grande), la sombra es más pequeña y más separada.
// Cuando la tarjeta está en la mesa (zoom=1.0), la sombra tiene tamaño real y offset base.
void CardSprite::renderShadow() {
// Offset de sombra escalado con el zoom para efecto de perspectiva
// La sombra siempre está en la mesa: su escala es inversamente proporcional al zoom
float shadow_zoom = 1.0F / horizontal_zoom_;
// El offset aumenta con la altura (más lejos de la tarjeta cuanto más alta)
float scaled_offset_x = shadow_offset_x_ * horizontal_zoom_;
float scaled_offset_y = shadow_offset_y_ * vertical_zoom_;
float scaled_offset_y = shadow_offset_y_ * horizontal_zoom_;
shadow_texture_->render(
pos_.x + scaled_offset_x,
pos_.y + scaled_offset_y,
&sprite_clip_,
horizontal_zoom_,
vertical_zoom_,
shadow_zoom,
shadow_zoom,
rotate_.angle,
&rotate_.center,
flip_);
@@ -141,7 +158,6 @@ void CardSprite::renderShadow() {
// Comprueba si el sprite está fuera de pantalla
auto CardSprite::isOffScreen() const -> bool {
// Considerar el zoom: el sprite puede ser más grande de lo que indica pos_
float effective_width = pos_.w * horizontal_zoom_;
float effective_height = pos_.h * vertical_zoom_;
return (pos_.x + effective_width < -OFF_SCREEN_MARGIN ||
@@ -155,6 +171,10 @@ auto CardSprite::hasLanded() const -> bool {
return state_ == CardState::LANDED || state_ == CardState::EXITING || state_ == CardState::FINISHED;
}
auto CardSprite::hasFirstTouch() const -> bool {
return first_touch_;
}
auto CardSprite::hasFinished() const -> bool {
return state_ == CardState::FINISHED;
}
@@ -175,6 +195,11 @@ void CardSprite::setEntryParams(float start_zoom, double start_angle, float dura
entry_easing_ = std::move(easing);
}
void CardSprite::setEntryPosition(float start_x, float start_y) {
entry_start_x_ = start_x;
entry_start_y_ = start_y;
}
void CardSprite::setLandingPosition(float x, float y) {
landing_x_ = x;
landing_y_ = y;