Compare commits
2 Commits
e9fed353ff
...
1f01268dcf
| Author | SHA1 | Date | |
|---|---|---|---|
| 1f01268dcf | |||
| 85d34fb907 |
@@ -12,6 +12,10 @@
|
||||
#include "game/ui/notifier.hpp" // Para Notifier, NotificationText
|
||||
#include "utils/utils.hpp" // Para stringInVector
|
||||
|
||||
#ifdef _DEBUG
|
||||
#include "core/system/debug.hpp" // Para Debug
|
||||
#endif
|
||||
|
||||
namespace GlobalInputs {
|
||||
|
||||
// Funciones internas
|
||||
@@ -101,10 +105,17 @@ void handleToggleVSync() {
|
||||
Notifier::get()->show({"V-SYNC " + std::string(Options::video.vertical_sync ? "ENABLED" : "DISABLED")}, NotificationText::CENTER);
|
||||
}
|
||||
|
||||
#ifdef _DEBUG
|
||||
void handleShowDebugInfo() {
|
||||
Screen::get()->toggleDebugInfo();
|
||||
}
|
||||
|
||||
void handleToggleDebug() {
|
||||
Debug::get()->toggleEnabled();
|
||||
Notifier::get()->show({"DEBUG " + std::string(Debug::get()->getEnabled() ? "ENABLED" : "DISABLED")}, NotificationText::CENTER);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Detecta qué acción global ha sido presionada (si alguna)
|
||||
auto getPressedAction() -> InputAction {
|
||||
if (Input::get()->checkAction(InputAction::EXIT, Input::DO_NOT_ALLOW_REPEAT)) {
|
||||
@@ -140,6 +151,9 @@ auto getPressedAction() -> InputAction {
|
||||
if (Input::get()->checkAction(InputAction::TOGGLE_VSYNC, Input::DO_NOT_ALLOW_REPEAT)) {
|
||||
return InputAction::TOGGLE_VSYNC;
|
||||
}
|
||||
if (Input::get()->checkAction(InputAction::TOGGLE_DEBUG, Input::DO_NOT_ALLOW_REPEAT)) {
|
||||
return InputAction::TOGGLE_DEBUG;
|
||||
}
|
||||
if (Input::get()->checkAction(InputAction::SHOW_DEBUG_INFO, Input::DO_NOT_ALLOW_REPEAT)) {
|
||||
return InputAction::SHOW_DEBUG_INFO;
|
||||
}
|
||||
@@ -201,6 +215,10 @@ void handle() {
|
||||
handleToggleVSync();
|
||||
break;
|
||||
|
||||
case InputAction::TOGGLE_DEBUG:
|
||||
handleToggleDebug();
|
||||
break;
|
||||
|
||||
case InputAction::SHOW_DEBUG_INFO:
|
||||
handleShowDebugInfo();
|
||||
break;
|
||||
|
||||
@@ -78,8 +78,8 @@ class Input {
|
||||
{Action::TOGGLE_MUSIC, KeyState(SDL_SCANCODE_F8)},
|
||||
{Action::TOGGLE_BORDER, KeyState(SDL_SCANCODE_F9)},
|
||||
{Action::TOGGLE_VSYNC, KeyState(SDL_SCANCODE_F10)},
|
||||
{Action::PAUSE, KeyState(SDL_SCANCODE_F11)},
|
||||
{Action::SHOW_DEBUG_INFO, KeyState(SDL_SCANCODE_F12)}} {}
|
||||
{Action::TOGGLE_DEBUG, KeyState(SDL_SCANCODE_F12)},
|
||||
{Action::SHOW_DEBUG_INFO, KeyState(SDL_SCANCODE_F11)}} {}
|
||||
};
|
||||
|
||||
struct Gamepad {
|
||||
|
||||
@@ -22,6 +22,7 @@ const std::unordered_map<InputAction, std::string> ACTION_TO_STRING = {
|
||||
{InputAction::PREVIOUS_PALETTE, "PREVIOUS_PALETTE"},
|
||||
{InputAction::TOGGLE_SHADERS, "TOGGLE_SHADERS"},
|
||||
{InputAction::SHOW_DEBUG_INFO, "SHOW_DEBUG_INFO"},
|
||||
{InputAction::TOGGLE_DEBUG, "TOGGLE_DEBUG"},
|
||||
{InputAction::NONE, "NONE"}};
|
||||
|
||||
const std::unordered_map<std::string, InputAction> STRING_TO_ACTION = {
|
||||
@@ -43,6 +44,7 @@ const std::unordered_map<std::string, InputAction> STRING_TO_ACTION = {
|
||||
{"PREVIOUS_PALETTE", InputAction::PREVIOUS_PALETTE},
|
||||
{"TOGGLE_SHADERS", InputAction::TOGGLE_SHADERS},
|
||||
{"SHOW_DEBUG_INFO", InputAction::SHOW_DEBUG_INFO},
|
||||
{"TOGGLE_DEBUG", InputAction::TOGGLE_DEBUG},
|
||||
{"NONE", InputAction::NONE}};
|
||||
|
||||
const std::unordered_map<SDL_GamepadButton, std::string> BUTTON_TO_STRING = {
|
||||
|
||||
@@ -30,6 +30,7 @@ enum class InputAction : int { // Acciones de entrada posibles en el juego
|
||||
NEXT_PALETTE,
|
||||
PREVIOUS_PALETTE,
|
||||
SHOW_DEBUG_INFO,
|
||||
TOGGLE_DEBUG,
|
||||
|
||||
// Input obligatorio
|
||||
NONE,
|
||||
|
||||
@@ -7,23 +7,6 @@
|
||||
|
||||
// Clase Debug
|
||||
class Debug {
|
||||
private:
|
||||
// [SINGLETON] Objeto privado
|
||||
static Debug* debug;
|
||||
|
||||
// Variables
|
||||
std::vector<std::string> slot_; // Vector con los textos a escribir
|
||||
std::vector<std::string> log_; // Vector con los textos a escribir
|
||||
int x_ = 0; // Posicion donde escribir el texto de debug
|
||||
int y_ = 0; // Posición donde escribir el texto de debug
|
||||
bool enabled_ = false; // Indica si esta activo el modo debug
|
||||
|
||||
// Constructor
|
||||
Debug() = default;
|
||||
|
||||
// Destructor
|
||||
~Debug() = default;
|
||||
|
||||
public:
|
||||
// [SINGLETON] Crearemos el objeto con esta función estática
|
||||
static void init();
|
||||
@@ -50,4 +33,21 @@ class Debug {
|
||||
void clearLog() { log_.clear(); }
|
||||
void setEnabled(bool value) { enabled_ = value; }
|
||||
void toggleEnabled() { enabled_ = !enabled_; }
|
||||
|
||||
private:
|
||||
// [SINGLETON] Objeto privado
|
||||
static Debug* debug;
|
||||
|
||||
// Variables
|
||||
std::vector<std::string> slot_; // Vector con los textos a escribir
|
||||
std::vector<std::string> log_; // Vector con los textos a escribir
|
||||
int x_ = 0; // Posicion donde escribir el texto de debug
|
||||
int y_ = 0; // Posición donde escribir el texto de debug
|
||||
bool enabled_ = false; // Indica si esta activo el modo debug
|
||||
|
||||
// Constructor
|
||||
Debug() = default;
|
||||
|
||||
// Destructor
|
||||
~Debug() = default;
|
||||
};
|
||||
@@ -334,7 +334,7 @@ auto Director::run() -> int {
|
||||
break;
|
||||
|
||||
case SceneManager::Scene::LOADING_SCREEN:
|
||||
runLoadingScreen();
|
||||
runLogo();
|
||||
break;
|
||||
|
||||
case SceneManager::Scene::TITLE:
|
||||
|
||||
@@ -13,7 +13,6 @@
|
||||
#include "core/rendering/text.hpp" // Para Text, TEXT_CENTER, TEXT_COLOR
|
||||
#include "core/resources/asset.hpp" // Para Asset
|
||||
#include "core/resources/resource.hpp" // Para ResourceRoom, Resource
|
||||
#include "core/system/debug.hpp" // Para Debug
|
||||
#include "core/system/global_events.hpp" // Para check
|
||||
#include "game/gameplay/cheevos.hpp" // Para Cheevos
|
||||
#include "game/gameplay/item_tracker.hpp" // Para ItemTracker
|
||||
@@ -27,6 +26,10 @@
|
||||
#include "utils/defines.hpp" // Para TILE_SIZE, PLAY_AREA_HEIGHT, RoomBorder::BOTTOM
|
||||
#include "utils/utils.hpp" // Para PaletteColor, stringToColor
|
||||
|
||||
#ifdef _DEBUG
|
||||
#include "core/system/debug.hpp" // Para Debug
|
||||
#endif
|
||||
|
||||
// Constructor
|
||||
Game::Game(Mode mode)
|
||||
: board_(std::make_shared<ScoreboardData>(0, 9, 0, true, 0, SDL_GetTicks(), Options::cheats.jail_is_open == Options::Cheat::State::ENABLED)),
|
||||
@@ -42,10 +45,6 @@ Game::Game(Mode mode)
|
||||
spawn_data_(Player::SpawnData(25 * TILE_SIZE, 13 * TILE_SIZE, 0, 0, 0, Player::State::STANDING, SDL_FLIP_HORIZONTAL))
|
||||
#endif
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
Debug::get()->setEnabled(false);
|
||||
#endif
|
||||
|
||||
// Crea objetos e inicializa variables
|
||||
ItemTracker::init();
|
||||
demoInit();
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
#include <SDL3/SDL.h>
|
||||
|
||||
#include <algorithm> // Para std::clamp
|
||||
#include <array> // Para std::array
|
||||
#include <random> // Para generador aleatorio
|
||||
|
||||
#include "core/audio/audio.hpp" // Para Audio
|
||||
#include "core/input/global_inputs.hpp" // Para check
|
||||
@@ -15,6 +17,7 @@
|
||||
#include "game/options.hpp" // Para Options, SectionState, options, Section
|
||||
#include "game/scene_manager.hpp" // Para SceneManager
|
||||
#include "utils/delta_timer.hpp" // Para DeltaTimer
|
||||
#include "utils/easing_functions.hpp" // Para funciones de suavizado
|
||||
#include "utils/utils.hpp" // Para PaletteColor
|
||||
|
||||
// Constructor
|
||||
@@ -34,6 +37,19 @@ Logo::Logo()
|
||||
initSprites(); // Crea los sprites de cada linea
|
||||
initColors(); // Inicializa el vector de colores
|
||||
|
||||
// Seleccionar función de easing aleatoria para la animación del logo
|
||||
// Usamos lambdas para funciones con parámetros opcionales
|
||||
static const std::array<EasingFunction, 4> EASING_OPTIONS = {
|
||||
[](float t) { return Easing::backOut(t); }, // Overshoot retro
|
||||
[](float t) { return Easing::elasticOut(t); }, // Rebote múltiple con oscilación
|
||||
Easing::bounceOut, // Rebote físico decreciente
|
||||
Easing::cubicOut // Suavizado sin overshoot (para variedad)
|
||||
};
|
||||
std::random_device rd;
|
||||
std::mt19937 gen(rd());
|
||||
std::uniform_int_distribution<size_t> dist(0, EASING_OPTIONS.size() - 1);
|
||||
easing_function_ = EASING_OPTIONS[dist(gen)];
|
||||
|
||||
// Cambia el color del borde
|
||||
Screen::get()->setBorderColor(static_cast<Uint8>(PaletteColor::BLACK));
|
||||
}
|
||||
@@ -59,41 +75,24 @@ void Logo::updateJAILGAMES(float delta_time) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Calcular el desplazamiento basado en velocidad y delta time
|
||||
const float DISPLACEMENT = JAILGAMES_SLIDE_SPEED * delta_time;
|
||||
// Calcular el progreso de la animación (0.0 a 1.0)
|
||||
const float progress = std::clamp(state_time_ / JAILGAMES_SLIDE_DURATION, 0.0F, 1.0F);
|
||||
|
||||
// Actualizar cada línea del sprite JAILGAMES
|
||||
// Aplicar función de suavizado seleccionada aleatoriamente (permite overshoot para efecto de rebote)
|
||||
// La posición final exacta se garantiza en updateState() antes de transicionar
|
||||
const float eased_progress = easing_function_(progress);
|
||||
|
||||
// Actualizar cada línea del sprite JAILGAMES interpolando con easing
|
||||
for (size_t i = 0; i < jailgames_sprite_.size(); ++i) {
|
||||
const float CURRENT_X = jailgames_sprite_[i]->getX();
|
||||
// Interpolar entre posición inicial y destino usando el progreso suavizado
|
||||
const float initial_x = static_cast<float>(jailgames_initial_x_[i]);
|
||||
const float dest_x = static_cast<float>(JAILGAMES_DEST_X);
|
||||
const float new_x = initial_x + (dest_x - initial_x) * eased_progress;
|
||||
|
||||
// Las líneas pares se mueven desde la derecha, las impares desde la izquierda
|
||||
if (i % 2 == 0) {
|
||||
// Mover hacia la izquierda
|
||||
if (CURRENT_X > JAILGAMES_DEST_X) {
|
||||
const float NEW_X = CURRENT_X - DISPLACEMENT;
|
||||
jailgames_sprite_[i]->setX(NEW_X < JAILGAMES_DEST_X ? JAILGAMES_DEST_X : NEW_X);
|
||||
}
|
||||
} else {
|
||||
// Mover hacia la derecha
|
||||
if (CURRENT_X < JAILGAMES_DEST_X) {
|
||||
const float NEW_X = CURRENT_X + DISPLACEMENT;
|
||||
jailgames_sprite_[i]->setX(NEW_X > JAILGAMES_DEST_X ? JAILGAMES_DEST_X : NEW_X);
|
||||
}
|
||||
}
|
||||
jailgames_sprite_[i]->setX(new_x);
|
||||
}
|
||||
}
|
||||
|
||||
// Verifica si todas las líneas están en su posición destino
|
||||
auto Logo::allJailgamesLinesInPosition() const -> bool {
|
||||
// Iterar por todas las líneas (empezando desde 1, como en updateJAILGAMES)
|
||||
for (size_t i = 0; i < jailgames_sprite_.size(); ++i) {
|
||||
if (jailgames_sprite_[i]->getX() != JAILGAMES_DEST_X) {
|
||||
return false; // Al menos una línea no ha llegado
|
||||
}
|
||||
}
|
||||
return true; // Todas las líneas están en posición
|
||||
}
|
||||
|
||||
// Calcula el índice de color según el progreso (0.0-1.0)
|
||||
auto Logo::getColorIndex(float progress) const -> int {
|
||||
// Asegurar que progress esté en el rango [0.0, 1.0]
|
||||
@@ -157,7 +156,12 @@ void Logo::updateState(float delta_time) {
|
||||
break;
|
||||
|
||||
case State::JAILGAMES_SLIDE_IN:
|
||||
if (allJailgamesLinesInPosition()) {
|
||||
if (state_time_ >= JAILGAMES_SLIDE_DURATION) {
|
||||
// Garantizar que todas las líneas estén exactamente en la posición final
|
||||
// antes de transicionar (previene race condition con updateJAILGAMES)
|
||||
for (auto& sprite : jailgames_sprite_) {
|
||||
sprite->setX(JAILGAMES_DEST_X);
|
||||
}
|
||||
transitionToState(State::SINCE_1998_FADE_IN);
|
||||
}
|
||||
break;
|
||||
@@ -263,10 +267,18 @@ void Logo::initColors() {
|
||||
// Crea los sprites de cada linea
|
||||
void Logo::initSprites() {
|
||||
const float WIDTH = jailgames_surface_->getWidth();
|
||||
jailgames_initial_x_.reserve(jailgames_surface_->getHeight());
|
||||
|
||||
for (int i = 0; i < jailgames_surface_->getHeight(); ++i) {
|
||||
jailgames_sprite_.push_back(std::make_shared<SurfaceSprite>(jailgames_surface_, 0, i, jailgames_surface_->getWidth(), 1));
|
||||
jailgames_sprite_.back()->setClip(0, i, jailgames_surface_->getWidth(), 1);
|
||||
jailgames_sprite_.at(i)->setX((i % 2 == 0) ? (256 + (i * 3)) : (-WIDTH - (i * 3)));
|
||||
|
||||
// Calcular posición inicial (alternando entre derecha e izquierda)
|
||||
constexpr int LINE_OFFSET = 6;
|
||||
const int initial_x = (i % 2 == 0) ? (256 + (i * LINE_OFFSET)) : (static_cast<int>(-WIDTH) - (i * LINE_OFFSET));
|
||||
jailgames_initial_x_.push_back(initial_x);
|
||||
|
||||
jailgames_sprite_.at(i)->setX(initial_x);
|
||||
jailgames_sprite_.at(i)->setY(83 + i);
|
||||
}
|
||||
}
|
||||
@@ -2,8 +2,9 @@
|
||||
|
||||
#include <SDL3/SDL.h>
|
||||
|
||||
#include <memory> // Para shared_ptr
|
||||
#include <vector> // Para vector
|
||||
#include <functional> // Para std::function
|
||||
#include <memory> // Para shared_ptr
|
||||
#include <vector> // Para vector
|
||||
|
||||
#include "utils/delta_timer.hpp" // Para DeltaTimer
|
||||
class SurfaceSprite; // Forward declaration
|
||||
@@ -11,6 +12,9 @@ class Surface; // Forward declaration
|
||||
|
||||
class Logo {
|
||||
public:
|
||||
// --- Tipos ---
|
||||
using EasingFunction = std::function<float(float)>; // Función de easing (permite lambdas)
|
||||
|
||||
// --- Enumeraciones ---
|
||||
enum class State {
|
||||
INITIAL, // Espera inicial
|
||||
@@ -36,13 +40,14 @@ class Logo {
|
||||
static constexpr float FADE_OUT_DURATION = 0.5F; // Duración del fade-out final
|
||||
|
||||
// --- Constantes de animación ---
|
||||
static constexpr float JAILGAMES_SLIDE_SPEED = 350.0F; // Velocidad de slide-in (pixels/segundo)
|
||||
static constexpr int JAILGAMES_DEST_X = 37; // Posición X de destino para JAILGAMES
|
||||
static constexpr float JAILGAMES_SLIDE_DURATION = 0.8F; // Duración de la animación de slide-in (segundos)
|
||||
static constexpr int JAILGAMES_DEST_X = 37; // Posición X de destino para JAILGAMES
|
||||
|
||||
// --- Objetos y punteros ---
|
||||
std::shared_ptr<Surface> jailgames_surface_ = nullptr; // Textura con los graficos "JAILGAMES"
|
||||
std::shared_ptr<Surface> since_1998_surface_ = nullptr; // Textura con los graficos "Since 1998"
|
||||
std::vector<std::shared_ptr<SurfaceSprite>> jailgames_sprite_; // Vector con los sprites de cada linea que forman el bitmap JAILGAMES
|
||||
std::vector<int> jailgames_initial_x_; // Posiciones X iniciales de cada línea (para interpolación con easing)
|
||||
std::shared_ptr<SurfaceSprite> since_1998_sprite_ = nullptr; // SSprite para manejar la textura2
|
||||
Uint8 jailgames_color_ = 0; // Color para el sprite de "JAILGAMES"
|
||||
Uint8 since_1998_color_ = 0; // Color para el sprite de "Since 1998"
|
||||
@@ -52,6 +57,7 @@ class Logo {
|
||||
std::unique_ptr<DeltaTimer> delta_timer_ = nullptr; // Timer para delta time
|
||||
State state_ = State::INITIAL; // Estado actual de la secuencia
|
||||
float state_time_ = 0.0F; // Tiempo acumulado en el estado actual
|
||||
EasingFunction easing_function_; // Función de easing para la animación del logo
|
||||
|
||||
// --- Funciones ---
|
||||
void update(); // Actualiza las variables
|
||||
@@ -63,7 +69,6 @@ class Logo {
|
||||
void updateState(float delta_time); // Actualiza el estado actual
|
||||
void transitionToState(State new_state); // Transiciona a un nuevo estado
|
||||
[[nodiscard]] auto getColorIndex(float progress) const -> int; // Calcula el índice de color según el progreso (0.0-1.0)
|
||||
[[nodiscard]] auto allJailgamesLinesInPosition() const -> bool; // Verifica si todas las líneas están en su posición destino
|
||||
static void endSection(); // Termina la sección
|
||||
void initColors(); // Inicializa el vector de colores
|
||||
void initSprites(); // Crea los sprites de cada linea
|
||||
|
||||
273
source/utils/easing_functions.hpp
Normal file
273
source/utils/easing_functions.hpp
Normal file
@@ -0,0 +1,273 @@
|
||||
/**
|
||||
* @file easing_functions.hpp
|
||||
* @brief Colección de funciones de suavizado (easing) para animaciones
|
||||
*
|
||||
* Todas las funciones toman un parámetro t (0.0 a 1.0) que representa
|
||||
* el progreso de la animación y retornan el valor suavizado.
|
||||
*
|
||||
* Convenciones:
|
||||
* - In: Aceleración (slow -> fast)
|
||||
* - Out: Desaceleración (fast -> slow)
|
||||
* - InOut: Aceleración + Desaceleración (slow -> fast -> slow)
|
||||
*/
|
||||
|
||||
#ifndef EASING_FUNCTIONS_HPP
|
||||
#define EASING_FUNCTIONS_HPP
|
||||
|
||||
#include <cmath>
|
||||
|
||||
#ifndef M_PI
|
||||
#define M_PI 3.14159265358979323846
|
||||
#endif
|
||||
|
||||
namespace Easing {
|
||||
|
||||
// ============================================================================
|
||||
// LINEAR
|
||||
// ============================================================================
|
||||
|
||||
inline float linear(float t) {
|
||||
return t;
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// QUAD (Cuadrática: t^2)
|
||||
// ============================================================================
|
||||
|
||||
inline float quadIn(float t) {
|
||||
return t * t;
|
||||
}
|
||||
|
||||
inline float quadOut(float t) {
|
||||
return t * (2.0F - t);
|
||||
}
|
||||
|
||||
inline float quadInOut(float t) {
|
||||
if (t < 0.5F) {
|
||||
return 2.0F * t * t;
|
||||
}
|
||||
return -1.0F + (4.0F - 2.0F * t) * t;
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// CUBIC (Cúbica: t^3)
|
||||
// ============================================================================
|
||||
|
||||
inline float cubicIn(float t) {
|
||||
return t * t * t;
|
||||
}
|
||||
|
||||
inline float cubicOut(float t) {
|
||||
const float f = t - 1.0F;
|
||||
return f * f * f + 1.0F;
|
||||
}
|
||||
|
||||
inline float cubicInOut(float t) {
|
||||
if (t < 0.5F) {
|
||||
return 4.0F * t * t * t;
|
||||
}
|
||||
const float f = (2.0F * t - 2.0F);
|
||||
return 0.5F * f * f * f + 1.0F;
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// QUART (Cuártica: t^4)
|
||||
// ============================================================================
|
||||
|
||||
inline float quartIn(float t) {
|
||||
return t * t * t * t;
|
||||
}
|
||||
|
||||
inline float quartOut(float t) {
|
||||
const float f = t - 1.0F;
|
||||
return 1.0F - f * f * f * f;
|
||||
}
|
||||
|
||||
inline float quartInOut(float t) {
|
||||
if (t < 0.5F) {
|
||||
return 8.0F * t * t * t * t;
|
||||
}
|
||||
const float f = t - 1.0F;
|
||||
return 1.0F - 8.0F * f * f * f * f;
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// QUINT (Quíntica: t^5)
|
||||
// ============================================================================
|
||||
|
||||
inline float quintIn(float t) {
|
||||
return t * t * t * t * t;
|
||||
}
|
||||
|
||||
inline float quintOut(float t) {
|
||||
const float f = t - 1.0F;
|
||||
return f * f * f * f * f + 1.0F;
|
||||
}
|
||||
|
||||
inline float quintInOut(float t) {
|
||||
if (t < 0.5F) {
|
||||
return 16.0F * t * t * t * t * t;
|
||||
}
|
||||
const float f = (2.0F * t - 2.0F);
|
||||
return 0.5F * f * f * f * f * f + 1.0F;
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// SINE (Sinusoidal)
|
||||
// ============================================================================
|
||||
|
||||
inline float sineIn(float t) {
|
||||
return 1.0F - std::cos(t * static_cast<float>(M_PI) * 0.5F);
|
||||
}
|
||||
|
||||
inline float sineOut(float t) {
|
||||
return std::sin(t * static_cast<float>(M_PI) * 0.5F);
|
||||
}
|
||||
|
||||
inline float sineInOut(float t) {
|
||||
return 0.5F * (1.0F - std::cos(static_cast<float>(M_PI) * t));
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// EXPO (Exponencial)
|
||||
// ============================================================================
|
||||
|
||||
inline float expoIn(float t) {
|
||||
if (t == 0.0F) return 0.0F;
|
||||
return std::pow(2.0F, 10.0F * (t - 1.0F));
|
||||
}
|
||||
|
||||
inline float expoOut(float t) {
|
||||
if (t == 1.0F) return 1.0F;
|
||||
return 1.0F - std::pow(2.0F, -10.0F * t);
|
||||
}
|
||||
|
||||
inline float expoInOut(float t) {
|
||||
if (t == 0.0F || t == 1.0F) return t;
|
||||
|
||||
if (t < 0.5F) {
|
||||
return 0.5F * std::pow(2.0F, (20.0F * t) - 10.0F);
|
||||
}
|
||||
return 0.5F * (2.0F - std::pow(2.0F, -20.0F * t + 10.0F));
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// CIRC (Circular)
|
||||
// ============================================================================
|
||||
|
||||
inline float circIn(float t) {
|
||||
return 1.0F - std::sqrt(1.0F - t * t);
|
||||
}
|
||||
|
||||
inline float circOut(float t) {
|
||||
const float f = t - 1.0F;
|
||||
return std::sqrt(1.0F - f * f);
|
||||
}
|
||||
|
||||
inline float circInOut(float t) {
|
||||
if (t < 0.5F) {
|
||||
return 0.5F * (1.0F - std::sqrt(1.0F - 4.0F * t * t));
|
||||
}
|
||||
const float f = 2.0F * t - 2.0F;
|
||||
return 0.5F * (std::sqrt(1.0F - f * f) + 1.0F);
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// BACK (Overshoot - retrocede antes de avanzar)
|
||||
// ============================================================================
|
||||
|
||||
inline float backIn(float t, float overshoot = 1.70158F) {
|
||||
return t * t * ((overshoot + 1.0F) * t - overshoot);
|
||||
}
|
||||
|
||||
inline float backOut(float t, float overshoot = 1.70158F) {
|
||||
const float f = t - 1.0F;
|
||||
return f * f * ((overshoot + 1.0F) * f + overshoot) + 1.0F;
|
||||
}
|
||||
|
||||
inline float backInOut(float t, float overshoot = 1.70158F) {
|
||||
const float s = overshoot * 1.525F;
|
||||
|
||||
if (t < 0.5F) {
|
||||
const float f = 2.0F * t;
|
||||
return 0.5F * (f * f * ((s + 1.0F) * f - s));
|
||||
}
|
||||
|
||||
const float f = 2.0F * t - 2.0F;
|
||||
return 0.5F * (f * f * ((s + 1.0F) * f + s) + 2.0F);
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// ELASTIC (Oscilación elástica - efecto de resorte)
|
||||
// ============================================================================
|
||||
|
||||
inline float elasticIn(float t, float amplitude = 1.0F, float period = 0.3F) {
|
||||
if (t == 0.0F || t == 1.0F) return t;
|
||||
|
||||
const float s = period / (2.0F * static_cast<float>(M_PI)) * std::asin(1.0F / amplitude);
|
||||
const float f = t - 1.0F;
|
||||
return -(amplitude * std::pow(2.0F, 10.0F * f) *
|
||||
std::sin((f - s) * (2.0F * static_cast<float>(M_PI)) / period));
|
||||
}
|
||||
|
||||
inline float elasticOut(float t, float amplitude = 1.0F, float period = 0.3F) {
|
||||
if (t == 0.0F || t == 1.0F) return t;
|
||||
|
||||
const float s = period / (2.0F * static_cast<float>(M_PI)) * std::asin(1.0F / amplitude);
|
||||
return amplitude * std::pow(2.0F, -10.0F * t) *
|
||||
std::sin((t - s) * (2.0F * static_cast<float>(M_PI)) / period) + 1.0F;
|
||||
}
|
||||
|
||||
inline float elasticInOut(float t, float amplitude = 1.0F, float period = 0.3F) {
|
||||
if (t == 0.0F || t == 1.0F) return t;
|
||||
|
||||
const float s = period / (2.0F * static_cast<float>(M_PI)) * std::asin(1.0F / amplitude);
|
||||
|
||||
if (t < 0.5F) {
|
||||
const float f = 2.0F * t - 1.0F;
|
||||
return -0.5F * (amplitude * std::pow(2.0F, 10.0F * f) *
|
||||
std::sin((f - s) * (2.0F * static_cast<float>(M_PI)) / period));
|
||||
}
|
||||
|
||||
const float f = 2.0F * t - 1.0F;
|
||||
return 0.5F * amplitude * std::pow(2.0F, -10.0F * f) *
|
||||
std::sin((f - s) * (2.0F * static_cast<float>(M_PI)) / period) + 1.0F;
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// BOUNCE (Rebote - simula física de rebote)
|
||||
// ============================================================================
|
||||
|
||||
inline float bounceOut(float t) {
|
||||
const float n1 = 7.5625F;
|
||||
const float d1 = 2.75F;
|
||||
|
||||
if (t < 1.0F / d1) {
|
||||
return n1 * t * t;
|
||||
}
|
||||
if (t < 2.0F / d1) {
|
||||
const float f = t - 1.5F / d1;
|
||||
return n1 * f * f + 0.75F;
|
||||
}
|
||||
if (t < 2.5F / d1) {
|
||||
const float f = t - 2.25F / d1;
|
||||
return n1 * f * f + 0.9375F;
|
||||
}
|
||||
const float f = t - 2.625F / d1;
|
||||
return n1 * f * f + 0.984375F;
|
||||
}
|
||||
|
||||
inline float bounceIn(float t) {
|
||||
return 1.0F - bounceOut(1.0F - t);
|
||||
}
|
||||
|
||||
inline float bounceInOut(float t) {
|
||||
if (t < 0.5F) {
|
||||
return 0.5F * bounceIn(2.0F * t);
|
||||
}
|
||||
return 0.5F * bounceOut(2.0F * t - 1.0F) + 0.5F;
|
||||
}
|
||||
|
||||
} // namespace Easing
|
||||
|
||||
#endif // EASING_FUNCTIONS_HPP
|
||||
Reference in New Issue
Block a user