ja es pot escriure en la consola

This commit is contained in:
2026-03-27 22:54:47 +01:00
parent f25ee18329
commit e85800c5ed
5 changed files with 125 additions and 21 deletions

View File

@@ -445,7 +445,7 @@ void Screen::renderInfo() const {
const int LINE_HEIGHT = text_->getCharacterSize() - 3; const int LINE_HEIGHT = text_->getCharacterSize() - 3;
const int X = 0; const int X = 0;
int y = 0; int y = (Console::get() != nullptr) ? Console::get()->getVisibleHeight() : 0;
// FPS // FPS
const std::string FPS_TEXT = std::to_string(fps_.last_value) + " fps"; const std::string FPS_TEXT = std::to_string(fps_.last_value) + " fps";

View File

@@ -3,6 +3,7 @@
#include "core/input/mouse.hpp" #include "core/input/mouse.hpp"
#include "game/options.hpp" // Para Options, options, OptionsGame, OptionsAudio #include "game/options.hpp" // Para Options, options, OptionsGame, OptionsAudio
#include "game/scene_manager.hpp" // Para SceneManager #include "game/scene_manager.hpp" // Para SceneManager
#include "game/ui/console.hpp" // Para Console
namespace GlobalEvents { namespace GlobalEvents {
// Comprueba los eventos que se pueden producir en cualquier sección del juego // Comprueba los eventos que se pueden producir en cualquier sección del juego
@@ -17,6 +18,14 @@ namespace GlobalEvents {
// reLoadTextures(); // reLoadTextures();
} }
// Enrutar eventos de texto a la consola cuando está activa
if (Console::get() != nullptr && Console::get()->isActive()) {
if (event.type == SDL_EVENT_TEXT_INPUT || event.type == SDL_EVENT_KEY_DOWN) {
Console::get()->handleEvent(event);
return;
}
}
Mouse::handleEvent(event); Mouse::handleEvent(event);
} }
} // namespace GlobalEvents } // namespace GlobalEvents

View File

