From cd836862c0eaea451abc949c5637f0b2232cb054 Mon Sep 17 00:00:00 2001 From: Sergio Valor Date: Wed, 29 Oct 2025 09:21:05 +0100 Subject: [PATCH] =?UTF-8?q?style:=20corregides=20les=20cap=C3=A7aleres=20d?= =?UTF-8?q?e=20game/entities?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CLAUDE.md | 2 +- source/game/entities/enemy.cpp | 2 +- source/game/entities/enemy.hpp | 79 ++++----- source/game/entities/item.cpp | 2 +- source/game/entities/item.hpp | 79 ++++----- source/game/entities/player.cpp | 70 ++++---- source/game/entities/player.hpp | 296 ++++++++++++-------------------- source/game/gameplay/room.cpp | 14 +- source/game/gameplay/room.hpp | 36 ++-- source/game/scenes/game.cpp | 18 +- source/game/scenes/game.hpp | 32 ++-- 11 files changed, 270 insertions(+), 360 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index 4abb55c..6338a64 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -450,7 +450,7 @@ Game code **Variables:** - `snake_case` for member variables with `_` suffix: `x_`, `y_`, `sprite_` -- `UPPER_CASE` for constants: `BLOCK`, `MAX_VY_`, `WIDTH_` +- `UPPER_CASE` for constants: `BLOCK`, `MAX_VY`, `WIDTH` - Private members: `private_member_` **Structs for Data:** diff --git a/source/game/entities/enemy.cpp b/source/game/entities/enemy.cpp index 9f69cd9..0c4554d 100644 --- a/source/game/entities/enemy.cpp +++ b/source/game/entities/enemy.cpp @@ -9,7 +9,7 @@ #include "utils/utils.hpp" // Para stringToColor // Constructor -Enemy::Enemy(const EnemyData& enemy) +Enemy::Enemy(const Data& enemy) : sprite_(std::make_shared(Resource::get()->getSurface(enemy.surface_path), Resource::get()->getAnimations(enemy.animation_path))), color_string_(enemy.color), x1_(enemy.x1), diff --git a/source/game/entities/enemy.hpp b/source/game/entities/enemy.hpp index 5bd2d75..96dbe63 100644 --- a/source/game/entities/enemy.hpp +++ b/source/game/entities/enemy.hpp @@ -6,32 +6,46 @@ #include // Para string class SurfaceAnimatedSprite; // lines 7-7 -// Estructura para pasar los datos de un enemigo -struct EnemyData { - std::string surface_path; // Ruta al fichero con la textura - std::string animation_path; // Ruta al fichero con la animación - int w; // Anchura del enemigo - int h; // Altura del enemigo - float x; // Posición inicial en el eje X - float y; // Posición inicial en el eje Y - float vx; // Velocidad en el eje X - float vy; // Velocidad en el eje Y - 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 - bool flip; // Indica si el enemigo hace flip al terminar su ruta - bool mirror; // Indica si el enemigo está volteado verticalmente - int frame; // Frame inicial para la animación del enemigo - std::string color; // Color del enemigo -}; - class Enemy { + public: + // --- Estructuras --- + struct Data { + std::string surface_path{}; // Ruta al fichero con la textura + std::string animation_path{}; // Ruta al fichero con la animación + int w = 0; // Anchura del enemigo + int h = 0; // Altura del enemigo + 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; + }; + + // --- Constructor y Destructor --- + explicit Enemy(const Data& enemy); + ~Enemy() = default; + + // --- 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 + // --- Objetos y punteros --- std::shared_ptr sprite_; // Sprite del enemigo - // Variables + // --- 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 @@ -42,25 +56,6 @@ class Enemy { 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 + // --- Comprueba si ha llegado al limite del recorrido para darse media vuelta --- void checkPath(); - - public: - // Constructor - explicit Enemy(const EnemyData& enemy); - - // Destructor - ~Enemy() = default; - - // Pinta el enemigo en pantalla - void render(); - - // Actualiza las variables del objeto - void update(float delta_time); - - // Devuelve el rectangulo que contiene al enemigo - auto getRect() -> SDL_FRect; - - // Obtiene el rectangulo de colision del enemigo - auto getCollider() -> SDL_FRect&; }; diff --git a/source/game/entities/item.cpp b/source/game/entities/item.cpp index fff81de..108fd52 100644 --- a/source/game/entities/item.cpp +++ b/source/game/entities/item.cpp @@ -4,7 +4,7 @@ #include "core/resources/resource.hpp" // Para Resource // Constructor -Item::Item(const ItemData &item) +Item::Item(const Data& item) : sprite_(std::make_shared(Resource::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) { diff --git a/source/game/entities/item.hpp b/source/game/entities/item.hpp index 1ccc653..1f131b1 100644 --- a/source/game/entities/item.hpp +++ b/source/game/entities/item.hpp @@ -7,56 +7,45 @@ #include // Para vector class SurfaceSprite; -struct ItemData { - 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 - 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 - ItemData() = default; -}; - 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 + 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; + }; + + // Constructor y Destructor + explicit Item(const Data& item); + ~Item() = default; + + // --- 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 + // --- Constantes --- static constexpr float ITEM_SIZE = 8; static constexpr float COLOR_CHANGE_INTERVAL = 0.06F; // Intervalo de cambio de color en segundos (4 frames a 66.67fps) - // Objetos y punteros + // --- 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 - - public: - // Constructor - explicit Item(const ItemData &item); - - // Destructor - ~Item() = default; - - // Pinta el objeto en pantalla - void render() const; - - // Actualiza las variables del objeto - void update(float delta_time); - - // Pausa/despausa el item - void setPaused(bool paused) { is_paused_ = paused; } - - // Obtiene el rectangulo de colision del objeto - auto getCollider() -> SDL_FRect& { return collider_; } - - // Obtiene su ubicación - auto getPos() -> SDL_FPoint; - - // Asigna los colores del objeto - void setColors(Uint8 col1, Uint8 col2); + // --- 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 }; \ No newline at end of file diff --git a/source/game/entities/player.cpp b/source/game/entities/player.cpp index bac56d5..2065508 100644 --- a/source/game/entities/player.cpp +++ b/source/game/entities/player.cpp @@ -15,12 +15,12 @@ #include "utils/defines.hpp" // Para RoomBorder::BOTTOM, RoomBorder::LEFT, RoomBorder::RIGHT // Constructor -Player::Player(const PlayerData& player) +Player::Player(const Data& player) : room_(player.room) { // Inicializa algunas variables initSprite(player.texture_path, player.animations_path); setColor(); - applySpawnValues(player.spawn); + applySpawnValues(player.spawn_data); placeSprite(); initSounds(); @@ -51,12 +51,12 @@ void Player::render() { // Actualiza las variables del objeto void Player::update(float delta_time) { if (!is_paused_) { - checkInput(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 - checkBorders(); // Comprueba si está situado en alguno de los cuatro bordes de la habitación - checkJumpEnd(); // Comprueba si ha finalizado el salto al alcanzar la altura de inicio - checkKillingTiles(); // Comprueba que el jugador no toque ningun tile de los que matan} + checkInput(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 + checkBorders(); // Comprueba si está situado en alguno de los cuatro bordes de la habitación + checkJumpEnd(); // Comprueba si ha finalizado el salto al alcanzar la altura de inicio + checkKillingTiles(); // Comprueba que el jugador no toque ningun tile de los que matan} } } @@ -65,7 +65,7 @@ void Player::checkInput(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_ != PlayerState::STANDING) { + if (state_ != State::STANDING) { return; } @@ -106,7 +106,7 @@ void Player::checkInput(float delta_time) { // Ya que se coloca el estado s_standing al cambiar de pantalla if (isOnFloor() || isOnAutoSurface()) { - setState(PlayerState::JUMPING); + setState(State::JUMPING); vy_ = JUMP_VELOCITY; jump_init_pos_ = y_; jumping_time_ = 0.0F; @@ -144,24 +144,24 @@ void Player::checkBorders() { // Comprueba el estado del jugador void Player::checkState(float delta_time) { // Actualiza las variables en función del estado - if (state_ == PlayerState::FALLING) { + if (state_ == State::FALLING) { vx_ = 0.0F; vy_ = MAX_VY; falling_time_ += delta_time; playFallSound(); } - else if (state_ == PlayerState::STANDING) { + else if (state_ == State::STANDING) { // Calcula la distancia de caída en pixels (velocidad * tiempo) const float FALLING_DISTANCE = MAX_VY * falling_time_; - if (previous_state_ == PlayerState::FALLING && FALLING_DISTANCE > MAX_FALLING_HEIGHT) { // Si cae de muy alto, el jugador muere + if (previous_state_ == State::FALLING && FALLING_DISTANCE > MAX_FALLING_HEIGHT) { // Si cae de muy alto, el jugador muere is_alive_ = false; } vy_ = 0.0F; jumping_time_ = 0.0F; falling_time_ = 0.0F; if (!isOnFloor() && !isOnAutoSurface() && !isOnDownSlope()) { - setState(PlayerState::FALLING); + setState(State::FALLING); vx_ = 0.0F; vy_ = MAX_VY; falling_time_ += delta_time; @@ -169,7 +169,7 @@ void Player::checkState(float delta_time) { } } - else if (state_ == PlayerState::JUMPING) { + else if (state_ == State::JUMPING) { falling_time_ = 0.0F; jumping_time_ += delta_time; playJumpSound(); @@ -181,12 +181,12 @@ void Player::switchBorders() { switch (border_) { case RoomBorder::TOP: y_ = PLAY_AREA_BOTTOM - HEIGHT - BLOCK; - setState(PlayerState::STANDING); + setState(State::STANDING); break; case RoomBorder::BOTTOM: y_ = PLAY_AREA_TOP; - setState(PlayerState::STANDING); + setState(State::STANDING); break; case RoomBorder::RIGHT: @@ -210,7 +210,7 @@ void Player::switchBorders() { 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_ == PlayerState::JUMPING) { + if (state_ == State::JUMPING) { vy_ += GRAVITY_FORCE * delta_time; vy_ = std::min(vy_, MAX_VY); } @@ -243,7 +243,7 @@ void Player::moveHorizontalLeft(float delta_time) { } // Si ha tocado alguna rampa mientras camina (sin saltar), asciende - if (state_ != PlayerState::JUMPING) { + if (state_ != State::JUMPING) { const LineVertical LEFT_SIDE = {.x = static_cast(x_), .y1 = static_cast(y_) + static_cast(HEIGHT) - 2, .y2 = static_cast(y_) + static_cast(HEIGHT) - 1}; // Comprueba solo los dos pixels de abajo const int LY = room_->checkLeftSlopes(&LEFT_SIDE); if (LY > -1) { @@ -252,7 +252,7 @@ void Player::moveHorizontalLeft(float delta_time) { } // Si está bajando la rampa, recoloca al jugador - if (isOnDownSlope() && state_ != PlayerState::JUMPING) { + if (isOnDownSlope() && state_ != State::JUMPING) { y_ += 1; } } @@ -284,7 +284,7 @@ void Player::moveHorizontalRight(float delta_time) { } // Si ha tocado alguna rampa mientras camina (sin saltar), asciende - if (state_ != PlayerState::JUMPING) { + if (state_ != State::JUMPING) { const LineVertical RIGHT_SIDE = {.x = static_cast(x_) + static_cast(WIDTH) - 1, .y1 = static_cast(y_) + static_cast(HEIGHT) - 2, .y2 = static_cast(y_) + static_cast(HEIGHT) - 1}; // Comprueba solo los dos pixels de abajo const int RY = room_->checkRightSlopes(&RIGHT_SIDE); if (RY > -1) { @@ -293,7 +293,7 @@ void Player::moveHorizontalRight(float delta_time) { } // Si está bajando la rampa, recoloca al jugador - if (isOnDownSlope() && state_ != PlayerState::JUMPING) { + if (isOnDownSlope() && state_ != State::JUMPING) { y_ += 1; } } @@ -322,7 +322,7 @@ void Player::moveVerticalUp(float delta_time) { } else { // Si hay colisión lo mueve hasta donde no colisiona y entra en caída y_ = POS + 1; - setState(PlayerState::FALLING); + setState(State::FALLING); } } @@ -345,13 +345,13 @@ void Player::moveVerticalDown(float delta_time) { if (POS > -1) { // Si hay colisión lo mueve hasta donde no colisiona y pasa a estar sobre la superficie y_ = POS - HEIGHT; - setState(PlayerState::STANDING); + setState(State::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 - if (state_ != PlayerState::JUMPING) { // Las rampas no se miran si se está saltando + if (state_ != State::JUMPING) { // Las rampas no se miran si se está saltando 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}; @@ -360,7 +360,7 @@ void Player::moveVerticalDown(float delta_time) { // No está saltando y hay colisión con una rampa // Calcula la nueva posición y_ = POINT - HEIGHT; - setState(PlayerState::STANDING); + setState(State::STANDING); #ifdef _DEBUG debug_color_ = static_cast(PaletteColor::YELLOW); debug_point_ = {.x = x_ + (WIDTH / 2), .y = POINT}; @@ -384,8 +384,8 @@ void Player::moveVerticalDown(float delta_time) { // Recalcula la posición del jugador y su animación void Player::move(float delta_time) { last_position_ = {.x = x_, .y = y_}; // Guarda la posicion actual antes de modificarla - applyGravity(delta_time); // Aplica gravedad al jugador - checkState(delta_time); // Comprueba el estado del jugador + applyGravity(delta_time); // Aplica gravedad al jugador + checkState(delta_time); // Comprueba el estado del jugador #ifdef _DEBUG debug_color_ = static_cast(PaletteColor::GREEN); @@ -399,13 +399,13 @@ void Player::move(float delta_time) { } // Si ha salido del suelo, el jugador cae - if (state_ == PlayerState::STANDING && !isOnFloor()) { - setState(PlayerState::FALLING); + if (state_ == State::STANDING && !isOnFloor()) { + setState(State::FALLING); auto_movement_ = false; } // Si ha salido de una superficie automatica, detiene el movimiento automatico - if (state_ == PlayerState::STANDING && isOnFloor() && !isOnAutoSurface()) { + if (state_ == State::STANDING && isOnFloor() && !isOnAutoSurface()) { auto_movement_ = false; } @@ -434,11 +434,11 @@ void Player::animate(float delta_time) { // Comprueba si ha finalizado el salto al alcanzar la altura de inicio void Player::checkJumpEnd() { - if (state_ == PlayerState::JUMPING) { + if (state_ == State::JUMPING) { if (vy_ > 0) { if (y_ >= jump_init_pos_) { // Si alcanza la altura de salto inicial, pasa al estado de caída - setState(PlayerState::FALLING); + setState(State::FALLING); vy_ = MAX_VY; jumping_time_ = 0.0F; } @@ -606,7 +606,7 @@ void Player::updateFeet() { } // Cambia el estado del jugador -void Player::setState(PlayerState value) { +void Player::setState(State value) { previous_state_ = state_; state_ = value; @@ -630,7 +630,7 @@ void Player::initSounds() { } // Aplica los valores de spawn al jugador -void Player::applySpawnValues(const PlayerSpawn& spawn) { +void Player::applySpawnValues(const SpawnData& spawn) { x_ = spawn.x; y_ = spawn.y; vx_ = spawn.vx; diff --git a/source/game/entities/player.hpp b/source/game/entities/player.hpp index 87153d6..c931d58 100644 --- a/source/game/entities/player.hpp +++ b/source/game/entities/player.hpp @@ -13,77 +13,93 @@ #include "utils/utils.hpp" // Para Color struct JA_Sound_t; // lines 13-13 -enum class PlayerState { - STANDING, - JUMPING, - FALLING, -}; - -struct PlayerSpawn { - float x; - float y; - float vx; - float vy; - int jump_init_pos; - PlayerState state; - SDL_FlipMode flip; - - // Constructor por defecto - PlayerSpawn() - : x(0), - y(0), - vx(0), - vy(0), - jump_init_pos(0), - state(PlayerState::STANDING), - flip(SDL_FLIP_NONE) {} - - // Constructor - PlayerSpawn(float x, float y, float vx, float vy, int jump_init_pos, PlayerState state, SDL_FlipMode flip) - : x(x), - y(y), - vx(vx), - vy(vy), - jump_init_pos(jump_init_pos), - state(state), - flip(flip) {} -}; - -struct PlayerData { - PlayerSpawn spawn; - std::string texture_path; - std::string animations_path; - std::shared_ptr room; - - // Constructor - PlayerData(PlayerSpawn spawn, std::string texture_path, std::string animations_path, std::shared_ptr room) - : spawn(spawn), - texture_path(std::move(std::move(texture_path))), - animations_path(std::move(std::move(animations_path))), - room(std::move(std::move(room))) {} -}; - 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 jump_init_pos = 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 jump_init_pos, State state, SDL_FlipMode flip) + : x(x), + y(y), + vx(vx), + vy(vy), + jump_init_pos(jump_init_pos), + state(state), + flip(flip) {} + }; + + struct Data { + SpawnData spawn_data{}; + std::string texture_path{}; + std::string animations_path{}; + std::shared_ptr room = nullptr; + + // Constructor por defecto + Data() = default; + + // Constructor con parámetros + Data(SpawnData spawn_data, std::string texture_path, std::string animations_path, std::shared_ptr room) + : spawn_data(std::move(spawn_data)), + texture_path(std::move(texture_path)), + 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 getOnBorder() const -> bool { return is_on_border_; } // Indica si el jugador esta en uno de los cuatro bordes de la pantalla + [[nodiscard]] auto getBorder() const -> RoomBorder { 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_, jump_init_pos_, 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 = BLOCK * 4; // Altura maxima permitida de caída en pixels + // --- Constantes --- + static constexpr int WIDTH = 8; // Ancho del jugador + static constexpr int HEIGHT = 16; // ALto del jugador + static constexpr int MAX_FALLING_HEIGHT = BLOCK * 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 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_INTERVAL = 0.06F; // Intervalo entre sonidos de salto/caída en segundos (4 frames a 66.67fps) + // --- Constantes de sonido --- + static constexpr float SOUND_INTERVAL = 0.06F; // Intervalo entre sonidos de salto/caída en segundos (4 frames a 66.67fps) - // Objetos y punteros + // --- --- Objetos y punteros --- --- std::shared_ptr room_; // Objeto encargado de gestionar cada habitación del juego std::shared_ptr sprite_; // Sprite del jugador - // Variables + // --- Variables --- float x_; // Posición del jugador en el eje X float y_; // Posición del jugador en el eje Y float vx_; // Velocidad/desplazamiento del jugador en el eje X @@ -93,8 +109,8 @@ class Player { std::vector collider_points_; // Puntos de colisión con el mapa std::vector under_feet_; // Contiene los puntos que hay bajo cada pie del jugador std::vector feet_; // Contiene los puntos que hay en el pie del jugador - PlayerState state_; // Estado en el que se encuentra el jugador. Util apara saber si está saltando o cayendo - PlayerState previous_state_; // Estado previo en el que se encontraba el jugador + State state_; // Estado en el que se encuentra el jugador. Util apara saber si está saltando o cayendo + State previous_state_; // Estado previo en el que se encontraba el jugador 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 @@ -107,130 +123,40 @@ class Player { float jumping_time_ = 0.0F; // Tiempo acumulado de salto en segundos float falling_time_ = 0.0F; // Tiempo acumulado de caída en segundos + // --- Funciones --- + void checkInput(float delta_time); // Comprueba las entradas y modifica variables + void checkBorders(); // Comprueba si se halla en alguno de los cuatro bordes + void checkState(float delta_time); // Comprueba el estado del jugador + void applyGravity(float delta_time); // Aplica gravedad al jugador + void move(float delta_time); // Recalcula la posición del jugador y su animación + void moveHorizontalLeft(float delta_time); // Maneja el movimiento horizontal hacia la izquierda + void moveHorizontalRight(float delta_time); // Maneja el movimiento horizontal hacia la derecha + void moveVerticalUp(float delta_time); // Maneja el movimiento vertical hacia arriba + void moveVerticalDown(float delta_time); // Maneja el movimiento vertical hacia abajo + void animate(float delta_time); // Establece la animación del jugador + void checkJumpEnd(); // Comprueba si ha finalizado el salto al alcanzar la altura de inicio + void playJumpSound(); // Calcula y reproduce el sonido de salto + void playFallSound(); // Calcula y reproduce el sonido de caer + 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 + auto checkKillingTiles() -> bool; // Comprueba que el jugador no toque ningun tile de los que matan + void updateColliderPoints(); // Actualiza los puntos de colisión + void updateFeet(); // Actualiza los puntos de los pies + void setState(State value); // Cambia el estado del jugador + void initSounds(); // Inicializa los sonidos de salto y caida + void placeSprite() { sprite_->setPos(x_, y_); } // Coloca el sprite en la posición del jugador + void applySpawnValues(const SpawnData& spawn); // Aplica los valores de spawn al jugador + void initSprite(const std::string& surface_path, const std::string& animations_path); // Inicializa el sprite del jugador + #ifdef _DEBUG + // --- Variables --- SDL_FRect debug_rect_x_; // Rectangulo de desplazamiento para el modo debug SDL_FRect debug_rect_y_; // Rectangulo de desplazamiento para el modo debug Uint8 debug_color_; // Color del recuadro de debug del jugador SDL_FPoint debug_point_; // Punto para debug + + // --- Funciones --- + void renderDebugInfo(); // Pinta la información de debug del jugador #endif - - // Comprueba las entradas y modifica variables - void checkInput(float delta_time); - - // Comprueba si se halla en alguno de los cuatro bordes - void checkBorders(); - - // Comprueba el estado del jugador - void checkState(float delta_time); - - // Aplica gravedad al jugador - void applyGravity(float delta_time); - - // Recalcula la posición del jugador y su animación - void move(float delta_time); - - // Maneja el movimiento horizontal hacia la izquierda - void moveHorizontalLeft(float delta_time); - - // Maneja el movimiento horizontal hacia la derecha - void moveHorizontalRight(float delta_time); - - // Maneja el movimiento vertical hacia arriba - void moveVerticalUp(float delta_time); - - // Maneja el movimiento vertical hacia abajo - void moveVerticalDown(float delta_time); - - // Establece la animación del jugador - void animate(float delta_time); - - // Comprueba si ha finalizado el salto al alcanzar la altura de inicio - void checkJumpEnd(); - - // Calcula y reproduce el sonido de salto - void playJumpSound(); - - // Calcula y reproduce el sonido de caer - void playFallSound(); - - // Comprueba si el jugador tiene suelo debajo de los pies - auto isOnFloor() -> bool; - - // Comprueba si el jugador esta sobre una superficie automática - auto isOnAutoSurface() -> bool; - - // Comprueba si el jugador está sobre una rampa hacia abajo - auto isOnDownSlope() -> bool; - - // Comprueba que el jugador no toque ningun tile de los que matan - auto checkKillingTiles() -> bool; - - // Actualiza los puntos de colisión - void updateColliderPoints(); - - // Actualiza los puntos de los pies - void updateFeet(); - - // Cambia el estado del jugador - void setState(PlayerState value); - - // Inicializa los sonidos de salto y caida - void initSounds(); - - // Coloca el sprite en la posición del jugador - void placeSprite() { sprite_->setPos(x_, y_); } - - // Aplica los valores de spawn al jugador - void applySpawnValues(const PlayerSpawn& spawn); - - // Inicializa el sprite del jugador - void initSprite(const std::string& surface_path, const std::string& animations_path); - -#ifdef _DEBUG - // Pinta la información de debug del jugador - void renderDebugInfo(); -#endif - -public: - // Constructor - explicit Player(const PlayerData& player); - - // Destructor - ~Player() = default; - - // Pinta el enemigo en pantalla - void render(); - - // Actualiza las variables del objeto - void update(float delta_time); - - // Indica si el jugador esta en uno de los cuatro bordes de la pantalla - [[nodiscard]] auto getOnBorder() const -> bool { return is_on_border_; } - - // Indica en cual de los cuatro bordes se encuentra - [[nodiscard]] auto getBorder() const -> RoomBorder { return border_; } - - // Cambia al jugador de un borde al opuesto. Util para el cambio de pantalla - void switchBorders(); - - // Obtiene el rectangulo que delimita al jugador - auto getRect() -> SDL_FRect { return {x_, y_, WIDTH, HEIGHT}; } - - // Obtiene el rectangulo de colision del jugador - auto getCollider() -> SDL_FRect& { return collider_box_; } - - // Obtiene el estado de reaparición del jugador - auto getSpawnParams() -> PlayerSpawn { return {x_, y_, vx_, vy_, jump_init_pos_, state_, sprite_->getFlip()}; } - - // Establece el color del jugador - void setColor(); - - // Establece la habitación en la que se encuentra el jugador - void setRoom(std::shared_ptr room) { room_ = std::move(room); } - - // Comprueba si el jugador esta vivo - [[nodiscard]] auto isAlive() const -> bool { return is_alive_; } - - // Pone el jugador en modo pausa - void setPaused(bool value) { is_paused_ = value; } }; \ No newline at end of file diff --git a/source/game/gameplay/room.cpp b/source/game/gameplay/room.cpp index 7a9a209..e1e0c02 100644 --- a/source/game/gameplay/room.cpp +++ b/source/game/gameplay/room.cpp @@ -78,8 +78,8 @@ void logUnknownParameter(const std::string& file_name, const std::string& key, b } // Carga un bloque [enemy]...[/enemy] desde un archivo -auto loadEnemyFromFile(std::ifstream& file, const std::string& file_name, bool verbose) -> EnemyData { - EnemyData enemy; +auto loadEnemyFromFile(std::ifstream& file, const std::string& file_name, bool verbose) -> Enemy::Data { + Enemy::Data enemy; enemy.flip = false; enemy.mirror = false; enemy.frame = -1; @@ -98,8 +98,8 @@ auto loadEnemyFromFile(std::ifstream& file, const std::string& file_name, bool v } // Carga un bloque [item]...[/item] desde un archivo -auto loadItemFromFile(std::ifstream& file, const std::string& file_name, bool verbose) -> ItemData { - ItemData item; +auto loadItemFromFile(std::ifstream& file, const std::string& file_name, bool verbose) -> Item::Data { + Item::Data item; item.counter = 0; item.color1 = stringToColor("yellow"); item.color2 = stringToColor("magenta"); @@ -209,7 +209,7 @@ auto setRoom(RoomData* room, const std::string& key, const std::string& value) - } // Asigna variables a una estructura EnemyData -auto setEnemy(EnemyData* enemy, const std::string& key, const std::string& value) -> bool { +auto setEnemy(Enemy::Data* enemy, const std::string& key, const std::string& value) -> bool { // Indicador de éxito en la asignación bool success = true; @@ -260,7 +260,7 @@ auto setEnemy(EnemyData* enemy, const std::string& key, const std::string& value } // Asigna variables a una estructura ItemData -auto setItem(ItemData* item, const std::string& key, const std::string& value) -> bool { +auto setItem(Item::Data* item, const std::string& key, const std::string& value) -> bool { // Indicador de éxito en la asignación bool success = true; @@ -345,7 +345,7 @@ void Room::initializeRoom(const RoomData& room) { if (!ItemTracker::get()->hasBeenPicked(room.name, ITEM_POS)) { // Crear una copia local de los datos del item - ItemData item_copy = item; + Item::Data item_copy = item; item_copy.color1 = stringToColor(item_color1_); item_copy.color2 = stringToColor(item_color2_); diff --git a/source/game/gameplay/room.hpp b/source/game/gameplay/room.hpp index 17216bc..251efdf 100644 --- a/source/game/gameplay/room.hpp +++ b/source/game/gameplay/room.hpp @@ -36,22 +36,22 @@ struct AnimatedTile { }; struct RoomData { - std::string number; // Numero de la habitación - std::string name; // Nombre de la habitación - std::string bg_color; // Color de fondo de la habitación - std::string border_color; // Color del borde de la pantalla - std::string item_color1; // Color 1 para los items de la habitación - std::string item_color2; // Color 2 para los items de la habitación - std::string upper_room; // Identificador de la habitación que se encuentra arriba - std::string lower_room; // Identificador de la habitación que se encuentra abajp - std::string left_room; // Identificador de la habitación que se encuentra a la izquierda - std::string right_room; // Identificador de la habitación que se encuentra a la derecha - std::string tile_set_file; // Imagen con los graficos para la habitación - std::string tile_map_file; // Fichero con el mapa de indices de tile - int conveyor_belt_direction; // Sentido en el que arrastran las superficies automáticas de la habitación - std::vector tile_map; // Indice de los tiles a dibujar en la habitación - std::vector enemies; // Listado con los enemigos de la habitación - std::vector items; // Listado con los items que hay en la habitación + std::string number; // Numero de la habitación + std::string name; // Nombre de la habitación + std::string bg_color; // Color de fondo de la habitación + std::string border_color; // Color del borde de la pantalla + std::string item_color1; // Color 1 para los items de la habitación + std::string item_color2; // Color 2 para los items de la habitación + std::string upper_room; // Identificador de la habitación que se encuentra arriba + std::string lower_room; // Identificador de la habitación que se encuentra abajp + std::string left_room; // Identificador de la habitación que se encuentra a la izquierda + std::string right_room; // Identificador de la habitación que se encuentra a la derecha + std::string tile_set_file; // Imagen con los graficos para la habitación + std::string tile_map_file; // Fichero con el mapa de indices de tile + int conveyor_belt_direction; // Sentido en el que arrastran las superficies automáticas de la habitación + std::vector tile_map; // Indice de los tiles a dibujar en la habitación + std::vector enemies; // Listado con los enemigos de la habitación + std::vector items; // Listado con los items que hay en la habitación }; // Carga las variables desde un fichero de mapa @@ -64,10 +64,10 @@ auto loadRoomTileFile(const std::string& file_path, bool verbose = false) -> std auto setRoom(RoomData* room, const std::string& key, const std::string& value) -> bool; // Asigna variables a una estructura EnemyData -auto setEnemy(EnemyData* enemy, const std::string& key, const std::string& value) -> bool; +auto setEnemy(Enemy::Data* enemy, const std::string& key, const std::string& value) -> bool; // Asigna variables a una estructura ItemData -auto setItem(ItemData* item, const std::string& key, const std::string& value) -> bool; +auto setItem(Item::Data* item, const std::string& key, const std::string& value) -> bool; class Room { private: diff --git a/source/game/scenes/game.cpp b/source/game/scenes/game.cpp index 4a9a435..7e62784 100644 --- a/source/game/scenes/game.cpp +++ b/source/game/scenes/game.cpp @@ -36,7 +36,7 @@ Game::Game(GameMode mode) mode_(mode), #ifdef _DEBUG current_room_("03.room"), - spawn_point_(PlayerSpawn(25 * BLOCK, 13 * BLOCK, 0, 0, 0, PlayerState::STANDING, SDL_FLIP_HORIZONTAL)) + spawn_data_(Player::SpawnData(25 * BLOCK, 13 * BLOCK, 0, 0, 0, Player::State::STANDING, SDL_FLIP_HORIZONTAL)) #else current_room_("03.room"), spawn_point_(PlayerSpawn(25 * BLOCK, 13 * BLOCK, 0, 0, 0, PlayerState::STANDING, SDL_FLIP_HORIZONTAL)) @@ -50,7 +50,7 @@ Game::Game(GameMode mode) ItemTracker::init(); demoInit(); room_ = std::make_shared(current_room_, board_); - initPlayer(spawn_point_, room_); + initPlayer(spawn_data_, room_); initStats(); total_items_ = getTotalItems(); @@ -178,9 +178,9 @@ void Game::render() { #ifdef _DEBUG // Pasa la información de debug void Game::updateDebugInfo() { - //Debug::get()->add("X = " + std::to_string(static_cast(player_->x_)) + ", Y = " + std::to_string(static_cast(player_->y_))); - //Debug::get()->add("VX = " + std::to_string(player_->vx_).substr(0, 4) + ", VY = " + std::to_string(player_->vy_).substr(0, 4)); - //Debug::get()->add("STATE = " + std::to_string(static_cast(player_->state_))); + // Debug::get()->add("X = " + std::to_string(static_cast(player_->x_)) + ", Y = " + std::to_string(static_cast(player_->y_))); + // Debug::get()->add("VX = " + std::to_string(player_->vx_).substr(0, 4) + ", VY = " + std::to_string(player_->vy_).substr(0, 4)); + // Debug::get()->add("STATE = " + std::to_string(static_cast(player_->state_))); } // Pone la información de debug en pantalla @@ -305,7 +305,7 @@ void Game::checkPlayerIsOnBorder() { const std::string ROOM_NAME = room_->getRoom(player_->getBorder()); if (changeRoom(ROOM_NAME)) { player_->switchBorders(); - spawn_point_ = player_->getSpawnParams(); + spawn_data_ = player_->getSpawnParams(); } } } @@ -363,7 +363,7 @@ void Game::killPlayer() { // Crea la nueva habitación y el nuevo jugador room_ = std::make_shared(current_room_, board_); - initPlayer(spawn_point_, room_); + initPlayer(spawn_data_, room_); // Pone los objetos en pausa mientras esta la habitación en negro room_->setPaused(true); @@ -566,10 +566,10 @@ void Game::checkEndGameCheevos() { } // Inicializa al jugador -void Game::initPlayer(const PlayerSpawn& spawn_point, std::shared_ptr room) { +void Game::initPlayer(const Player::SpawnData& spawn_point, std::shared_ptr room) { std::string player_texture = Options::cheats.alternate_skin == Options::Cheat::State::ENABLED ? "player2.gif" : "player.gif"; std::string player_animations = Options::cheats.alternate_skin == Options::Cheat::State::ENABLED ? "player2.ani" : "player.ani"; - const PlayerData PLAYER(spawn_point, player_texture, player_animations, std::move(room)); + const Player::Data PLAYER(spawn_point, player_texture, player_animations, std::move(room)); player_ = std::make_shared(PLAYER); } diff --git a/source/game/scenes/game.hpp b/source/game/scenes/game.hpp index a889ace..603a303 100644 --- a/source/game/scenes/game.hpp +++ b/source/game/scenes/game.hpp @@ -24,10 +24,10 @@ enum class GameMode { class Game { private: // Constantes de tiempo - static constexpr float BLACK_SCREEN_DURATION = 0.30F; // Duración de la pantalla negra en segundos (20 frames a 66.67fps) - static constexpr float GAME_OVER_THRESHOLD = 0.255F; // Tiempo antes del game over en segundos (17 frames a 66.67fps) - static constexpr float DEMO_ROOM_DURATION = 6.0F; // Duración de cada habitación en modo demo en segundos (400 frames) - static constexpr float JAIL_RESTORE_INTERVAL = 1.5F; // Intervalo de restauración de vidas en la Jail en segundos (100 frames) + static constexpr float BLACK_SCREEN_DURATION = 0.30F; // Duración de la pantalla negra en segundos (20 frames a 66.67fps) + static constexpr float GAME_OVER_THRESHOLD = 0.255F; // Tiempo antes del game over en segundos (17 frames a 66.67fps) + static constexpr float DEMO_ROOM_DURATION = 6.0F; // Duración de cada habitación en modo demo en segundos (400 frames) + static constexpr float JAIL_RESTORE_INTERVAL = 1.5F; // Intervalo de restauración de vidas en la Jail en segundos (100 frames) // Estructuras struct DemoData { @@ -58,17 +58,17 @@ class Game { std::shared_ptr room_name_surface_; // Textura para escribir el nombre de la habitación // Variables - GameMode mode_; // Modo del juego - DemoData demo_; // Variables para el modo demo - DeltaTimer delta_timer_; // Timer para calcular delta time - std::string current_room_; // Fichero de la habitación actual - PlayerSpawn spawn_point_; // Lugar de la habitación donde aparece el jugador - bool paused_ = false; // Indica si el juego se encuentra en pausa - bool black_screen_ = false; // Indica si la pantalla está en negro. Se utiliza para la muerte del jugador - float black_screen_time_ = 0.0F; // Tiempo acumulado en pantalla negra en segundos - int total_items_; // Cantidad total de items que hay en el mapeado del juego - SDL_FRect room_name_rect_; // Rectangulo donde pintar la textura con el nombre de la habitación - float jail_restore_time_ = 0.0F; // Tiempo acumulado para restauración de vidas en la Jail + GameMode mode_; // Modo del juego + DemoData demo_; // Variables para el modo demo + DeltaTimer delta_timer_; // Timer para calcular delta time + std::string current_room_; // Fichero de la habitación actual + Player::SpawnData spawn_data_; // Lugar de la habitación donde aparece el jugador + bool paused_ = false; // Indica si el juego se encuentra en pausa + bool black_screen_ = false; // Indica si la pantalla está en negro. Se utiliza para la muerte del jugador + float black_screen_time_ = 0.0F; // Tiempo acumulado en pantalla negra en segundos + int total_items_; // Cantidad total de items que hay en el mapeado del juego + SDL_FRect room_name_rect_; // Rectangulo donde pintar la textura con el nombre de la habitación + float jail_restore_time_ = 0.0F; // Tiempo acumulado para restauración de vidas en la Jail // Actualiza el juego, las variables, comprueba la entrada, etc. void update(); @@ -154,7 +154,7 @@ class Game { void checkEndGameCheevos(); // Inicializa al jugador - void initPlayer(const PlayerSpawn& spawn_point, std::shared_ptr room); + void initPlayer(const Player::SpawnData& spawn_point, std::shared_ptr room); // Crea la textura para poner el nombre de la habitación void createRoomNameTexture();