From 9cf45062a386f0916031162872a60aa4f3418554 Mon Sep 17 00:00:00 2001 From: Sergio Date: Wed, 12 Nov 2025 13:47:19 +0100 Subject: [PATCH] =?UTF-8?q?netejant=20cap=C3=A7aleres?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .claude/settings.local.json | 4 +- source/core/rendering/screen.cpp | 2 +- source/core/rendering/text.cpp | 60 +-- source/core/rendering/text.hpp | 106 ++-- source/core/rendering/texture.hpp | 70 +-- source/core/resources/resource_cache.cpp | 8 +- source/core/resources/resource_cache.hpp | 10 +- source/core/system/debug.hpp | 45 +- source/game/entities/enemy.hpp | 68 +-- source/game/entities/item.cpp | 3 +- source/game/entities/item.hpp | 37 +- source/game/entities/player.cpp.bak | 628 ----------------------- source/game/entities/player.hpp.bak | 171 ------ source/game/entities/player.md | 132 ----- source/game/scenes/credits.cpp | 6 +- source/game/scenes/ending.cpp | 4 +- source/game/scenes/ending2.cpp | 6 +- source/game/scenes/game.cpp | 4 +- source/game/scenes/game_over.cpp | 12 +- source/game/scenes/title.cpp | 42 +- source/game/ui/notifier.cpp | 4 +- 21 files changed, 198 insertions(+), 1224 deletions(-) delete mode 100644 source/game/entities/player.cpp.bak delete mode 100644 source/game/entities/player.hpp.bak delete mode 100644 source/game/entities/player.md diff --git a/.claude/settings.local.json b/.claude/settings.local.json index 8579bab1..deb7a8de 100644 --- a/.claude/settings.local.json +++ b/.claude/settings.local.json @@ -4,7 +4,9 @@ "Bash(cmake --build:*)", "Bash(test:*)", "Bash(tools/linter/run_clang-tidy.sh:*)", - "Bash(make resources.pack:*)" + "Bash(make resources.pack:*)", + "Bash(tools/linter/run_cppcheck.sh:*)", + "Bash(cat:*)" ], "deny": [], "ask": [] diff --git a/source/core/rendering/screen.cpp b/source/core/rendering/screen.cpp index cee27059..8acc03ca 100644 --- a/source/core/rendering/screen.cpp +++ b/source/core/rendering/screen.cpp @@ -345,7 +345,7 @@ void Screen::renderInfo() { // FPS const std::string FPS_TEXT = std::to_string(fps_.last_value) + " FPS"; - text->writeColored(Options::game.width - text->lenght(FPS_TEXT), 0, FPS_TEXT, color); + text->writeColored(Options::game.width - text->length(FPS_TEXT), 0, FPS_TEXT, color); // Resolution text->writeColored(0, 0, info_resolution_, color); diff --git a/source/core/rendering/text.cpp b/source/core/rendering/text.cpp index 9726247d..e1bd377b 100644 --- a/source/core/rendering/text.cpp +++ b/source/core/rendering/text.cpp @@ -15,17 +15,10 @@ #include "utils/utils.hpp" // Para getFileName, stringToColor, printWithDots // Llena una estructuta TextFile desde un fichero -auto loadTextFile(const std::string& file_path) -> std::shared_ptr { - auto tf = std::make_shared(); +auto Text::loadTextFile(const std::string& file_path) -> std::shared_ptr { + auto tf = std::make_shared(); - // Inicializa a cero el vector con las coordenadas - for (auto& i : tf->offset) { - i.x = 0; - i.y = 0; - i.w = 0; - tf->box_width = 0; - tf->box_height = 0; - } + // No es necesario inicializar - los miembros tienen valores por defecto // Load file using ResourceHelper (supports both filesystem and pack) auto file_data = Resource::Helper::loadFile(file_path); @@ -101,35 +94,18 @@ Text::Text(const std::shared_ptr& surface, const std::string& text_file // Inicializa variables desde la estructura box_height_ = tf->box_height; box_width_ = tf->box_width; - for (int i = 0; i < 128; ++i) { - offset_[i].x = tf->offset[i].x; - offset_[i].y = tf->offset[i].y; - offset_[i].w = tf->offset[i].w; - } + offset_ = tf->offset; // Crea los objetos sprite_ = std::make_unique(surface, (SDL_FRect){0.0F, 0.0F, static_cast(box_width_), static_cast(box_height_)}); - - // Inicializa variables - fixed_width_ = false; } // Constructor -Text::Text(const std::shared_ptr& surface, const std::shared_ptr& text_file) { - // Inicializa variables desde la estructura - box_height_ = text_file->box_height; - box_width_ = text_file->box_width; - for (int i = 0; i < 128; ++i) { - offset_[i].x = text_file->offset[i].x; - offset_[i].y = text_file->offset[i].y; - offset_[i].w = text_file->offset[i].w; - } - - // Crea los objetos - sprite_ = std::make_unique(surface, (SDL_FRect){0.0F, 0.0F, static_cast(box_width_), static_cast(box_height_)}); - - // Inicializa variables - fixed_width_ = false; +Text::Text(const std::shared_ptr& surface, const std::shared_ptr& text_file) + : sprite_(std::make_unique(surface, (SDL_FRect){0.0F, 0.0F, static_cast(text_file->box_width), static_cast(text_file->box_height)})), + box_width_(text_file->box_width), + box_height_(text_file->box_height), + offset_(text_file->offset) { } // Escribe texto en pantalla @@ -152,7 +128,7 @@ void Text::write(int x, int y, const std::string& text, int kerning, int lenght) // Escribe el texto en una surface auto Text::writeToSurface(const std::string& text, int zoom, int kerning) -> std::shared_ptr { - auto width = lenght(text, kerning) * zoom; + auto width = length(text, kerning) * zoom; auto height = box_height_ * zoom; auto surface = std::make_shared(width, height); auto previuos_renderer = Screen::get()->getRendererSurface(); @@ -166,7 +142,7 @@ auto Text::writeToSurface(const std::string& text, int zoom, int kerning) -> std // Escribe el texto con extras en una surface auto Text::writeDXToSurface(Uint8 flags, const std::string& text, int kerning, Uint8 text_color, Uint8 shadow_distance, Uint8 shadow_color, int lenght) -> std::shared_ptr { - auto width = Text::lenght(text, kerning) + shadow_distance; + auto width = Text::length(text, kerning) + shadow_distance; auto height = box_height_ + shadow_distance; auto surface = std::make_shared(width, height); auto previuos_renderer = Screen::get()->getRendererSurface(); @@ -204,19 +180,19 @@ void Text::writeShadowed(int x, int y, const std::string& text, Uint8 color, Uin // Escribe el texto centrado en un punto x void Text::writeCentered(int x, int y, const std::string& text, int kerning, int lenght) { - x -= (Text::lenght(text, kerning) / 2); + x -= (Text::length(text, kerning) / 2); write(x, y, text, kerning, lenght); } // Escribe texto con extras void Text::writeDX(Uint8 flags, int x, int y, const std::string& text, int kerning, Uint8 text_color, Uint8 shadow_distance, Uint8 shadow_color, int lenght) { - const auto CENTERED = ((flags & TEXT_CENTER) == TEXT_CENTER); - const auto SHADOWED = ((flags & TEXT_SHADOW) == TEXT_SHADOW); - const auto COLORED = ((flags & TEXT_COLOR) == TEXT_COLOR); - const auto STROKED = ((flags & TEXT_STROKE) == TEXT_STROKE); + const auto CENTERED = ((flags & CENTER_FLAG) == CENTER_FLAG); + const auto SHADOWED = ((flags & SHADOW_FLAG) == SHADOW_FLAG); + const auto COLORED = ((flags & COLOR_FLAG) == COLOR_FLAG); + const auto STROKED = ((flags & STROKE_FLAG) == STROKE_FLAG); if (CENTERED) { - x -= (Text::lenght(text, kerning) / 2); + x -= (Text::length(text, kerning) / 2); } if (SHADOWED) { @@ -242,7 +218,7 @@ void Text::writeDX(Uint8 flags, int x, int y, const std::string& text, int kerni } // Obtiene la longitud en pixels de una cadena -auto Text::lenght(const std::string& text, int kerning) const -> int { +auto Text::length(const std::string& text, int kerning) const -> int { int shift = 0; for (size_t i = 0; i < text.length(); ++i) { shift += (offset_[static_cast(text[i])].w + kerning); diff --git a/source/core/rendering/text.hpp b/source/core/rendering/text.hpp index 08efd64a..0455b225 100644 --- a/source/core/rendering/text.hpp +++ b/source/core/rendering/text.hpp @@ -2,77 +2,63 @@ #include +#include // Para std::array #include // Para shared_ptr, unique_ptr #include // Para string #include "core/rendering/surface_sprite.hpp" // Para SSprite class Surface; // lines 8-8 -constexpr int TEXT_COLOR = 1; -constexpr int TEXT_SHADOW = 2; -constexpr int TEXT_CENTER = 4; -constexpr int TEXT_STROKE = 8; - -struct TextOffset { - int x, y, w; -}; - -struct TextFile { - int box_width; // Anchura de la caja de cada caracter en el png - int box_height; // Altura de la caja de cada caracter en el png - TextOffset offset[128]; // Vector con las posiciones y ancho de cada letra -}; - -// Llena una estructuta TextFile desde un fichero -auto loadTextFile(const std::string& file_path) -> std::shared_ptr; - // Clase texto. Pinta texto en pantalla a partir de un bitmap class Text { + public: + // Tipos anidados públicos + struct Offset { + int x{0}, y{0}, w{0}; + }; + + struct File { + int box_width{0}; // Anchura de la caja de cada caracter en el png + int box_height{0}; // Altura de la caja de cada caracter en el png + std::array offset{}; // Vector con las posiciones y ancho de cada letra + }; + + // Constructor + Text(const std::shared_ptr& surface, const std::string& text_file); + Text(const std::shared_ptr& surface, const std::shared_ptr& text_file); + + // Destructor + ~Text() = default; + + // Constantes de flags para writeDX + static constexpr int COLOR_FLAG = 1; + static constexpr int SHADOW_FLAG = 2; + static constexpr int CENTER_FLAG = 4; + static constexpr int STROKE_FLAG = 8; + + void write(int x, int y, const std::string& text, int kerning = 1, int lenght = -1); // Escribe el texto en pantalla + void writeColored(int x, int y, const std::string& text, Uint8 color, int kerning = 1, int lenght = -1); // Escribe el texto con colores + void writeShadowed(int x, int y, const std::string& text, Uint8 color, Uint8 shadow_distance = 1, int kerning = 1, int lenght = -1); // Escribe el texto con sombra + void writeCentered(int x, int y, const std::string& text, int kerning = 1, int lenght = -1); // Escribe el texto centrado en un punto x + void writeDX(Uint8 flags, int x, int y, const std::string& text, int kerning = 1, Uint8 text_color = Uint8(), Uint8 shadow_distance = 1, Uint8 shadow_color = Uint8(), int lenght = -1); // Escribe texto con extras + + auto writeToSurface(const std::string& text, int zoom = 1, int kerning = 1) -> std::shared_ptr; // Escribe el texto en una textura + auto writeDXToSurface(Uint8 flags, const std::string& text, int kerning = 1, Uint8 text_color = Uint8(), Uint8 shadow_distance = 1, Uint8 shadow_color = Uint8(), int lenght = -1) -> std::shared_ptr; // Escribe el texto con extras en una textura + + [[nodiscard]] auto length(const std::string& text, int kerning = 1) const -> int; // Obtiene la longitud en pixels de una cadena + [[nodiscard]] auto getCharacterSize() const -> int; // Devuelve el tamaño del caracter + + void setFixedWidth(bool value); // Establece si se usa un tamaño fijo de letra + + static auto loadTextFile(const std::string& file_path) -> std::shared_ptr; // Método de utilidad para cargar ficheros de texto + private: // Objetos y punteros std::unique_ptr sprite_ = nullptr; // Objeto con los graficos para el texto // Variables - int box_width_ = 0; // Anchura de la caja de cada caracter en el png - int box_height_ = 0; // Altura de la caja de cada caracter en el png - bool fixed_width_ = false; // Indica si el texto se ha de escribir con longitud fija en todas las letras - TextOffset offset_[128] = {}; // Vector con las posiciones y ancho de cada letra - - public: - // Constructor - Text(const std::shared_ptr& surface, const std::string& text_file); - Text(const std::shared_ptr& surface, const std::shared_ptr& text_file); - - // Destructor - ~Text() = default; - - // Escribe el texto en pantalla - void write(int x, int y, const std::string& text, int kerning = 1, int lenght = -1); - - // Escribe el texto en una textura - auto writeToSurface(const std::string& text, int zoom = 1, int kerning = 1) -> std::shared_ptr; - - // Escribe el texto con extras en una textura - auto writeDXToSurface(Uint8 flags, const std::string& text, int kerning = 1, Uint8 text_color = Uint8(), Uint8 shadow_distance = 1, Uint8 shadow_color = Uint8(), int lenght = -1) -> std::shared_ptr; - - // Escribe el texto con colores - void writeColored(int x, int y, const std::string& text, Uint8 color, int kerning = 1, int lenght = -1); - - // Escribe el texto con sombra - void writeShadowed(int x, int y, const std::string& text, Uint8 color, Uint8 shadow_distance = 1, int kerning = 1, int lenght = -1); - - // Escribe el texto centrado en un punto x - void writeCentered(int x, int y, const std::string& text, int kerning = 1, int lenght = -1); - - // Escribe texto con extras - void writeDX(Uint8 flags, int x, int y, const std::string& text, int kerning = 1, Uint8 text_color = Uint8(), Uint8 shadow_distance = 1, Uint8 shadow_color = Uint8(), int lenght = -1); - - // Obtiene la longitud en pixels de una cadena - [[nodiscard]] auto lenght(const std::string& text, int kerning = 1) const -> int; - - // Devuelve el valor de la variable - [[nodiscard]] auto getCharacterSize() const -> int; - - // Establece si se usa un tamaño fijo de letra - void setFixedWidth(bool value); + int box_width_ = 0; // Anchura de la caja de cada caracter en el png + int box_height_ = 0; // Altura de la caja de cada caracter en el png + bool fixed_width_ = false; // Indica si el texto se ha de escribir con longitud fija en todas las letras + std::array offset_{}; // Vector con las posiciones y ancho de cada letra }; \ No newline at end of file diff --git a/source/core/rendering/texture.hpp b/source/core/rendering/texture.hpp index 65eab623..9e2fbfc3 100644 --- a/source/core/rendering/texture.hpp +++ b/source/core/rendering/texture.hpp @@ -7,7 +7,30 @@ struct Color; // lines 11-11 class Texture { + public: + explicit Texture(SDL_Renderer* renderer, std::string path = std::string()); // Constructor + ~Texture(); // Destructor + + auto loadFromFile(const std::string& path) -> bool; // Carga una imagen desde un fichero + auto createBlank(int width, int height, SDL_PixelFormat format = SDL_PIXELFORMAT_RGBA8888, SDL_TextureAccess access = SDL_TEXTUREACCESS_STREAMING) -> bool; // Crea una textura en blanco + auto reLoad() -> bool; // Recarga la textura + + void setColor(Uint8 red, Uint8 green, Uint8 blue); // Establece el color para la modulacion + void setColor(Color color); // Establece el color para la modulacion + void setBlendMode(SDL_BlendMode blending); // Establece el blending + void setAlpha(Uint8 alpha); // Establece el alpha para la modulación + void setAsRenderTarget(SDL_Renderer* renderer); // Establece la textura como objetivo de renderizado + + void render(float x, float y, SDL_FRect* clip = nullptr, float zoom_w = 1, float zoom_h = 1, double angle = 0.0, SDL_FPoint* center = nullptr, SDL_FlipMode flip = SDL_FLIP_NONE); // Renderiza la textura en un punto específico + + [[nodiscard]] auto getWidth() const -> int { return width_; } // Obtiene el ancho de la imagen + [[nodiscard]] auto getHeight() const -> int { return height_; } // Obtiene el alto de la imagen + auto getSDLTexture() -> SDL_Texture*; // Obtiene la textura + auto getRenderer() -> SDL_Renderer*; // Obtiene el renderizador + private: + void unloadTexture(); // Libera la memoria de la textura + // Objetos y punteros SDL_Renderer* renderer_; // Renderizador donde dibujar la textura SDL_Texture* texture_ = nullptr; // La textura @@ -17,51 +40,4 @@ class Texture { float width_ = 0.0F; // Ancho de la imagen float height_ = 0.0F; // Alto de la imagen std::vector> palettes_; // Vector con las diferentes paletas - - // Libera la memoria de la textura - void unloadTexture(); - - public: - // Constructor - explicit Texture(SDL_Renderer* renderer, std::string path = std::string()); - - // Destructor - ~Texture(); - - // Carga una imagen desde un fichero - auto loadFromFile(const std::string& path) -> bool; - - // Crea una textura en blanco - auto createBlank(int width, int height, SDL_PixelFormat format = SDL_PIXELFORMAT_RGBA8888, SDL_TextureAccess access = SDL_TEXTUREACCESS_STREAMING) -> bool; - - // Establece el color para la modulacion - void setColor(Uint8 red, Uint8 green, Uint8 blue); - void setColor(Color color); - - // Establece el blending - void setBlendMode(SDL_BlendMode blending); - - // Establece el alpha para la modulación - void setAlpha(Uint8 alpha); - - // Renderiza la textura en un punto específico - void render(float x, float y, SDL_FRect* clip = nullptr, float zoom_w = 1, float zoom_h = 1, double angle = 0.0, SDL_FPoint* center = nullptr, SDL_FlipMode flip = SDL_FLIP_NONE); - - // Establece la textura como objetivo de renderizado - void setAsRenderTarget(SDL_Renderer* renderer); - - // Obtiene el ancho de la imagen - [[nodiscard]] auto getWidth() const -> int { return width_; } - - // Obtiene el alto de la imagen - [[nodiscard]] auto getHeight() const -> int { return height_; } - - // Recarga la textura - auto reLoad() -> bool; - - // Obtiene la textura - auto getSDLTexture() -> SDL_Texture*; - - // Obtiene el renderizador - auto getRenderer() -> SDL_Renderer*; }; \ No newline at end of file diff --git a/source/core/resources/resource_cache.cpp b/source/core/resources/resource_cache.cpp index 74a7a536..c35745e5 100644 --- a/source/core/resources/resource_cache.cpp +++ b/source/core/resources/resource_cache.cpp @@ -125,7 +125,7 @@ auto Cache::getPalette(const std::string& name) -> Palette { } // Obtiene el fichero de texto a partir de un nombre -auto Cache::getTextFile(const std::string& name) -> std::shared_ptr { +auto Cache::getTextFile(const std::string& name) -> std::shared_ptr { auto it = std::ranges::find_if(text_files_, [&name](const auto& t) { return t.name == name; }); if (it != text_files_.end()) { @@ -287,7 +287,7 @@ void Cache::loadTextFiles() { for (const auto& l : list) { auto name = getFileName(l); - text_files_.emplace_back(name, loadTextFile(l)); + text_files_.emplace_back(name, Text::loadTextFile(l)); updateLoadingProgress(); } } @@ -426,7 +426,7 @@ void Cache::renderProgress() { // Draw APP_NAME centered above center const std::string APP_NAME = spaceBetweenLetters(Version::APP_NAME); loading_text_->writeColored( - CENTER_X - (loading_text_->lenght(APP_NAME) / 2), + CENTER_X - (loading_text_->length(APP_NAME) / 2), CENTER_Y - TEXT_HEIGHT, APP_NAME, LOADING_TEXT_COLOR); @@ -434,7 +434,7 @@ void Cache::renderProgress() { // Draw VERSION centered below center const std::string VERSION_TEXT = "(" + std::string(Version::GIT_HASH) + ")"; loading_text_->writeColored( - CENTER_X - (loading_text_->lenght(VERSION_TEXT) / 2), + CENTER_X - (loading_text_->length(VERSION_TEXT) / 2), CENTER_Y + TEXT_HEIGHT, VERSION_TEXT, LOADING_TEXT_COLOR); diff --git a/source/core/resources/resource_cache.hpp b/source/core/resources/resource_cache.hpp index 83ef1da2..67832455 100644 --- a/source/core/resources/resource_cache.hpp +++ b/source/core/resources/resource_cache.hpp @@ -58,11 +58,11 @@ struct ResourcePalette { // Estructura para almacenar ficheros TextFile y su nombre struct ResourceTextFile { - std::string name; // Nombre del fichero - std::shared_ptr text_file; // Objeto con los descriptores de la fuente de texto + std::string name; // Nombre del fichero + std::shared_ptr text_file; // Objeto con los descriptores de la fuente de texto // Constructor - ResourceTextFile(std::string name, std::shared_ptr text_file) + ResourceTextFile(std::string name, std::shared_ptr text_file) : name(std::move(name)), text_file(std::move(std::move(text_file))) {} }; @@ -80,7 +80,7 @@ struct ResourceText { // Estructura para almacenar ficheros animaciones y su nombre struct ResourceAnimation { - std::string name; // Nombre del fichero + std::string name; // Nombre del fichero SurfaceAnimatedSprite::Animations animation; // Objeto con las animaciones // Constructor @@ -239,7 +239,7 @@ class Cache { auto getPalette(const std::string& name) -> Palette; // Obtiene el fichero de texto a partir de un nombre - auto getTextFile(const std::string& name) -> std::shared_ptr; + auto getTextFile(const std::string& name) -> std::shared_ptr; // Obtiene el objeto de texto a partir de un nombre auto getText(const std::string& name) -> std::shared_ptr; diff --git a/source/core/system/debug.hpp b/source/core/system/debug.hpp index 158f14c1..8538a04a 100644 --- a/source/core/system/debug.hpp +++ b/source/core/system/debug.hpp @@ -8,35 +8,28 @@ // Clase Debug class Debug { public: - // [SINGLETON] Crearemos el objeto con esta función estática - static void init(); + static void init(); // [SINGLETON] Crearemos el objeto con esta función estática + static void destroy(); // [SINGLETON] Destruiremos el objeto con esta función estática + static auto get() -> Debug*; // [SINGLETON] Con este método obtenemos el objeto y podemos trabajar con él - // [SINGLETON] Destruiremos el objeto con esta función estática - static void destroy(); + void render(); // Dibuja en pantalla - // [SINGLETON] Con este método obtenemos el objeto y podemos trabajar con él - static auto get() -> Debug*; + void setPos(SDL_FPoint p); // Establece la posición donde se colocará la información de debug - // Dibuja en pantalla - void render(); + [[nodiscard]] auto getEnabled() const -> bool { return enabled_; } // Obtiene si el debug está activo - // Establece la posición donde se colocará la información de debug - void setPos(SDL_FPoint p); - - // Getters - [[nodiscard]] auto getEnabled() const -> bool { return enabled_; } - - // Setters - void add(const std::string& text) { slot_.push_back(text); } - void clear() { slot_.clear(); } - void addToLog(const std::string& text) { log_.push_back(text); } - void clearLog() { log_.clear(); } - void setEnabled(bool value) { enabled_ = value; } - void toggleEnabled() { enabled_ = !enabled_; } + void add(const std::string& text) { slot_.push_back(text); } // Añade texto al slot de debug + void clear() { slot_.clear(); } // Limpia el slot de debug + void addToLog(const std::string& text) { log_.push_back(text); } // Añade texto al log + void clearLog() { log_.clear(); } // Limpia el log + void setEnabled(bool value) { enabled_ = value; } // Establece si el debug está activo + void toggleEnabled() { enabled_ = !enabled_; } // Alterna el estado del debug private: - // [SINGLETON] Objeto privado - static Debug* debug; + static Debug* debug; // [SINGLETON] Objeto privado + + Debug() = default; // Constructor + ~Debug() = default; // Destructor // Variables std::vector slot_; // Vector con los textos a escribir @@ -44,10 +37,4 @@ class Debug { 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; }; \ No newline at end of file diff --git a/source/game/entities/enemy.hpp b/source/game/entities/enemy.hpp index 9a8f531e..d5faa996 100644 --- a/source/game/entities/enemy.hpp +++ b/source/game/entities/enemy.hpp @@ -8,58 +8,44 @@ class SurfaceAnimatedSprite; // lines 7-7 class Enemy { public: - // --- Estructuras --- struct Data { - /* [DOC:29/10/2025] la surface ara se pillarà del .ANI - std::string surface_path{}; // Ruta al fichero con la textura - [/DOC] */ std::string animation_path; // Ruta al fichero con la animación - /* [DOC:29/10/2025] w i h ja no fan falta, se pilla del .ANI - int w = 0; // Anchura del enemigo - int h = 0; // Altura del enemigo - [/DOC] */ - float x = 0.0F; // Posición inicial en el eje X - float y = 0.0F; // Posición inicial en el eje Y - float vx = 0.0F; // Velocidad en el eje X - float vy = 0.0F; // Velocidad en el eje Y - int x1 = 0; // Límite izquierdo de la ruta en el eje X - int x2 = 0; // Límite derecho de la ruta en el eje X - int y1 = 0; // Límite superior de la ruta en el eje Y - int y2 = 0; // Límite inferior de la ruta en el eje Y - bool flip = false; // Indica si el enemigo hace flip al terminar su ruta - bool mirror = false; // Indica si el enemigo está volteado verticalmente - int frame = 0; // Frame inicial para la animación del enemigo - std::string color; // Color del enemigo - - // Constructor por defecto - Data() = default; + float x{0.0F}; // Posición inicial en el eje X + float y{0.0F}; // Posición inicial en el eje Y + float vx{0.0F}; // Velocidad en el eje X + float vy{0.0F}; // Velocidad en el eje Y + int x1{0}; // Límite izquierdo de la ruta en el eje X + int x2{0}; // Límite derecho de la ruta en el eje X + int y1{0}; // Límite superior de la ruta en el eje Y + int y2{0}; // Límite inferior de la ruta en el eje Y + bool flip{false}; // Indica si el enemigo hace flip al terminar su ruta + bool mirror{false}; // Indica si el enemigo está volteado verticalmente + int frame{0}; // Frame inicial para la animación del enemigo + std::string color; // Color del enemigo }; - // --- Constructor y Destructor --- - explicit Enemy(const Data& enemy); - ~Enemy() = default; + explicit Enemy(const Data& enemy); // Constructor + ~Enemy() = default; // Destructor - // --- Funciones --- void render(); // Pinta el enemigo en pantalla void update(float delta_time); // Actualiza las variables del objeto + auto getRect() -> SDL_FRect; // Devuelve el rectangulo que contiene al enemigo auto getCollider() -> SDL_FRect&; // Obtiene el rectangulo de colision del enemigo private: - // --- Objetos y punteros --- + void checkPath(); // Comprueba si ha llegado al limite del recorrido para darse media vuelta + std::shared_ptr sprite_; // Sprite del enemigo - // --- Variables --- - Uint8 color_; // Color del enemigo - std::string color_string_; // Color del enemigo en formato texto - int x1_; // Limite izquierdo de la ruta en el eje X - int x2_; // Limite derecho de la ruta en el eje X - int y1_; // Limite superior de la ruta en el eje Y - int y2_; // Limite inferior de la ruta en el eje Y - SDL_FRect collider_; // Caja de colisión - bool should_flip_; // Indica si el enemigo hace flip al terminar su ruta - bool should_mirror_; // Indica si el enemigo se dibuja volteado verticalmente - - // --- Comprueba si ha llegado al limite del recorrido para darse media vuelta --- - void checkPath(); + // Variables + Uint8 color_{0}; // Color del enemigo + std::string color_string_; // Color del enemigo en formato texto + int x1_{0}; // Limite izquierdo de la ruta en el eje X + int x2_{0}; // Limite derecho de la ruta en el eje X + int y1_{0}; // Limite superior de la ruta en el eje Y + int y2_{0}; // Limite inferior de la ruta en el eje Y + SDL_FRect collider_{}; // Caja de colisión + bool should_flip_{false}; // Indica si el enemigo hace flip al terminar su ruta + bool should_mirror_{false}; // Indica si el enemigo se dibuja volteado verticalmente }; diff --git a/source/game/entities/item.cpp b/source/game/entities/item.cpp index e7c61909..5c06beee 100644 --- a/source/game/entities/item.cpp +++ b/source/game/entities/item.cpp @@ -6,8 +6,7 @@ // Constructor Item::Item(const Data& item) : sprite_(std::make_shared(Resource::Cache::get()->getSurface(item.tile_set_file), item.x, item.y, ITEM_SIZE, ITEM_SIZE)), - time_accumulator_(static_cast(item.counter) * COLOR_CHANGE_INTERVAL), - is_paused_(false) { + time_accumulator_(static_cast(item.counter) * COLOR_CHANGE_INTERVAL) { // Inicia variables sprite_->setClip((item.tile % 10) * ITEM_SIZE, (item.tile / 10) * ITEM_SIZE, ITEM_SIZE, ITEM_SIZE); collider_ = sprite_->getRect(); diff --git a/source/game/entities/item.hpp b/source/game/entities/item.hpp index d4a2a56a..c64409ef 100644 --- a/source/game/entities/item.hpp +++ b/source/game/entities/item.hpp @@ -9,43 +9,36 @@ class SurfaceSprite; class Item { public: - // --- Estructuras --- struct Data { std::string tile_set_file; // Ruta al fichero con los gráficos del item - float x{0}; // Posición del item en pantalla - float y{0}; // Posición del item en pantalla + float x{0.0F}; // Posición del item en pantalla + float y{0.0F}; // Posición del item en pantalla int tile{0}; // Número de tile dentro de la textura int counter{0}; // Contador inicial. Es el que lo hace cambiar de color - Uint8 color1{}; // Uno de los dos colores que se utiliza para el item - Uint8 color2{}; // Uno de los dos colores que se utiliza para el item - - // Constructor - Data() = default; + Uint8 color1{0}; // Uno de los dos colores que se utiliza para el item + Uint8 color2{0}; // Uno de los dos colores que se utiliza para el item }; - // Constructor y Destructor - explicit Item(const Data& item); - ~Item() = default; + explicit Item(const Data& item); // Constructor + ~Item() = default; // Destructor + + void render() const; // Pinta el objeto en pantalla + void update(float delta_time); // Actualiza las variables del objeto - // --- Funciones --- - void render() const; // Pinta el objeto en pantalla - void update(float delta_time); // Actualiza las variables del objeto void setPaused(bool paused) { is_paused_ = paused; } // Pausa/despausa el item auto getCollider() -> SDL_FRect& { return collider_; } // Obtiene el rectangulo de colision del objeto auto getPos() -> SDL_FPoint; // Obtiene su ubicación void setColors(Uint8 col1, Uint8 col2); // Asigna los colores del objeto private: - // --- Constantes --- - static constexpr float ITEM_SIZE = 8; + static constexpr float ITEM_SIZE = 8.0F; // Tamaño del item en pixels static constexpr float COLOR_CHANGE_INTERVAL = 0.06F; // Intervalo de cambio de color en segundos (4 frames a 66.67fps) - // --- Objetos y punteros --- std::shared_ptr sprite_; // SSprite del objeto - // --- Variables --- - std::vector color_; // Vector con los colores del objeto - float time_accumulator_; // Acumulador de tiempo para cambio de color - SDL_FRect collider_; // Rectangulo de colisión - bool is_paused_; // Indica si el item está pausado + // Variables + std::vector color_; // Vector con los colores del objeto + float time_accumulator_{0.0F}; // Acumulador de tiempo para cambio de color + SDL_FRect collider_{}; // Rectangulo de colisión + bool is_paused_{false}; // Indica si el item está pausado }; \ No newline at end of file diff --git a/source/game/entities/player.cpp.bak b/source/game/entities/player.cpp.bak deleted file mode 100644 index 6dba9902..00000000 --- a/source/game/entities/player.cpp.bak +++ /dev/null @@ -1,628 +0,0 @@ -// IWYU pragma: no_include -#include "game/entities/player.hpp" - -#include // Para max, min -#include // Para ceil, abs -#include -#include // Para std::ranges::any_of - -#include "core/audio/audio.hpp" // Para Audio -#include "core/input/input.hpp" // Para Input, InputAction -#include "core/rendering/surface_animated_sprite.hpp" // Para SAnimatedSprite -#include "core/resources/resource_cache.hpp" // Para Resource -#include "game/gameplay/room.hpp" // Para Room, TileType -#include "game/options.hpp" // Para Cheat, Options, options -#include "utils/defines.hpp" // Para RoomBorder::BOTTOM, RoomBorder::LEFT, RoomBorder::RIGHT - -// Constructor -Player::Player(const Data& player) - : room_(player.room) { - // Inicializa algunas variables - initSprite(player.animations_path); - setColor(); - applySpawnValues(player.spawn_data); - placeSprite(); - initSounds(); - - previous_state_ = state_; -} - -// Pinta el jugador en pantalla -void Player::render() { - sprite_->render(1, color_); -} - -// Actualiza las variables del objeto -void Player::update(float delta_time) { - if (!is_paused_) { - handleInput(delta_time); // Comprueba las entradas y modifica variables - move(delta_time); // Recalcula la posición del jugador - animate(delta_time); // Establece la animación del jugador - handleBorders(); // Comprueba si está situado en alguno de los cuatro bordes de la habitación - handleJumpEnd(); // Comprueba si ha finalizado el salto al alcanzar la altura de inicio - handleKillingTiles(); // Comprueba que el jugador no toque ningun tile de los que matan - setColor(); // Establece el color del jugador - } -} - -// Comprueba las entradas y modifica variables -void Player::handleInput(float delta_time) { - (void)delta_time; // No usado en este método, pero mantenido para consistencia - - // Solo comprueba las entradas de dirección cuando está sobre una superficie - if (state_ != State::STANDING) { - return; - } - - if (!auto_movement_) { - // Comprueba las entradas de desplazamiento lateral solo en el caso de no estar enganchado a una superficie automatica - if (Input::get()->checkAction(InputAction::LEFT)) { - vx_ = -HORIZONTAL_VELOCITY; - sprite_->setFlip(SDL_FLIP_HORIZONTAL); - } - - else if (Input::get()->checkAction(InputAction::RIGHT)) { - vx_ = HORIZONTAL_VELOCITY; - sprite_->setFlip(SDL_FLIP_NONE); - } - - else { - // No se pulsa ninguna dirección - vx_ = 0.0F; - if (isOnAutoSurface()) { - // Si deja de moverse sobre una superficie se engancha - auto_movement_ = true; - } - } - } else { // El movimiento lo proporciona la superficie - vx_ = HORIZONTAL_VELOCITY * room_->getAutoSurfaceDirection(); - - if (vx_ > 0.0F) { - sprite_->setFlip(SDL_FLIP_NONE); - } else { - sprite_->setFlip(SDL_FLIP_HORIZONTAL); - } - } - - if (Input::get()->checkAction(InputAction::JUMP)) { - // Solo puede saltar si ademas de estar (state == STANDING) - // Esta sobre el suelo, rampa o suelo que se mueve - // Esto es para evitar el salto desde el vacio al cambiar de pantalla verticalmente - // Ya que se coloca el estado STANDING al cambiar de pantalla - - if (isOnFloor() || isOnAutoSurface()) { - transitionToState(State::JUMPING); - vy_ = JUMP_VELOCITY; - last_grounded_position_ = static_cast(y_); - } - } -} - -// Comprueba si está situado en alguno de los cuatro bordes de la habitación -void Player::handleBorders() { - if (x_ < PLAY_AREA_LEFT) { - border_ = Room::Border::LEFT; - is_on_border_ = true; - } - - else if (x_ + WIDTH > PLAY_AREA_RIGHT) { - border_ = Room::Border::RIGHT; - is_on_border_ = true; - } - - else if (y_ < PLAY_AREA_TOP) { - border_ = Room::Border::TOP; - is_on_border_ = true; - } - - else if (y_ + HEIGHT > PLAY_AREA_BOTTOM) { - border_ = Room::Border::BOTTOM; - is_on_border_ = true; - } - - else { - is_on_border_ = false; - } -} - -// Comprueba el estado del jugador -void Player::handleState(float delta_time) { - (void)delta_time; // No usado actualmente - - // Reproduce sonidos según el estado - if (state_ == State::FALLING) { - playFallSound(); - } else if (state_ == State::STANDING) { - // Si no tiene suelo debajo y no está en rampa descendente -> FALLING - if (!isOnFloor() && !isOnAutoSurface() && !isOnDownSlope()) { - last_grounded_position_ = static_cast(y_); // Guarda Y actual al SALIR de STANDING - transitionToState(State::FALLING); // setState() establece vx_=0, vy_=MAX_VY - playFallSound(); - } - } else if (state_ == State::JUMPING) { - playJumpSound(); - } -} - -// Cambia al jugador de un borde al opuesto. Util para el cambio de pantalla -void Player::switchBorders() { - switch (border_) { - case Room::Border::TOP: - y_ = PLAY_AREA_BOTTOM - HEIGHT - TILE_SIZE; - transitionToState(State::STANDING); - break; - - case Room::Border::BOTTOM: - y_ = PLAY_AREA_TOP; - transitionToState(State::STANDING); - break; - - case Room::Border::RIGHT: - x_ = PLAY_AREA_LEFT; - break; - - case Room::Border::LEFT: - x_ = PLAY_AREA_RIGHT - WIDTH; - break; - - default: - break; - } - - // CRÍTICO: Resetear last_grounded_position_ para evitar muerte falsa por diferencia de Y entre pantallas - last_grounded_position_ = static_cast(y_); - is_on_border_ = false; - placeSprite(); -} - -// Aplica gravedad al jugador -void Player::applyGravity(float delta_time) { - // La gravedad solo se aplica cuando el jugador esta saltando - // Nunca mientras cae o esta de pie - if (state_ == State::JUMPING) { - vy_ += GRAVITY_FORCE * delta_time; - vy_ = std::min(vy_, MAX_VY); - } -} - -// Maneja el movimiento sobre rampas -// direction: -1 para izquierda, 1 para derecha -void Player::handleSlopeMovement(int direction) { - // No procesa rampas durante el salto (permite atravesarlas cuando salta con movimiento horizontal) - // Pero SÍ procesa en STANDING y FALLING (para pegarse a las rampas) - if (state_ == State::JUMPING) { - return; - } - - // Regla: Si está bajando la rampa, se pega a la slope - if (isOnDownSlope()) { - y_ += 1; - return; - } - - // Regla: Si está STANDING y tropieza lateralmente con una Slope, se pega a la slope - // Comprueba si hay rampa en contacto lateral (solo los dos pixels inferiores) - const int SIDE_X = direction < 0 ? static_cast(x_) : static_cast(x_) + WIDTH - 1; - const LineVertical SIDE = { - .x = SIDE_X, - .y1 = static_cast(y_) + HEIGHT - 2, - .y2 = static_cast(y_) + HEIGHT - 1}; - - // Comprueba la rampa correspondiente según la dirección - const int SLOPE_Y = direction < 0 ? room_->checkLeftSlopes(&SIDE) : room_->checkRightSlopes(&SIDE); - - if (SLOPE_Y > -1) { - // Hay rampa: sube al jugador para pegarlo a la rampa - y_ = SLOPE_Y - HEIGHT; - } -} - -// Maneja el movimiento horizontal -// direction: -1 para izquierda, 1 para derecha -void Player::moveHorizontal(float delta_time, int direction) { - const float DISPLACEMENT = vx_ * delta_time; - - // Crea el rectangulo de proyección en el eje X para ver si colisiona - SDL_FRect proj; - if (direction < 0) { - // Movimiento a la izquierda - proj = { - .x = x_ + DISPLACEMENT, - .y = y_, - .w = std::ceil(std::fabs(DISPLACEMENT)), - .h = HEIGHT}; - } else { - // Movimiento a la derecha - proj = { - .x = x_ + WIDTH, - .y = y_, - .w = std::ceil(DISPLACEMENT), - .h = HEIGHT}; - } - - // Comprueba la colisión con las superficies - const int POS = direction < 0 ? room_->checkRightSurfaces(&proj) : room_->checkLeftSurfaces(&proj); - - // Calcula la nueva posición - if (POS == -1) { - // No hay colisión: mueve al jugador - x_ += DISPLACEMENT; - } else { - // Hay colisión: reposiciona al jugador en el punto de colisión - x_ = direction < 0 ? POS + 1 : POS - WIDTH; - } - - // Maneja el movimiento sobre rampas - handleSlopeMovement(direction); -} - -// Maneja el movimiento vertical hacia arriba -void Player::moveVerticalUp(float delta_time) { - // Crea el rectangulo de proyección en el eje Y para ver si colisiona - const float DISPLACEMENT = vy_ * delta_time; - SDL_FRect proj = { - .x = x_, - .y = y_ + DISPLACEMENT, - .w = WIDTH, - .h = std::ceil(std::fabs(DISPLACEMENT)) // Para evitar que tenga una altura de 0 pixels - }; - - // Comprueba la colisión - const int POS = room_->checkBottomSurfaces(&proj); - - // Calcula la nueva posición - if (POS == -1) { - // Si no hay colisión - y_ += DISPLACEMENT; - } else { - // Si hay colisión lo mueve hasta donde no colisiona - // Regla: Si está JUMPING y tropieza contra el techo -> FALLING - y_ = POS + 1; - transitionToState(State::FALLING); - } -} - -// Maneja el movimiento vertical hacia abajo -void Player::moveVerticalDown(float delta_time) { - // Crea el rectangulo de proyección en el eje Y para ver si colisiona - const float DISPLACEMENT = vy_ * delta_time; - SDL_FRect proj = { - .x = x_, - .y = y_ + HEIGHT, - .w = WIDTH, - .h = std::ceil(DISPLACEMENT) // Para evitar que tenga una altura de 0 pixels - }; - - // Comprueba la colisión con las superficies normales y las automáticas - const float POS = std::max(room_->checkTopSurfaces(&proj), room_->checkAutoSurfaces(&proj)); - if (POS > -1) { - // Si hay colisión lo mueve hasta donde no colisiona y pasa a estar sobre la superficie - y_ = POS - HEIGHT; - - // VERIFICAR MUERTE ANTES de cambiar de estado (PLAYER_MECHANICS.md línea 1268-1274) - const int FALL_DISTANCE = static_cast(y_) - last_grounded_position_; - if (previous_state_ == State::FALLING && FALL_DISTANCE > MAX_FALLING_HEIGHT) { - is_alive_ = false; // Muere si cae más de 32 píxeles - } - - transitionToState(State::STANDING); - last_grounded_position_ = static_cast(y_); // Actualizar AL ENTRAR en STANDING - // Deja de estar enganchado a la superficie automatica - auto_movement_ = false; - } else { - // Si no hay colisión con los muros, comprueba la colisión con las rampas - // CORRECCIÓN: FALLING siempre se pega a rampas, JUMPING se pega solo si vx_ == 0 - if (state_ == State::FALLING || (state_ == State::JUMPING && vx_ == 0.0F)) { - // No está saltando O salta recto: se pega a las rampas - auto rect = toSDLRect(proj); - const LineVertical LEFT_SIDE = {.x = rect.x, .y1 = rect.y, .y2 = rect.y + rect.h - 1}; - const LineVertical RIGHT_SIDE = {.x = rect.x + rect.w - 1, .y1 = rect.y, .y2 = rect.y + rect.h - 1}; - const float POINT = std::max(room_->checkRightSlopes(&RIGHT_SIDE), room_->checkLeftSlopes(&LEFT_SIDE)); - if (POINT > -1) { - // No está saltando y hay colisión con una rampa - // Calcula la nueva posición - y_ = POINT - HEIGHT; - - // VERIFICAR MUERTE ANTES de cambiar de estado (PLAYER_MECHANICS.md línea 1268-1274) - const int FALL_DISTANCE = static_cast(y_) - last_grounded_position_; - if (previous_state_ == State::FALLING && FALL_DISTANCE > MAX_FALLING_HEIGHT) { - is_alive_ = false; // Muere si cae más de 32 píxeles - } - - transitionToState(State::STANDING); - last_grounded_position_ = static_cast(y_); // Actualizar AL ENTRAR en STANDING - } else { - // No está saltando y no hay colisón con una rampa - // Calcula la nueva posición - y_ += DISPLACEMENT; - } - } else { - // Esta saltando con movimiento horizontal y no hay colisión con los muros - // Calcula la nueva posición (atraviesa rampas) - y_ += DISPLACEMENT; - } - } -} - -// Orquesta el movimiento del jugador -void Player::move(float delta_time) { - applyGravity(delta_time); // Aplica gravedad al jugador - handleState(delta_time); // Comprueba el estado del jugador - - // Movimiento horizontal - if (vx_ < 0.0F) { - moveHorizontal(delta_time, -1); // Izquierda - } else if (vx_ > 0.0F) { - moveHorizontal(delta_time, 1); // Derecha - } - - // Si ha salido del suelo, el jugador cae - if (state_ == State::STANDING && !isOnFloor()) { - transitionToState(State::FALLING); - auto_movement_ = false; - } - - // Si ha salido de una superficie automatica, detiene el movimiento automatico - if (state_ == State::STANDING && isOnFloor() && !isOnAutoSurface()) { - auto_movement_ = false; - } - - // Movimiento vertical - if (vy_ < 0.0F) { - moveVerticalUp(delta_time); - } else if (vy_ > 0.0F) { - moveVerticalDown(delta_time); - } - - y_prev_ = y_; // Guarda Y DESPUÉS de todo el movimiento (para detectar hitos en sonidos) - - // Actualiza la geometría del collider y sprite - updateColliderGeometry(); -} - -// Establece la animación del jugador -void Player::animate(float delta_time) { - if (vx_ != 0) { - sprite_->update(delta_time); - } -} - -// Comprueba si ha finalizado el salto al alcanzar la altura de inicio -void Player::handleJumpEnd() { - // Si el jugador vuelve EXACTAMENTE a la altura inicial, debe CONTINUAR en JUMPING - // Solo cuando la SUPERA (desciende más allá) cambia a FALLING - if (state_ == State::JUMPING && vy_ > 0.0F && static_cast(y_) > last_grounded_position_) { - transitionToState(State::FALLING); - } -} - -// Calcula y reproduce el sonido de salto basado en distancia vertical recorrida -void Player::playJumpSound() { - // Sistema basado en distancia vertical, no en tiempo (PLAYER_MECHANICS.md línea 107-120) - const float DISTANCE_FROM_START = std::abs(y_ - static_cast(last_grounded_position_)); - const int SOUND_INDEX = static_cast(DISTANCE_FROM_START / SOUND_DISTANCE_INTERVAL); - - // Calcular índice previo (frame anterior) - const float PREV_DISTANCE = std::abs(y_prev_ - static_cast(last_grounded_position_)); - const int PREVIOUS_INDEX = static_cast(PREV_DISTANCE / SOUND_DISTANCE_INTERVAL); - - // Solo reproduce cuando cambia de índice (nuevo hito alcanzado) - if (SOUND_INDEX != PREVIOUS_INDEX && SOUND_INDEX < static_cast(jumping_sound_.size())) { - Audio::get()->playSound(jumping_sound_[SOUND_INDEX], Audio::Group::GAME); - } -} - -// Calcula y reproduce el sonido de caída basado en distancia vertical recorrida -void Player::playFallSound() { - // Sistema basado en distancia vertical, no en tiempo (PLAYER_MECHANICS.md línea 193-206) - const float DISTANCE_FALLEN = y_ - static_cast(last_grounded_position_); - const int SOUND_INDEX = static_cast(DISTANCE_FALLEN / SOUND_DISTANCE_INTERVAL); - - // Calcular índice previo (frame anterior) - const float PREV_DISTANCE = y_prev_ - static_cast(last_grounded_position_); - const int PREVIOUS_INDEX = static_cast(PREV_DISTANCE / SOUND_DISTANCE_INTERVAL); - - // Solo reproduce cuando cambia de índice (nuevo hito alcanzado) - if (SOUND_INDEX != PREVIOUS_INDEX && SOUND_INDEX < static_cast(falling_sound_.size())) { - Audio::get()->playSound(falling_sound_[SOUND_INDEX], Audio::Group::GAME); - } -} - -// Comprueba si el jugador tiene suelo debajo de los pies -auto Player::isOnFloor() -> bool { - bool on_floor = false; - bool on_slope_l = false; - bool on_slope_r = false; - - updateFeet(); - - // Comprueba las superficies - for (auto f : under_feet_) { - on_floor |= room_->checkTopSurfaces(&f); - on_floor |= room_->checkAutoSurfaces(&f); - } - - // Comprueba las rampas - on_slope_l = room_->checkLeftSlopes(under_feet_.data()); - on_slope_r = room_->checkRightSlopes(&under_feet_[1]); - - return on_floor || on_slope_l || on_slope_r; -} - -// Comprueba si el jugador esta sobre una superficie automática -auto Player::isOnAutoSurface() -> bool { - bool on_auto_surface = false; - - updateFeet(); - - // Comprueba las superficies - for (auto f : under_feet_) { - on_auto_surface |= room_->checkAutoSurfaces(&f); - } - - return on_auto_surface; -} - -// Comprueba si el jugador está sobre una rampa hacia abajo -auto Player::isOnDownSlope() -> bool { - bool on_slope = false; - - updateFeet(); - - // Cuando el jugador baja una escalera, se queda volando - // Hay que mirar otro pixel más por debajo - SDL_FPoint foot0 = under_feet_[0]; - SDL_FPoint foot1 = under_feet_[1]; - foot0.y += 1.0F; - foot1.y += 1.0F; - - // Comprueba las rampas - on_slope |= room_->checkLeftSlopes(&foot0); - on_slope |= room_->checkRightSlopes(&foot1); - - return on_slope; -} - -// Comprueba que el jugador no toque ningun tile de los que matan -auto Player::handleKillingTiles() -> bool { - // Comprueba si hay contacto con algún tile que mata - if (std::ranges::any_of(collider_points_, [this](const auto& c) { - return room_->getTile(c) == Room::Tile::KILL; - })) { - is_alive_ = false; // Mata al jugador inmediatamente - return true; // Retorna en cuanto se detecta una colisión - } - - return false; // No se encontró ninguna colisión -} - -// Establece el color del jugador -void Player::setColor() { - /* - if (Options::cheats.invincible == Options::Cheat::State::ENABLED) { - color_ = static_cast(PaletteColor::CYAN); - } else if (Options::cheats.infinite_lives == Options::Cheat::State::ENABLED) { - color_ = static_cast(PaletteColor::YELLOW); - } else { - color_ = static_cast(PaletteColor::WHITE); - } - */ - - switch (state_) { - case State::STANDING: - color_ = static_cast(PaletteColor::YELLOW); - break; - - case State::JUMPING: - color_ = static_cast(PaletteColor::GREEN); - break; - - case State::FALLING: - color_ = static_cast(PaletteColor::RED); - break; - - default: - break; - } -} - -// Actualiza los puntos de colisión -void Player::updateColliderPoints() { - const SDL_FRect RECT = getRect(); - collider_points_[0] = {.x = RECT.x, .y = RECT.y}; - collider_points_[1] = {.x = RECT.x + 7, .y = RECT.y}; - collider_points_[2] = {.x = RECT.x + 7, .y = RECT.y + 7}; - collider_points_[3] = {.x = RECT.x, .y = RECT.y + 7}; - collider_points_[4] = {.x = RECT.x, .y = RECT.y + 8}; - collider_points_[5] = {.x = RECT.x + 7, .y = RECT.y + 8}; - collider_points_[6] = {.x = RECT.x + 7, .y = RECT.y + 15}; - collider_points_[7] = {.x = RECT.x, .y = RECT.y + 15}; -} - -// Actualiza los puntos de los pies -void Player::updateFeet() { - const SDL_FPoint P = {x_, y_}; - - under_feet_[0] = {.x = P.x, .y = P.y + HEIGHT}; - under_feet_[1] = {.x = P.x + 7, .y = P.y + HEIGHT}; - - feet_[0] = {.x = P.x, .y = P.y + HEIGHT - 1}; - feet_[1] = {.x = P.x + 7, .y = P.y + HEIGHT - 1}; -} - -// Cambia el estado del jugador -void Player::transitionToState(State value) { - previous_state_ = state_; - state_ = value; - - // Establecer velocidades INMEDIATAMENTE al cambiar de estado - switch (state_) { - case State::STANDING: - vx_ = 0.0F; - vy_ = 0.0F; - break; - - case State::JUMPING: - // vx_ mantiene su valor actual (heredado de STANDING) - vy_ = JUMP_VELOCITY; - break; - - case State::FALLING: - vx_ = 0.0F; // CRÍTICO para pegarse a rampas - vy_ = MAX_VY; - auto_movement_ = false; - break; - - default: - break; - } -} - -// Inicializa los sonidos de salto y caida -void Player::initSounds() { - jumping_sound_.clear(); - falling_sound_.clear(); - - for (int i = 1; i <= 24; ++i) { - std::string sound_file = "jump" + std::to_string(i) + ".wav"; - jumping_sound_.push_back(Resource::Cache::get()->getSound(sound_file)); - - if (i >= 11) { - falling_sound_.push_back(Resource::Cache::get()->getSound(sound_file)); - } - } -} - -// Aplica los valores de spawn al jugador -void Player::applySpawnValues(const SpawnData& spawn) { - x_ = spawn.x; - y_ = spawn.y; - y_prev_ = spawn.y; // Inicializar y_prev_ igual a y_ para evitar saltos en primer frame - vx_ = spawn.vx; - vy_ = spawn.vy; - last_grounded_position_ = spawn.last_grounded_position; - state_ = spawn.state; - sprite_->setFlip(spawn.flip); -} - -// Inicializa el sprite del jugador -void Player::initSprite(const std::string& animations_path) { - auto animations = Resource::Cache::get()->getAnimations(animations_path); - - sprite_ = std::make_unique(animations); - sprite_->setWidth(WIDTH); - sprite_->setHeight(HEIGHT); - sprite_->setCurrentAnimation("walk"); -} - -// Actualiza collider_box y collision points -void Player::updateColliderGeometry() { - placeSprite(); // Coloca el sprite en la posición del jugador - collider_box_ = getRect(); // Actualiza el rectangulo de colisión - updateColliderPoints(); // Actualiza los puntos de colisión -} - -// Coloca el sprite en la posición del jugador -void Player::placeSprite() { - sprite_->setPos(x_, y_); -} \ No newline at end of file diff --git a/source/game/entities/player.hpp.bak b/source/game/entities/player.hpp.bak deleted file mode 100644 index 40695880..00000000 --- a/source/game/entities/player.hpp.bak +++ /dev/null @@ -1,171 +0,0 @@ -#pragma once - -#include - -#include // Para array -#include // Para shared_ptr, __shared_ptr_access -#include // Para string -#include -#include // Para vector - -#include "core/rendering/surface_animated_sprite.hpp" // Para SAnimatedSprite -#include "game/gameplay/room.hpp" -#include "utils/defines.hpp" // Para BORDER_TOP, BLOCK -#include "utils/utils.hpp" // Para Color -struct JA_Sound_t; // lines 13-13 - -class Player { - public: - // --- Enums y Structs --- - enum class State { - STANDING, - JUMPING, - FALLING, - }; - - struct SpawnData { - float x = 0; - float y = 0; - float vx = 0; - float vy = 0; - int last_grounded_position = 0; - State state = State::STANDING; - SDL_FlipMode flip = SDL_FLIP_NONE; - - // Constructor por defecto - SpawnData() = default; - - // Constructor con parámetros - SpawnData(float x, float y, float vx, float vy, int last_grounded_position, State state, SDL_FlipMode flip) - : x(x), - y(y), - vx(vx), - vy(vy), - last_grounded_position(last_grounded_position), - state(state), - flip(flip) {} - }; - - struct Data { - SpawnData spawn_data; - std::string animations_path; - std::shared_ptr room = nullptr; - - // Constructor por defecto - Data() = default; - - // Constructor con parámetros - Data(SpawnData spawn_data, const std::string& texture_path, std::string animations_path, std::shared_ptr room) - : spawn_data(spawn_data), - animations_path(std::move(animations_path)), - room(std::move(room)) {} - }; - - // --- Constructor y Destructor --- - explicit Player(const Data& player); - ~Player() = default; - - // --- Funciones --- - void render(); // Pinta el enemigo en pantalla - void update(float delta_time); // Actualiza las variables del objeto - [[nodiscard]] auto isOnBorder() const -> bool { return is_on_border_; } // Indica si el jugador esta en uno de los cuatro bordes de la pantalla - [[nodiscard]] auto getBorder() const -> Room::Border { return border_; } // Indica en cual de los cuatro bordes se encuentra - void switchBorders(); // Cambia al jugador de un borde al opuesto. Util para el cambio de pantalla - auto getRect() -> SDL_FRect { return {x_, y_, WIDTH, HEIGHT}; } // Obtiene el rectangulo que delimita al jugador - auto getCollider() -> SDL_FRect& { return collider_box_; } // Obtiene el rectangulo de colision del jugador - auto getSpawnParams() -> SpawnData { return {x_, y_, vx_, vy_, last_grounded_position_, state_, sprite_->getFlip()}; } // Obtiene el estado de reaparición del jugador - void setColor(); // Establece el color del jugador - void setRoom(std::shared_ptr room) { room_ = std::move(room); } // Establece la habitación en la que se encuentra el jugador - [[nodiscard]] auto isAlive() const -> bool { return is_alive_; } // Comprueba si el jugador esta vivo - void setPaused(bool value) { is_paused_ = value; } // Pone el jugador en modo pausa - - private: - // --- Constantes --- - static constexpr int WIDTH = 8; // Ancho del jugador - static constexpr int HEIGHT = 16; // ALto del jugador - static constexpr int MAX_FALLING_HEIGHT = TILE_SIZE * 4; // Altura maxima permitida de caída en pixels - - // --- Constantes de física (per-second values) --- - static constexpr float HORIZONTAL_VELOCITY = 40.0F; // Velocidad horizontal en pixels/segundo (0.6 * 66.67fps) - static constexpr float MAX_VY = 80.0F; // Velocidad vertical máxima en pixels/segundo (1.2 * 66.67fps) - static constexpr float JUMP_VELOCITY = -80.0F; // Velocidad inicial del salto en pixels/segundo - static constexpr float GRAVITY_FORCE = 155.6F; // Fuerza de gravedad en pixels/segundo² (0.035 * 66.67²) - - // --- Constantes de sonido --- - static constexpr float SOUND_DISTANCE_INTERVAL = 3.0F; // Distancia en píxeles entre cada sonido de salto/caída - - // --- --- Objetos y punteros --- --- - std::shared_ptr room_; // Objeto encargado de gestionar cada habitación del juego - std::unique_ptr sprite_; // Sprite del jugador - - // --- Variables de posición y física --- - float x_ = 0.0F; // Posición del jugador en el eje X - float y_ = 0.0F; // Posición del jugador en el eje Y - float y_prev_ = 0.0F; // Posición Y del frame anterior (para detectar hitos de distancia en sonidos) - float vx_ = 0.0F; // Velocidad/desplazamiento del jugador en el eje X - float vy_ = 0.0F; // Velocidad/desplazamiento del jugador en el eje Y - - // --- Variables de estado --- - State state_ = State::STANDING; // Estado en el que se encuentra el jugador. Util apara saber si está saltando o cayendo - State previous_state_ = State::STANDING; // Estado previo en el que se encontraba el jugador - - // --- Variables de colisión --- - SDL_FRect collider_box_; // Caja de colisión con los enemigos u objetos - std::array collider_points_{}; // Puntos de colisión con el mapa - std::array under_feet_{}; // Contiene los puntos que hay bajo cada pie del jugador - std::array feet_{}; // Contiene los puntos que hay en el pie del jugador - - // --- Variables de juego --- - bool is_on_border_ = false; // Indica si el jugador esta en uno de los cuatro bordes de la pantalla - bool is_alive_ = true; // Indica si el jugador esta vivo o no - bool is_paused_ = false; // Indica si el jugador esta en modo pausa - bool auto_movement_ = false; // Indica si esta siendo arrastrado por una superficie automatica - Room::Border border_ = Room::Border::TOP; // Indica en cual de los cuatro bordes se encuentra - int last_grounded_position_ = 0; // Ultima posición en Y en la que se estaba en contacto con el suelo (hace doble función: tracking de caída + altura inicial del salto) - - // --- Variables de renderizado y sonido --- - Uint8 color_ = 0; // Color del jugador - std::vector jumping_sound_; // Vecor con todos los sonidos del salto - std::vector falling_sound_; // Vecor con todos los sonidos de la caída - - // --- Funciones de inicialización --- - void initSprite(const std::string& animations_path); // Inicializa el sprite del jugador - void initSounds(); // Inicializa los sonidos de salto y caida - void applySpawnValues(const SpawnData& spawn); // Aplica los valores de spawn al jugador - - // --- Funciones de procesamiento de entrada --- - void handleInput(float delta_time); // Comprueba las entradas y modifica variables - - // --- Funciones de gestión de estado --- - void handleState(float delta_time); // Comprueba el estado del jugador y actualiza variables - void transitionToState(State value); // Cambia el estado del jugador - - // --- Funciones de física --- - void applyGravity(float delta_time); // Aplica gravedad al jugador - - // --- Funciones de movimiento y colisión --- - void move(float delta_time); // Orquesta el movimiento del jugador - void moveHorizontal(float delta_time, int direction); // Maneja el movimiento horizontal (-1: izq, 1: der) - void moveVerticalUp(float delta_time); // Maneja el movimiento vertical hacia arriba - void moveVerticalDown(float delta_time); // Maneja el movimiento vertical hacia abajo - void handleSlopeMovement(int direction); // Maneja el movimiento sobre rampas - - // --- Funciones de detección de superficies --- - auto isOnFloor() -> bool; // Comprueba si el jugador tiene suelo debajo de los pies - auto isOnAutoSurface() -> bool; // Comprueba si el jugador esta sobre una superficie automática - auto isOnDownSlope() -> bool; // Comprueba si el jugador está sobre una rampa hacia abajo - - // --- Funciones de actualización de geometría --- - void updateColliderGeometry(); // Actualiza collider_box y collision points - void updateColliderPoints(); // Actualiza los puntos de colisión - void updateFeet(); // Actualiza los puntos de los pies - void placeSprite(); // Coloca el sprite en la posición del jugador - - // --- Funciones de finalización --- - void animate(float delta_time); // Establece la animación del jugador - void handleBorders(); // Comprueba si se halla en alguno de los cuatro bordes - void handleJumpEnd(); // Comprueba si ha finalizado el salto al alcanzar la altura de inicio - auto handleKillingTiles() -> bool; // Comprueba que el jugador no toque ningun tile de los que matan - void playJumpSound(); // Calcula y reproduce el sonido de salto - void playFallSound(); // Calcula y reproduce el sonido de caer -}; \ No newline at end of file diff --git a/source/game/entities/player.md b/source/game/entities/player.md deleted file mode 100644 index eef5115d..00000000 --- a/source/game/entities/player.md +++ /dev/null @@ -1,132 +0,0 @@ -handleInput() -{ - if (checkAction(LEFT)) - { - wannaGo::LEFT; - } - else if (checkAction(RIGHT)) - { - wannaGo::RIGHT; - } - else - { - wannaGo::STAY; - } - - wannaJUMP = (checkAction(JUMP)); -} - -move() -{ - handleHorizontalMovement(); - handleVerticalMovement(); -} - -handleHorizontalMovement() -{ - if (State!=STANDING) - { - return; - } - - if (automovement) - { - vx = FIXED_BY_ROOM; - } - else - { - vx = wannaGo::DIRECTION; - } - - moveAndCollide(); - -} - -handleVerticalMovement() -{ - if (State==STANDING) - { - return; - } - - if (State==JUMPING) - { - applyGravity(); - } - - moveAndCollide(); - -} - - -handleConveyorBelts() -{ - if (!automovement and isOnConveyorBelt and wannaGo::STAY) - { - automovement = true; - } - - if (automovement and !isOnConveyorBelt) - { - automovement = false; - } -} - -handleShouldFall() -{ - if (!isOnFloor and State::STANDING) - { - transitionToState(FALLING); - } -} - -transitionToState(state) -{ - prev = state_; - state_ = state; - - switch (state) - { - case STANDING: - vy = 0; - case JUMPING: - if (prev==STANDING) - { - vy = -MAX_VY; - last_ground_position = y; - } - case FALLING: - last_ground_position = y; - vy = MAX_VY; - vx = 0; - } -} - -updateState() -{ - switch (state) - { - case STANDING: - handleConveyorBelts(); - handleShouldFall(); - if (wannaJump) - { - transitionToState(JUMPING); - } - case JUMPING: - automovement = false; - playJumpingSound(); - handleEndJump(); - case FALLING: - automovement = false; - playFallingSound(); - } -} - -update() -{ - hanldeInput(); - updateState(); - move(); - animate(); -} \ No newline at end of file diff --git a/source/game/scenes/credits.cpp b/source/game/scenes/credits.cpp index 7aaf9cfa..8e36687c 100644 --- a/source/game/scenes/credits.cpp +++ b/source/game/scenes/credits.cpp @@ -10,7 +10,7 @@ #include "core/rendering/screen.hpp" // Para Screen #include "core/rendering/surface.hpp" // Para Surface #include "core/rendering/surface_animated_sprite.hpp" // Para SAnimatedSprite -#include "core/rendering/text.hpp" // Para Text, TEXT_CENTER, TEXT_COLOR +#include "core/rendering/text.hpp" // Para Text, Text::CENTER_FLAG, Text::COLOR_FLAG #include "core/resources/resource_cache.hpp" // Para Resource #include "core/system/global_events.hpp" // Para check #include "game/options.hpp" // Para Options, options, OptionsGame, Sectio... @@ -118,12 +118,12 @@ void Credits::fillTexture() { int pos_y = 0; for (const auto& t : texts_) { - text->writeDX(TEXT_CENTER | TEXT_COLOR, PLAY_AREA_CENTER_X, pos_y * SIZE, t.label, 1, t.color); + text->writeDX(Text::CENTER_FLAG | Text::COLOR_FLAG, PLAY_AREA_CENTER_X, pos_y * SIZE, t.label, 1, t.color); pos_y++; } // Escribe el corazón - const int TEXT_LENGHT = text->lenght(texts_[22].label, 1) - text->lenght(" ", 1); // Se resta el ultimo caracter que es un espacio + const int TEXT_LENGHT = text->length(texts_[22].label, 1) - text->length(" ", 1); // Se resta el ultimo caracter que es un espacio const int POS_X = ((PLAY_AREA_WIDTH - TEXT_LENGHT) / 2) + TEXT_LENGHT; text->writeColored(POS_X, 176, "}", static_cast(PaletteColor::BRIGHT_RED)); Screen::get()->setRendererSurface(previuos_renderer); diff --git a/source/game/scenes/ending.cpp b/source/game/scenes/ending.cpp index d9550a7a..f65317e8 100644 --- a/source/game/scenes/ending.cpp +++ b/source/game/scenes/ending.cpp @@ -211,7 +211,7 @@ void Ending::iniTexts() { for (const auto& txt : texts) { auto text = Resource::Cache::get()->getText("smb2"); - const float WIDTH = text->lenght(txt.caption, 1) + 2 + 2; + const float WIDTH = text->length(txt.caption, 1) + 2 + 2; const float HEIGHT = text->getCharacterSize() + 2 + 2; auto text_color = static_cast(PaletteColor::WHITE); auto shadow_color = static_cast(PaletteColor::BLACK); @@ -222,7 +222,7 @@ void Ending::iniTexts() { st.image_surface = std::make_shared(WIDTH, HEIGHT); auto previuos_renderer = Screen::get()->getRendererSurface(); Screen::get()->setRendererSurface(st.image_surface); - text->writeDX(TEXT_STROKE, 2, 2, txt.caption, 1, text_color, 2, shadow_color); + text->writeDX(Text::STROKE_FLAG, 2, 2, txt.caption, 1, text_color, 2, shadow_color); // Crea el sprite st.image_sprite = std::make_shared(st.image_surface, 0, 0, st.image_surface->getWidth(), st.image_surface->getHeight()); diff --git a/source/game/scenes/ending2.cpp b/source/game/scenes/ending2.cpp index 5e775b63..8b5e89f5 100644 --- a/source/game/scenes/ending2.cpp +++ b/source/game/scenes/ending2.cpp @@ -388,7 +388,7 @@ void Ending2::createSpriteTexts() { } // Calcula las dimensiones del texto - const float W = text->lenght(txt, 1); + const float W = text->length(txt, 1); const float H = text->getCharacterSize(); // Determina la columna y la posición X del texto @@ -424,7 +424,7 @@ void Ending2::createTexts() { // Crea los sprites de texto a partir de la lista for (size_t i = 0; i < list.size(); ++i) { // Calcula constantes - const float W = text->lenght(list[i], 1); + const float W = text->length(list[i], 1); const float H = text->getCharacterSize(); const float X = GAMECANVAS_CENTER_X; const float DX = -(W / 2); @@ -453,7 +453,7 @@ void Ending2::createTexts() { // Crea los sprites de texto a partir de la lista for (size_t i = 0; i < list.size(); ++i) { // Calcula constantes - const float W = text->lenght(list[i], 1); + const float W = text->length(list[i], 1); const float H = text->getCharacterSize(); const float X = GAMECANVAS_CENTER_X; const float DX = -(W / 2); diff --git a/source/game/scenes/game.cpp b/source/game/scenes/game.cpp index 05365c66..d07cf82f 100644 --- a/source/game/scenes/game.cpp +++ b/source/game/scenes/game.cpp @@ -10,7 +10,7 @@ #include "core/input/input.hpp" // Para Input, InputAction, Input::DO_NOT_ALLOW_REPEAT #include "core/rendering/screen.hpp" // Para Screen #include "core/rendering/surface.hpp" // Para Surface -#include "core/rendering/text.hpp" // Para Text, TEXT_CENTER, TEXT_COLOR +#include "core/rendering/text.hpp" // Para Text, Text::CENTER_FLAG, Text::COLOR_FLAG #include "core/resources/resource_cache.hpp" // Para ResourceRoom, Resource #include "core/resources/resource_list.hpp" // Para Asset #include "core/system/global_events.hpp" // Para check @@ -506,7 +506,7 @@ void Game::fillRoomNameTexture() { // Escribe el texto en la textura auto text = Resource::Cache::get()->getText("smb2"); - text->writeDX(TEXT_CENTER | TEXT_COLOR, GAMECANVAS_CENTER_X, text->getCharacterSize() / 2, room_->getName(), 1, room_->getBGColor()); + text->writeDX(Text::CENTER_FLAG | Text::COLOR_FLAG, GAMECANVAS_CENTER_X, text->getCharacterSize() / 2, room_->getName(), 1, room_->getBGColor()); // Deja el renderizador por defecto Screen::get()->setRendererSurface(previuos_renderer); diff --git a/source/game/scenes/game_over.cpp b/source/game/scenes/game_over.cpp index 59e134e0..798eb98a 100644 --- a/source/game/scenes/game_over.cpp +++ b/source/game/scenes/game_over.cpp @@ -10,7 +10,7 @@ #include "core/input/input.hpp" // Para Input #include "core/rendering/screen.hpp" // Para Screen #include "core/rendering/surface_animated_sprite.hpp" // Para SAnimatedSprite -#include "core/rendering/text.hpp" // Para TEXT_CENTER, TEXT_COLOR, Text +#include "core/rendering/text.hpp" // Para Text::CENTER_FLAG, Text::COLOR_FLAG, Text #include "core/resources/resource_cache.hpp" // Para Resource #include "core/system/global_events.hpp" // Para check #include "game/options.hpp" // Para Options, options, OptionsStats, Secti... @@ -68,7 +68,7 @@ void GameOver::render() { auto text = Resource::Cache::get()->getText("smb2"); // Escribe el texto de GAME OVER - text->writeDX(TEXT_CENTER | TEXT_COLOR, GAMECANVAS_CENTER_X, TEXT_Y, "G A M E O V E R", 1, color_); + text->writeDX(Text::CENTER_FLAG | Text::COLOR_FLAG, GAMECANVAS_CENTER_X, TEXT_Y, "G A M E O V E R", 1, color_); // Dibuja los sprites (ya posicionados en el constructor, solo ajustamos Y) player_sprite_->setPosY(TEXT_Y + SPRITE_Y_OFFSET); @@ -78,12 +78,12 @@ void GameOver::render() { // Escribe el texto con las habitaciones y los items const std::string ITEMS_TEXT = std::to_string(Options::stats.items / 100) + std::to_string((Options::stats.items % 100) / 10) + std::to_string(Options::stats.items % 10); const std::string ROOMS_TEXT = std::to_string(Options::stats.rooms / 100) + std::to_string((Options::stats.rooms % 100) / 10) + std::to_string(Options::stats.rooms % 10); - text->writeDX(TEXT_CENTER | TEXT_COLOR, GAMECANVAS_CENTER_X, TEXT_Y + ITEMS_Y_OFFSET, "ITEMS: " + ITEMS_TEXT, 1, color_); - text->writeDX(TEXT_CENTER | TEXT_COLOR, GAMECANVAS_CENTER_X, TEXT_Y + ROOMS_Y_OFFSET, "ROOMS: " + ROOMS_TEXT, 1, color_); + text->writeDX(Text::CENTER_FLAG | Text::COLOR_FLAG, GAMECANVAS_CENTER_X, TEXT_Y + ITEMS_Y_OFFSET, "ITEMS: " + ITEMS_TEXT, 1, color_); + text->writeDX(Text::CENTER_FLAG | Text::COLOR_FLAG, GAMECANVAS_CENTER_X, TEXT_Y + ROOMS_Y_OFFSET, "ROOMS: " + ROOMS_TEXT, 1, color_); // Escribe el texto con "Tu peor pesadilla" - text->writeDX(TEXT_CENTER | TEXT_COLOR, GAMECANVAS_CENTER_X, TEXT_Y + NIGHTMARE_TITLE_Y_OFFSET, "YOUR WORST NIGHTMARE IS", 1, color_); - text->writeDX(TEXT_CENTER | TEXT_COLOR, GAMECANVAS_CENTER_X, TEXT_Y + NIGHTMARE_TEXT_Y_OFFSET, Options::stats.worst_nightmare, 1, color_); + text->writeDX(Text::CENTER_FLAG | Text::COLOR_FLAG, GAMECANVAS_CENTER_X, TEXT_Y + NIGHTMARE_TITLE_Y_OFFSET, "YOUR WORST NIGHTMARE IS", 1, color_); + text->writeDX(Text::CENTER_FLAG | Text::COLOR_FLAG, GAMECANVAS_CENTER_X, TEXT_Y + NIGHTMARE_TEXT_Y_OFFSET, Options::stats.worst_nightmare, 1, color_); // Vuelca el contenido del renderizador en pantalla Screen::get()->render(); diff --git a/source/game/scenes/title.cpp b/source/game/scenes/title.cpp index 720c65b2..217789b2 100644 --- a/source/game/scenes/title.cpp +++ b/source/game/scenes/title.cpp @@ -10,7 +10,7 @@ #include "core/rendering/screen.hpp" // Para Screen #include "core/rendering/surface.hpp" // Para Surface #include "core/rendering/surface_sprite.hpp" // Para SSprite -#include "core/rendering/text.hpp" // Para Text, TEXT_CENTER, TEXT_COLOR +#include "core/rendering/text.hpp" // Para Text, Text::CENTER_FLAG, Text::COLOR_FLAG #include "core/resources/resource_cache.hpp" // Para Resource #include "core/resources/resource_list.hpp" // Para Asset #include "core/system/global_events.hpp" // Para check @@ -58,7 +58,7 @@ void Title::initMarquee() { Glyph l; l.letter = long_text_[i]; // char directo, no substring l.x = MARQUEE_START_X; // Usar constante - l.width = marquee_text_->lenght(std::string(1, long_text_[i])); // Pre-calcular ancho + l.width = marquee_text_->length(std::string(1, long_text_[i])); // Pre-calcular ancho l.enabled = false; letters_.push_back(l); } @@ -457,7 +457,7 @@ void Title::createCheevosTexture() { const std::string CHEEVOS_OWNER = "PROJECTS"; const std::string CHEEVOS_LIST_CAPTION = CHEEVOS_OWNER + " (" + std::to_string(Cheevos::get()->getTotalUnlockedAchievements()) + " / " + std::to_string(Cheevos::get()->size()) + ")"; int pos = 2; - TEXT->writeDX(TEXT_CENTER | TEXT_COLOR, cheevos_surface_->getWidth() / 2, pos, CHEEVOS_LIST_CAPTION, 1, stringToColor("bright_green")); + TEXT->writeDX(Text::CENTER_FLAG | Text::COLOR_FLAG, cheevos_surface_->getWidth() / 2, pos, CHEEVOS_LIST_CAPTION, 1, stringToColor("bright_green")); pos += TEXT->getCharacterSize(); const Uint8 CHEEVO_LOCKED_COLOR = stringToColor("white"); const Uint8 CHEEVO_UNLOCKED_COLOR = stringToColor("bright_green"); @@ -469,9 +469,9 @@ void Title::createCheevosTexture() { pos += CHEEVOS_PADDING; constexpr int HALF = CHEEVOS_PADDING / 2; cheevos_surface_->drawLine(LINE_X1, pos - HALF - 1, LINE_X2, pos - HALF - 1, CHEEVO_COLOR); - TEXT->writeDX(TEXT_CENTER | TEXT_COLOR, CHEEVOS_TEXTURE_WIDTH / 2, pos, cheevo.caption, 1, CHEEVO_COLOR); + TEXT->writeDX(Text::CENTER_FLAG | Text::COLOR_FLAG, CHEEVOS_TEXTURE_WIDTH / 2, pos, cheevo.caption, 1, CHEEVO_COLOR); pos += TEXT->getCharacterSize() + 1; - TEXT->writeDX(TEXT_CENTER | TEXT_COLOR, CHEEVOS_TEXTURE_WIDTH / 2, pos, cheevo.description, 1, CHEEVO_COLOR); + TEXT->writeDX(Text::CENTER_FLAG | Text::COLOR_FLAG, CHEEVOS_TEXTURE_WIDTH / 2, pos, cheevo.description, 1, CHEEVO_COLOR); pos += TEXT->getCharacterSize(); } @@ -522,10 +522,10 @@ void Title::renderMainMenu() { const int TOTAL_HEIGHT = 3 * SPACING; // 3 espacios entre 4 items const int START_Y = MENU_CENTER_Y - (TOTAL_HEIGHT / 2); - menu_text_->writeDX(TEXT_CENTER | TEXT_COLOR, PLAY_AREA_CENTER_X, START_Y, "1. PLAY", 1, COLOR); - menu_text_->writeDX(TEXT_CENTER | TEXT_COLOR, PLAY_AREA_CENTER_X, START_Y + SPACING, "2. REDEFINE KEYBOARD", 1, COLOR); - menu_text_->writeDX(TEXT_CENTER | TEXT_COLOR, PLAY_AREA_CENTER_X, START_Y + (2 * SPACING), "3. REDEFINE JOYSTICK", 1, COLOR); - menu_text_->writeDX(TEXT_CENTER | TEXT_COLOR, PLAY_AREA_CENTER_X, START_Y + (3 * SPACING), "4. PROJECTS", 1, COLOR); + menu_text_->writeDX(Text::CENTER_FLAG | Text::COLOR_FLAG, PLAY_AREA_CENTER_X, START_Y, "1. PLAY", 1, COLOR); + menu_text_->writeDX(Text::CENTER_FLAG | Text::COLOR_FLAG, PLAY_AREA_CENTER_X, START_Y + SPACING, "2. REDEFINE KEYBOARD", 1, COLOR); + menu_text_->writeDX(Text::CENTER_FLAG | Text::COLOR_FLAG, PLAY_AREA_CENTER_X, START_Y + (2 * SPACING), "3. REDEFINE JOYSTICK", 1, COLOR); + menu_text_->writeDX(Text::CENTER_FLAG | Text::COLOR_FLAG, PLAY_AREA_CENTER_X, START_Y + (3 * SPACING), "4. PROJECTS", 1, COLOR); } // Dibuja el menu de logros @@ -674,11 +674,11 @@ void Title::renderKeyboardRemap() { // Mensaje principal: "PRESS KEY FOR [ACTION]" o "KEYS DEFINED" si completado if (remap_step_ >= 3) { - menu_text_->writeDX(TEXT_CENTER | TEXT_COLOR, PLAY_AREA_CENTER_X, START_Y, "KEYS DEFINED", 1, COLOR); + menu_text_->writeDX(Text::CENTER_FLAG | Text::COLOR_FLAG, PLAY_AREA_CENTER_X, START_Y, "KEYS DEFINED", 1, COLOR); } else { const std::string ACTION = getActionName(remap_step_); const std::string MESSAGE = "PRESS KEY FOR " + ACTION; - menu_text_->writeDX(TEXT_CENTER | TEXT_COLOR, PLAY_AREA_CENTER_X, START_Y, MESSAGE, 1, COLOR); + menu_text_->writeDX(Text::CENTER_FLAG | Text::COLOR_FLAG, PLAY_AREA_CENTER_X, START_Y, MESSAGE, 1, COLOR); } // Mostrar teclas ya capturadas (con espaciado de 2 líneas desde el mensaje principal) @@ -686,22 +686,22 @@ void Title::renderKeyboardRemap() { if (remap_step_ > 0) { const std::string LEFT_KEY = SDL_GetScancodeName(temp_keys_[0]); const std::string LEFT_MSG = "LEFT: " + LEFT_KEY; - menu_text_->writeDX(TEXT_CENTER | TEXT_COLOR, PLAY_AREA_CENTER_X, KEYS_START_Y, LEFT_MSG, 1, COLOR); + menu_text_->writeDX(Text::CENTER_FLAG | Text::COLOR_FLAG, PLAY_AREA_CENTER_X, KEYS_START_Y, LEFT_MSG, 1, COLOR); } if (remap_step_ > 1) { const std::string RIGHT_KEY = SDL_GetScancodeName(temp_keys_[1]); const std::string RIGHT_MSG = "RIGHT: " + RIGHT_KEY; - menu_text_->writeDX(TEXT_CENTER | TEXT_COLOR, PLAY_AREA_CENTER_X, KEYS_START_Y + LINE_SPACING, RIGHT_MSG, 1, COLOR); + menu_text_->writeDX(Text::CENTER_FLAG | Text::COLOR_FLAG, PLAY_AREA_CENTER_X, KEYS_START_Y + LINE_SPACING, RIGHT_MSG, 1, COLOR); } if (remap_step_ >= 3) { const std::string JUMP_KEY = SDL_GetScancodeName(temp_keys_[2]); const std::string JUMP_MSG = "JUMP: " + JUMP_KEY; - menu_text_->writeDX(TEXT_CENTER | TEXT_COLOR, PLAY_AREA_CENTER_X, KEYS_START_Y + (2 * LINE_SPACING), JUMP_MSG, 1, COLOR); + menu_text_->writeDX(Text::CENTER_FLAG | Text::COLOR_FLAG, PLAY_AREA_CENTER_X, KEYS_START_Y + (2 * LINE_SPACING), JUMP_MSG, 1, COLOR); } // Mensaje de error si existe (4 líneas después del inicio de las teclas) if (!remap_error_message_.empty()) { - menu_text_->writeDX(TEXT_CENTER | TEXT_COLOR, PLAY_AREA_CENTER_X, KEYS_START_Y + (4 * LINE_SPACING), remap_error_message_, 1, ERROR_COLOR); + menu_text_->writeDX(Text::CENTER_FLAG | Text::COLOR_FLAG, PLAY_AREA_CENTER_X, KEYS_START_Y + (4 * LINE_SPACING), remap_error_message_, 1, ERROR_COLOR); } } @@ -723,11 +723,11 @@ void Title::renderJoystickRemap() { // Mensaje principal: "PRESS BUTTON FOR [ACTION]" o "BUTTONS DEFINED" si completado if (remap_step_ >= 3) { - menu_text_->writeDX(TEXT_CENTER | TEXT_COLOR, PLAY_AREA_CENTER_X, START_Y, "BUTTONS DEFINED", 1, COLOR); + menu_text_->writeDX(Text::CENTER_FLAG | Text::COLOR_FLAG, PLAY_AREA_CENTER_X, START_Y, "BUTTONS DEFINED", 1, COLOR); } else { const std::string ACTION = getActionName(remap_step_); const std::string MESSAGE = "PRESS BUTTON FOR " + ACTION; - menu_text_->writeDX(TEXT_CENTER | TEXT_COLOR, PLAY_AREA_CENTER_X, START_Y, MESSAGE, 1, COLOR); + menu_text_->writeDX(Text::CENTER_FLAG | Text::COLOR_FLAG, PLAY_AREA_CENTER_X, START_Y, MESSAGE, 1, COLOR); } // Mostrar botones ya capturados (con espaciado de 2 líneas desde el mensaje principal) @@ -735,22 +735,22 @@ void Title::renderJoystickRemap() { if (remap_step_ > 0) { const std::string LEFT_BTN = getButtonName(temp_buttons_[0]); const std::string LEFT_MSG = "LEFT: " + LEFT_BTN; - menu_text_->writeDX(TEXT_CENTER | TEXT_COLOR, PLAY_AREA_CENTER_X, BUTTONS_START_Y, LEFT_MSG, 1, COLOR); + menu_text_->writeDX(Text::CENTER_FLAG | Text::COLOR_FLAG, PLAY_AREA_CENTER_X, BUTTONS_START_Y, LEFT_MSG, 1, COLOR); } if (remap_step_ > 1) { const std::string RIGHT_BTN = getButtonName(temp_buttons_[1]); const std::string RIGHT_MSG = "RIGHT: " + RIGHT_BTN; - menu_text_->writeDX(TEXT_CENTER | TEXT_COLOR, PLAY_AREA_CENTER_X, BUTTONS_START_Y + LINE_SPACING, RIGHT_MSG, 1, COLOR); + menu_text_->writeDX(Text::CENTER_FLAG | Text::COLOR_FLAG, PLAY_AREA_CENTER_X, BUTTONS_START_Y + LINE_SPACING, RIGHT_MSG, 1, COLOR); } if (remap_step_ >= 3) { const std::string JUMP_BTN = getButtonName(temp_buttons_[2]); const std::string JUMP_MSG = "JUMP: " + JUMP_BTN; - menu_text_->writeDX(TEXT_CENTER | TEXT_COLOR, PLAY_AREA_CENTER_X, BUTTONS_START_Y + (2 * LINE_SPACING), JUMP_MSG, 1, COLOR); + menu_text_->writeDX(Text::CENTER_FLAG | Text::COLOR_FLAG, PLAY_AREA_CENTER_X, BUTTONS_START_Y + (2 * LINE_SPACING), JUMP_MSG, 1, COLOR); } // Mensaje de error si existe (4 líneas después del inicio de los botones) if (!remap_error_message_.empty()) { - menu_text_->writeDX(TEXT_CENTER | TEXT_COLOR, PLAY_AREA_CENTER_X, BUTTONS_START_Y + (4 * LINE_SPACING), remap_error_message_, 1, ERROR_COLOR); + menu_text_->writeDX(Text::CENTER_FLAG | Text::COLOR_FLAG, PLAY_AREA_CENTER_X, BUTTONS_START_Y + (4 * LINE_SPACING), remap_error_message_, 1, ERROR_COLOR); } } diff --git a/source/game/ui/notifier.cpp b/source/game/ui/notifier.cpp index 56a0a60c..a7396f0f 100644 --- a/source/game/ui/notifier.cpp +++ b/source/game/ui/notifier.cpp @@ -12,7 +12,7 @@ #include "core/rendering/screen.hpp" // Para Screen #include "core/rendering/surface.hpp" // Para Surface #include "core/rendering/surface_sprite.hpp" // Para SSprite -#include "core/rendering/text.hpp" // Para Text, TEXT_CENTER, TEXT_COLOR +#include "core/rendering/text.hpp" // Para Text, Text::CENTER_FLAG, Text::COLOR_FLAG #include "core/resources/resource_cache.hpp" // Para Resource #include "game/options.hpp" // Para Options, options, NotificationPosition #include "utils/delta_timer.hpp" // Para DeltaTimer @@ -220,7 +220,7 @@ void Notifier::show(std::vector texts, TextAlign text_is, Uint32 di text_->writeColored(PADDING_IN_H + ICON_SPACE, PADDING_IN_V + (iterator * (TEXT_SIZE + 1)), text, COLOR); break; case TextAlign::CENTER: - text_->writeDX(TEXT_CENTER | TEXT_COLOR, WIDTH / 2, PADDING_IN_V + (iterator * (TEXT_SIZE + 1)), text, 1, COLOR); + text_->writeDX(Text::CENTER_FLAG | Text::COLOR_FLAG, WIDTH / 2, PADDING_IN_V + (iterator * (TEXT_SIZE + 1)), text, 1, COLOR); break; default: break;