la consola ja no va per velocitat sino per temps

This commit is contained in:
2026-04-12 15:42:13 +02:00
parent 848b658611
commit db3cb06c7a
2 changed files with 46 additions and 24 deletions

View File

@@ -8,6 +8,7 @@
#include <string> // Para string #include <string> // Para string
#include <vector> // Para vector #include <vector> // Para vector
#include "core/input/key_config.hpp" // Para KeyConfig
#include "core/rendering/screen.hpp" // Para Screen #include "core/rendering/screen.hpp" // Para Screen
#include "core/rendering/sprite/sprite.hpp" // Para Sprite #include "core/rendering/sprite/sprite.hpp" // Para Sprite
#include "core/rendering/surface.hpp" // Para Surface #include "core/rendering/surface.hpp" // Para Surface
@@ -15,6 +16,7 @@
#include "core/resources/resource_cache.hpp" // Para Resource #include "core/resources/resource_cache.hpp" // Para Resource
#include "game/options.hpp" // Para Options #include "game/options.hpp" // Para Options
#include "game/ui/notifier.hpp" // Para Notifier #include "game/ui/notifier.hpp" // Para Notifier
#include "utils/easing_functions.hpp" // Para Easing::cubicInOut
// ── Helpers de texto ────────────────────────────────────────────────────────── // ── 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 // Animación de altura (resize cuando msg_lines_ cambia); solo en ACTIVE
if (status_ == Status::ACTIVE && height_ != target_height_) { 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_; const float PREV_HEIGHT = height_;
if (height_ < target_height_) { height_ = anim_start_ + ((anim_end_ - anim_start_) * Easing::cubicInOut(anim_progress_));
height_ = std::min(height_ + (SLIDE_SPEED * delta_time), target_height_); if (anim_progress_ >= 1.0F) {
} else { height_ = target_height_;
height_ = std::max(height_ - (SLIDE_SPEED * delta_time), target_height_); anim_progress_ = 0.0F;
} }
// Actualizar el Notifier incrementalmente con el delta de altura // Actualizar el Notifier incrementalmente con el delta de altura
if (Notifier::get() != nullptr) { if (Notifier::get() != nullptr) {
@@ -246,28 +254,22 @@ void Console::update(float delta_time) { // NOLINT(readability-function-cogniti
// Redibujar texto cada frame // Redibujar texto cada frame
redrawText(); redrawText();
switch (status_) { // Animación de apertura/cierre (basada en tiempo)
case Status::RISING: { if (status_ == Status::RISING || status_ == Status::VANISHING) {
y_ += SLIDE_SPEED * delta_time; anim_progress_ = std::min(anim_progress_ + (delta_time / ANIM_DURATION), 1.0F);
if (y_ >= 0.0F) { y_ = anim_start_ + ((anim_end_ - anim_start_) * Easing::cubicInOut(anim_progress_));
y_ = 0.0F;
if (anim_progress_ >= 1.0F) {
y_ = anim_end_;
anim_progress_ = 0.0F;
if (status_ == Status::RISING) {
status_ = Status::ACTIVE; status_ = Status::ACTIVE;
} } else {
break;
}
case Status::VANISHING: {
y_ -= SLIDE_SPEED * delta_time;
if (y_ <= -height_) {
y_ = -height_;
status_ = Status::HIDDEN; status_ = Status::HIDDEN;
// Resetear el mensaje una vez completamente oculta
msg_lines_ = {std::string(CONSOLE_NAME) + " " + std::string(CONSOLE_VERSION)}; msg_lines_ = {std::string(CONSOLE_NAME) + " " + std::string(CONSOLE_VERSION)};
target_height_ = calcTargetHeight(static_cast<int>(msg_lines_.size())); target_height_ = calcTargetHeight(static_cast<int>(msg_lines_.size()));
} }
break;
} }
default:
break;
} }
SDL_FRect rect = {.x = 0, .y = y_, .w = Options::game.width, .h = height_}; 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<int>(msg_lines_.size())); target_height_ = calcTargetHeight(static_cast<int>(msg_lines_.size()));
height_ = target_height_; height_ = target_height_;
y_ = -height_; y_ = -height_;
anim_start_ = y_;
anim_end_ = 0.0F;
anim_progress_ = 0.0F;
status_ = Status::RISING; status_ = Status::RISING;
input_line_.clear(); input_line_.clear();
cursor_timer_ = 0.0F; cursor_timer_ = 0.0F;
@@ -308,8 +313,11 @@ void Console::toggle() {
break; break;
case Status::ACTIVE: case Status::ACTIVE:
// Al cerrar: mantener el texto visible hasta que esté completamente oculta // Al cerrar: mantener el texto visible hasta que esté completamente oculta
anim_start_ = y_;
anim_end_ = -height_;
anim_progress_ = 0.0F;
status_ = Status::VANISHING; status_ = Status::VANISHING;
target_height_ = height_; // No animar durante VANISHING target_height_ = height_; // No animar altura durante VANISHING
history_index_ = -1; history_index_ = -1;
saved_input_.clear(); saved_input_.clear();
SDL_StopTextInput(SDL_GetKeyboardFocus()); 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) { if (event.type == SDL_EVENT_TEXT_INPUT) {
// Filtrar caracteres de control (tab, newline, etc.) // Filtrar caracteres de control (tab, newline, etc.)
if (static_cast<unsigned char>(event.text.text[0]) < 32) { return; } if (static_cast<unsigned char>(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<int>(input_line_.size()) < MAX_LINE_CHARS) { if (static_cast<int>(input_line_.size()) < MAX_LINE_CHARS) {
input_line_ += event.text.text; input_line_ += event.text.text;
} }

View File

@@ -56,16 +56,16 @@ class Console {
}; };
// Constantes visuales // 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 // Constantes de consola
static constexpr std::string_view CONSOLE_NAME = "Projecte 2026 Console"; 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_LINE_CHARS = 32;
static constexpr int MAX_HISTORY_SIZE = 20; static constexpr int MAX_HISTORY_SIZE = 20;
static constexpr float CURSOR_ON_TIME = 0.5F; static constexpr float CURSOR_ON_TIME = 0.5F;
static constexpr float CURSOR_OFF_TIME = 0.3F; 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] // [SINGLETON]
static Console* console; static Console* console;
@@ -101,6 +101,11 @@ class Console {
int typewriter_chars_{0}; // Caracteres de msg_lines_ actualmente visibles int typewriter_chars_{0}; // Caracteres de msg_lines_ actualmente visibles
float typewriter_timer_{0.0F}; 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 // Animación de altura dinámica
float target_height_{0.0F}; // Altura objetivo (según número de líneas de mensaje) 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 int notifier_offset_applied_{0}; // Acumulador del offset enviado al Notifier