Files
coffee_crisis_arcade_edition/source/card_sprite.hpp
2026-04-03 18:24:58 +02:00

106 lines
3.9 KiB
C++

#pragma once
#include <SDL3/SDL.h> // Para SDL_FPoint
#include <functional> // Para function
#include <memory> // Para shared_ptr
#include "moving_sprite.hpp" // Para MovingSprite
class Texture;
// --- Estados de la tarjeta ---
enum class CardState {
IDLE, // No activada todavía
ENTERING, // Animación de entrada (zoom + rotación + desplazamiento con rebote)
LANDED, // En reposo sobre la mesa
EXITING, // Saliendo de pantalla girando
FINISHED, // Fuera de pantalla
};
// --- Clase CardSprite: tarjeta animada con zoom, rotación y sombra integrada ---
//
// Simula una tarjeta lanzada sobre una mesa desde un borde de la pantalla.
// Durante la entrada, interpola posición, zoom y rotación con easing (rebote).
// Durante la salida, se desplaza fuera de pantalla girando, sin sombra.
class CardSprite : public MovingSprite {
public:
explicit CardSprite(std::shared_ptr<Texture> texture);
~CardSprite() override = default;
// --- Ciclo principal ---
void update(float delta_time) override;
void render() override;
// --- Control de estado ---
void enable(); // Inicia la animación de entrada
void startExit(); // Inicia la animación de salida
// --- Consultas de estado ---
[[nodiscard]] auto hasLanded() const -> bool; // ¿Ha aterrizado definitivamente?
[[nodiscard]] auto hasFirstTouch() const -> bool; // ¿Ha tocado la mesa por primera vez? (primer rebote)
[[nodiscard]] auto hasFinished() const -> bool; // ¿Ha terminado completamente?
[[nodiscard]] auto isExiting() const -> bool; // ¿Está saliendo de pantalla?
[[nodiscard]] auto getState() const -> CardState; // Estado actual
// --- Configuración de entrada ---
void setEntryParams(float start_zoom, double start_angle, float duration_s, std::function<double(double)> easing);
void setEntryPosition(float start_x, float start_y); // Posición inicial (borde de pantalla)
void setLandingPosition(float x, float y); // Posición final centrada
// --- Configuración de salida ---
void setExitParams(float vx, float vy, float ax, float ay, double rotate_amount);
// --- Sombra ---
void setShadowTexture(std::shared_ptr<Texture> texture);
void setShadowOffset(float offset_x, float offset_y);
// --- Limites de pantalla (para detectar salida) ---
void setScreenBounds(float width, float height);
private:
// --- Estado ---
CardState state_ = CardState::IDLE;
bool first_touch_ = false; // Primer contacto con la mesa (eased >= umbral)
// --- Umbral para detectar el primer toque ---
static constexpr double FIRST_TOUCH_THRESHOLD = 0.98;
// --- Parámetros de entrada ---
float start_zoom_ = 1.8F;
double start_angle_ = 15.0;
float entry_duration_s_ = 1.5F;
float entry_elapsed_ = 0.0F;
std::function<double(double)> entry_easing_;
float entry_start_x_ = 0.0F; // Posición inicial X (borde)
float entry_start_y_ = 0.0F; // Posición inicial Y (borde)
float landing_x_ = 0.0F;
float landing_y_ = 0.0F;
// --- Parámetros de salida ---
float exit_vx_ = 0.0F;
float exit_vy_ = 0.0F;
float exit_ax_ = 0.0F;
float exit_ay_ = 0.0F;
double exit_rotate_amount_ = 0.0;
// --- Sombra ---
std::shared_ptr<Texture> shadow_texture_;
float shadow_offset_x_ = 8.0F;
float shadow_offset_y_ = 8.0F;
bool shadow_visible_ = true;
// --- Límites de pantalla ---
float screen_width_ = 320.0F;
float screen_height_ = 240.0F;
// --- Margen fuera de pantalla para considerar FINISHED ---
static constexpr float OFF_SCREEN_MARGIN = 50.0F;
// --- Métodos internos ---
void updateEntering(float delta_time);
void updateExiting(float delta_time);
void renderShadow();
[[nodiscard]] auto isOffScreen() const -> bool;
};