@@ -25,6 +25,7 @@
#include "game/gameplay/stats.hpp" // Para Stats #include "game/gameplay/stats.hpp" // Para Stats
#include "game/options.hpp" // Para Options, options, Cheat, SectionState #include "game/options.hpp" // Para Options, options, Cheat, SectionState
#include "game/scene_manager.hpp" // Para SceneManager #include "game/scene_manager.hpp" // Para SceneManager
#include "game/ui/console.hpp" // Para Console
#include "game/ui/notifier.hpp" // Para Notifier, NotificationText, CHEEVO_NO... #include "game/ui/notifier.hpp" // Para Notifier, NotificationText, CHEEVO_NO...
#include "utils/defines.hpp" // Para Tile::SIZE, PlayArea::HEIGHT, RoomBorder::BOTTOM #include "utils/defines.hpp" // Para Tile::SIZE, PlayArea::HEIGHT, RoomBorder::BOTTOM
#include "utils/utils.hpp" // Para PaletteColor, stringToColor #include "utils/utils.hpp" // Para PaletteColor, stringToColor
@@ -71,7 +72,9 @@ void Game::handleEvents() {
while (SDL_PollEvent(&event)) { while (SDL_PollEvent(&event)) {
GlobalEvents::handle(event); GlobalEvents::handle(event);
#ifdef _DEBUG #ifdef _DEBUG
if (!Console::get()->isActive()) {
handleDebugEvents(event); handleDebugEvents(event);
}
#endif #endif
} }
} }
@@ -87,6 +90,12 @@ void Game::handleInput() {
Notifier::get()->show({scoreboard_data_->music ? Locale::get()->get("game.music_enabled") : Locale::get()->get("game.music_disabled")}); Notifier::get()->show({scoreboard_data_->music ? Locale::get()->get("game.music_enabled") : Locale::get()->get("game.music_disabled")});
} }
// Si la consola está activa, no procesar inputs del juego
if (Console::get()->isActive()) {
GlobalInputs::handle();
return;
}
// Durante fade/postfade, solo procesar inputs globales // Durante fade/postfade, solo procesar inputs globales
if (state_ != State::PLAYING) { if (state_ != State::PLAYING) {
GlobalInputs::handle(); GlobalInputs::handle();
@@ -163,6 +172,7 @@ void Game::updatePlaying(float delta_time) {
room_->update(delta_time); room_->update(delta_time);
switch (mode_) { switch (mode_) {
case Mode::GAME: case Mode::GAME:
if (!Console::get()->isActive()) {
#ifdef _DEBUG #ifdef _DEBUG
// Maneja el arrastre del jugador con el ratón (debug) // Maneja el arrastre del jugador con el ratón (debug)
handleDebugMouseDrag(delta_time); handleDebugMouseDrag(delta_time);
@@ -174,6 +184,7 @@ void Game::updatePlaying(float delta_time) {
#else #else
player_->update(delta_time); player_->update(delta_time);
#endif #endif
}
checkPlayerIsOnBorder(); checkPlayerIsOnBorder();
checkPlayerAndItems(); checkPlayerAndItems();
checkPlayerAndEnemies(); checkPlayerAndEnemies();

View File

@@ -47,6 +47,21 @@ void Console::buildSurface() {
surface_ = std::make_shared<Surface>(WIDTH, height_); surface_ = std::make_shared<Surface>(WIDTH, height_);
// Posición inicial (fuera de pantalla por arriba)
SDL_FRect sprite_rect = {.x = 0, .y = y_, .w = WIDTH, .h = height_};
sprite_ = std::make_shared<Sprite>(surface_, sprite_rect);
// Dibujo inicial del texto
redrawText();
}
// Redibuja el texto dinámico sobre la surface (fondo + borde + líneas)
void Console::redrawText() {
const float WIDTH = Options::game.width;
const int TEXT_SIZE = 6;
const int PADDING_IN_H = TEXT_SIZE;
const int PADDING_IN_V = TEXT_SIZE / 2;
auto previous_renderer = Screen::get()->getRendererSurface(); auto previous_renderer = Screen::get()->getRendererSurface();
Screen::get()->setRendererSurface(surface_); Screen::get()->setRendererSurface(surface_);
@@ -55,17 +70,15 @@ void Console::buildSurface() {
SDL_FRect rect = {.x = 0, .y = 0, .w = WIDTH, .h = height_}; SDL_FRect rect = {.x = 0, .y = 0, .w = WIDTH, .h = height_};
surface_->drawRectBorder(&rect, BORDER_COLOR); surface_->drawRectBorder(&rect, BORDER_COLOR);
// Texto de marcador de posición // Línea 1: mensajes
const int TEXT_SIZE = 6; text_->writeColored(PADDING_IN_H, PADDING_IN_V, msg_line_, MSG_COLOR);
const int PADDING_IN_H = TEXT_SIZE;
const int PADDING_IN_V = TEXT_SIZE / 2; // Línea 2: prompt + input + cursor
text_->writeColored(PADDING_IN_H, PADDING_IN_V, "> _", BORDER_COLOR); const bool SHOW_CURSOR = cursor_visible_ && (static_cast<int>(input_line_.size()) < MAX_INPUT_CHARS);
const std::string INPUT_STR = "> " + input_line_ + (SHOW_CURSOR ? "_" : "");
text_->writeColored(PADDING_IN_H, PADDING_IN_V + TEXT_SIZE, INPUT_STR, BORDER_COLOR);
Screen::get()->setRendererSurface(previous_renderer); Screen::get()->setRendererSurface(previous_renderer);
// Posición inicial (fuera de pantalla por arriba)
SDL_FRect sprite_rect = {.x = 0, .y = y_, .w = WIDTH, .h = height_};
sprite_ = std::make_shared<Sprite>(surface_, sprite_rect);
} }
// Actualiza la animación de la consola // Actualiza la animación de la consola
@@ -74,6 +87,19 @@ void Console::update(float delta_time) {
return; return;
} }
// Parpadeo del cursor (solo cuando activa)
if (status_ == Status::ACTIVE) {
cursor_timer_ += delta_time;
const float THRESHOLD = cursor_visible_ ? CURSOR_ON_TIME : CURSOR_OFF_TIME;
if (cursor_timer_ >= THRESHOLD) {
cursor_timer_ = 0.0F;
cursor_visible_ = !cursor_visible_;
}
}
// Redibujar texto cada frame
redrawText();
switch (status_) { switch (status_) {
case Status::RISING: { case Status::RISING: {
y_ += SLIDE_SPEED * delta_time; y_ += SLIDE_SPEED * delta_time;
@@ -112,9 +138,14 @@ void Console::toggle() {
switch (status_) { switch (status_) {
case Status::HIDDEN: case Status::HIDDEN:
status_ = Status::RISING; status_ = Status::RISING;
input_line_.clear();
cursor_timer_ = 0.0F;
cursor_visible_ = true;
SDL_StartTextInput(SDL_GetKeyboardFocus());
break; break;
case Status::ACTIVE: case Status::ACTIVE:
status_ = Status::VANISHING; status_ = Status::VANISHING;
SDL_StopTextInput(SDL_GetKeyboardFocus());
break; break;
default: default:
// Durante RISING o VANISHING no se hace nada // Durante RISING o VANISHING no se hace nada
@@ -122,7 +153,44 @@ void Console::toggle() {
} }
} }
// Procesa el evento SDL: entrada de texto, Backspace, Enter
void Console::handleEvent(const SDL_Event& event) {
if (status_ != Status::ACTIVE) { return; }
if (event.type == SDL_EVENT_TEXT_INPUT) {
if (static_cast<int>(input_line_.size()) < MAX_INPUT_CHARS) {
input_line_ += event.text.text;
}
return;
}
if (event.type == SDL_EVENT_KEY_DOWN) {
if (event.key.scancode == SDL_SCANCODE_BACKSPACE && !input_line_.empty()) {
input_line_.pop_back();
} else if (event.key.scancode == SDL_SCANCODE_RETURN ||
event.key.scancode == SDL_SCANCODE_KP_ENTER) {
processCommand();
}
}
}
// Ejecuta el comando introducido y reinicia la línea de input
void Console::processCommand() {
if (!input_line_.empty()) {
msg_line_ = "OK";
}
input_line_.clear();
cursor_timer_ = 0.0F;
cursor_visible_ = true;
}
// Indica si la consola está activa (visible o en animación) // Indica si la consola está activa (visible o en animación)
auto Console::isActive() -> bool { auto Console::isActive() -> bool {
return status_ != Status::HIDDEN; return status_ != Status::HIDDEN;
} }
// Devuelve los píxeles visibles de la consola (sincronizado con la animación)
auto Console::getVisibleHeight() -> int {
if (status_ == Status::HIDDEN) { return 0; }
return static_cast<int>(y_ + height_);
}

View File

@@ -20,9 +20,11 @@ class Console {
void update(float delta_time); void update(float delta_time);
void render(); void render();
void toggle(); void toggle();
void handleEvent(const SDL_Event& event);
// Consultas // Consultas
auto isActive() -> bool; // true si RISING, ACTIVE o VANISHING auto isActive() -> bool; // true si RISING, ACTIVE o VANISHING
auto getVisibleHeight() -> int; // Píxeles visibles actuales (0 = oculta, height_ = totalmente visible)
private: private:
enum class Status { enum class Status {
@@ -35,8 +37,14 @@ class Console {
// Constantes visuales // Constantes visuales
static constexpr Uint8 BG_COLOR = 0; // PaletteColor::BLACK static constexpr Uint8 BG_COLOR = 0; // PaletteColor::BLACK
static constexpr Uint8 BORDER_COLOR = 9; // PaletteColor::BRIGHT_GREEN static constexpr Uint8 BORDER_COLOR = 9; // PaletteColor::BRIGHT_GREEN
static constexpr Uint8 MSG_COLOR = 8; // PaletteColor::GREEN
static constexpr float SLIDE_SPEED = 120.0F; static constexpr float SLIDE_SPEED = 120.0F;
// Constantes de entrada
static constexpr int MAX_INPUT_CHARS = 28;
static constexpr float CURSOR_ON_TIME = 0.5F;
static constexpr float CURSOR_OFF_TIME = 0.3F;
// [SINGLETON] // [SINGLETON]
static Console* console; static Console* console;
@@ -46,6 +54,8 @@ class Console {
// Métodos privados // Métodos privados
void buildSurface(); // Crea la Surface con el aspecto visual void buildSurface(); // Crea la Surface con el aspecto visual
void redrawText(); // Redibuja el texto dinámico (msg + input + cursor)
void processCommand(); // Procesa el comando introducido por el usuario
// Objetos de renderizado // Objetos de renderizado
std::shared_ptr<Text> text_; std::shared_ptr<Text> text_;
@@ -56,4 +66,10 @@ class Console {
Status status_{Status::HIDDEN}; Status status_{Status::HIDDEN};
float y_{0.0F}; // Posición Y actual (animada) float y_{0.0F}; // Posición Y actual (animada)
float height_{0.0F}; // Altura del panel float height_{0.0F}; // Altura del panel
// Estado de la entrada de texto
std::string msg_line_{"JDD CONSOLE V1.0"};
std::string input_line_;
float cursor_timer_{0.0F};
bool cursor_visible_{true};
}; };