From db3cb06c7a223f41caf0607dd69439e0bad93cd1 Mon Sep 17 00:00:00 2001 From: Sergio Valor Date: Sun, 12 Apr 2026 15:42:13 +0200 Subject: [PATCH] la consola ja no va per velocitat sino per temps --- source/game/ui/console.cpp | 59 ++++++++++++++++++++++++-------------- source/game/ui/console.hpp | 11 +++++-- 2 files changed, 46 insertions(+), 24 deletions(-) diff --git a/source/game/ui/console.cpp b/source/game/ui/console.cpp index eab308f..f90b1e6 100644 --- a/source/game/ui/console.cpp +++ b/source/game/ui/console.cpp @@ -8,6 +8,7 @@ #include // Para string #include // Para vector +#include "core/input/key_config.hpp" // Para KeyConfig #include "core/rendering/screen.hpp" // Para Screen #include "core/rendering/sprite/sprite.hpp" // Para Sprite #include "core/rendering/surface.hpp" // Para Surface @@ -15,6 +16,7 @@ #include "core/resources/resource_cache.hpp" // Para Resource #include "game/options.hpp" // Para Options #include "game/ui/notifier.hpp" // Para Notifier +#include "utils/easing_functions.hpp" // Para Easing::cubicInOut // ── Helpers de texto ────────────────────────────────────────────────────────── @@ -220,11 +222,17 @@ void Console::update(float delta_time) { // NOLINT(readability-function-cogniti // Animación de altura (resize cuando msg_lines_ cambia); solo en ACTIVE if (status_ == Status::ACTIVE && height_ != target_height_) { + if (anim_progress_ == 0.0F) { + // Iniciar animación de resize + anim_start_ = height_; + anim_end_ = target_height_; + } + anim_progress_ = std::min(anim_progress_ + (delta_time / ANIM_DURATION), 1.0F); const float PREV_HEIGHT = height_; - if (height_ < target_height_) { - height_ = std::min(height_ + (SLIDE_SPEED * delta_time), target_height_); - } else { - height_ = std::max(height_ - (SLIDE_SPEED * delta_time), target_height_); + height_ = anim_start_ + ((anim_end_ - anim_start_) * Easing::cubicInOut(anim_progress_)); + if (anim_progress_ >= 1.0F) { + height_ = target_height_; + anim_progress_ = 0.0F; } // Actualizar el Notifier incrementalmente con el delta de altura if (Notifier::get() != nullptr) { @@ -246,28 +254,22 @@ void Console::update(float delta_time) { // NOLINT(readability-function-cogniti // Redibujar texto cada frame redrawText(); - switch (status_) { - case Status::RISING: { - y_ += SLIDE_SPEED * delta_time; - if (y_ >= 0.0F) { - y_ = 0.0F; + // Animación de apertura/cierre (basada en tiempo) + if (status_ == Status::RISING || status_ == Status::VANISHING) { + anim_progress_ = std::min(anim_progress_ + (delta_time / ANIM_DURATION), 1.0F); + y_ = anim_start_ + ((anim_end_ - anim_start_) * Easing::cubicInOut(anim_progress_)); + + if (anim_progress_ >= 1.0F) { + y_ = anim_end_; + anim_progress_ = 0.0F; + if (status_ == Status::RISING) { status_ = Status::ACTIVE; - } - break; - } - case Status::VANISHING: { - y_ -= SLIDE_SPEED * delta_time; - if (y_ <= -height_) { - y_ = -height_; + } else { status_ = Status::HIDDEN; - // Resetear el mensaje una vez completamente oculta msg_lines_ = {std::string(CONSOLE_NAME) + " " + std::string(CONSOLE_VERSION)}; target_height_ = calcTargetHeight(static_cast(msg_lines_.size())); } - break; } - default: - break; } SDL_FRect rect = {.x = 0, .y = y_, .w = Options::game.width, .h = height_}; @@ -291,6 +293,9 @@ void Console::toggle() { target_height_ = calcTargetHeight(static_cast(msg_lines_.size())); height_ = target_height_; y_ = -height_; + anim_start_ = y_; + anim_end_ = 0.0F; + anim_progress_ = 0.0F; status_ = Status::RISING; input_line_.clear(); cursor_timer_ = 0.0F; @@ -308,8 +313,11 @@ void Console::toggle() { break; case Status::ACTIVE: // Al cerrar: mantener el texto visible hasta que esté completamente oculta + anim_start_ = y_; + anim_end_ = -height_; + anim_progress_ = 0.0F; status_ = Status::VANISHING; - target_height_ = height_; // No animar durante VANISHING + target_height_ = height_; // No animar altura durante VANISHING history_index_ = -1; saved_input_.clear(); SDL_StopTextInput(SDL_GetKeyboardFocus()); @@ -332,6 +340,15 @@ void Console::handleEvent(const SDL_Event& event) { // NOLINT(readability-funct if (event.type == SDL_EVENT_TEXT_INPUT) { // Filtrar caracteres de control (tab, newline, etc.) if (static_cast(event.text.text[0]) < 32) { return; } + // Ignorar texto si la tecla toggle está pulsada (evita escribir su carácter) + if (KeyConfig::get() != nullptr) { + SDL_Keycode toggle_key = KeyConfig::get()->key("GLOBAL", "console"); + SDL_Scancode toggle_sc = SDL_GetScancodeFromKey(toggle_key, nullptr); + if (toggle_sc != SDL_SCANCODE_UNKNOWN) { + const bool* ks = SDL_GetKeyboardState(nullptr); + if (ks[toggle_sc]) { return; } + } + } if (static_cast(input_line_.size()) < MAX_LINE_CHARS) { input_line_ += event.text.text; } diff --git a/source/game/ui/console.hpp b/source/game/ui/console.hpp index 3bef90b..9a779d7 100644 --- a/source/game/ui/console.hpp +++ b/source/game/ui/console.hpp @@ -56,16 +56,16 @@ class Console { }; // Constantes visuales - static constexpr float SLIDE_SPEED = 180.0F; + static constexpr float ANIM_DURATION = 0.3F; // Duración de cualquier animación (segundos) // Constantes de consola static constexpr std::string_view CONSOLE_NAME = "Projecte 2026 Console"; - static constexpr std::string_view CONSOLE_VERSION = "v2.3"; + static constexpr std::string_view CONSOLE_VERSION = "v2.4"; static constexpr int MAX_LINE_CHARS = 32; static constexpr int MAX_HISTORY_SIZE = 20; static constexpr float CURSOR_ON_TIME = 0.5F; static constexpr float CURSOR_OFF_TIME = 0.3F; - static constexpr float TYPEWRITER_CHAR_DELAY = 0.01F; // segundos entre letra y letra + static constexpr float TYPEWRITER_CHAR_DELAY = 0.008F; // segundos entre letra y letra // [SINGLETON] static Console* console; @@ -101,6 +101,11 @@ class Console { int typewriter_chars_{0}; // Caracteres de msg_lines_ actualmente visibles float typewriter_timer_{0.0F}; + // Animación basada en tiempo (0→1 en ANIM_DURATION) + float anim_progress_{0.0F}; // Progreso normalizado [0, 1] + float anim_start_{0.0F}; // Valor inicial (y_ o height_) + float anim_end_{0.0F}; // Valor final + // Animación de altura dinámica float target_height_{0.0F}; // Altura objetivo (según número de líneas de mensaje) int notifier_offset_applied_{0}; // Acumulador del offset enviado al Notifier