From 9ef7f4274df600e2e356e920789412817ea66c16 Mon Sep 17 00:00:00 2001 From: Sergio Valor Date: Sat, 22 Nov 2025 09:29:20 +0100 Subject: [PATCH] corregida logica de atravesar el fondo de la pantalla a velocitat terminal --- source/core/system/director.cpp | 2 +- source/game/defaults.hpp | 2 +- source/game/entities/player.cpp | 56 ++++++++++++++++----------------- source/game/entities/player.hpp | 12 ++++--- source/game/gameplay/room.hpp | 3 +- source/game/scenes/game.cpp | 9 +++++- source/game/scenes/game.hpp | 14 ++++----- 7 files changed, 53 insertions(+), 45 deletions(-) diff --git a/source/core/system/director.cpp b/source/core/system/director.cpp index 25f2796..3b68503 100644 --- a/source/core/system/director.cpp +++ b/source/core/system/director.cpp @@ -151,7 +151,7 @@ Director::Director(std::vector const& args) { Debug::init(); #endif - std::cout << "\n"; // Fin de inicialización de sistemas + std::cout << "\n"; // Fin de inicialización de sistemas // Special handling for cheevos.bin - also needs filesystem path #ifdef RELEASE_BUILD diff --git a/source/game/defaults.hpp b/source/game/defaults.hpp index ceb448d..1c4ea2c 100644 --- a/source/game/defaults.hpp +++ b/source/game/defaults.hpp @@ -64,7 +64,7 @@ constexpr bool ENABLED = true; // Sonido habilitado por defecto // --- CHEATS --- namespace Cheat { -constexpr bool INFINITE_LIVES = true; // Vidas infinitas desactivadas por defecto +constexpr bool INFINITE_LIVES = false; // Vidas infinitas desactivadas por defecto constexpr bool INVINCIBLE = false; // Invencibilidad desactivada por defecto constexpr bool JAIL_IS_OPEN = false; // Jail abierta desactivada por defecto constexpr bool ALTERNATE_SKIN = false; // Skin alternativa desactivada por defecto diff --git a/source/game/entities/player.cpp b/source/game/entities/player.cpp index ce2db9e..f09f895 100644 --- a/source/game/entities/player.cpp +++ b/source/game/entities/player.cpp @@ -48,7 +48,7 @@ void Player::update(float delta_time) { updateState(delta_time); move(delta_time); animate(delta_time); - handleBorders(); + border_ = handleBorders(); } } @@ -125,21 +125,18 @@ void Player::transitionToState(State state) { switch (state) { case State::ON_GROUND: - // std::cout << "ON_GROUND\n"; vy_ = 0; handleDeathByFalling(); resetSoundControllersOnLanding(); current_slope_ = nullptr; break; case State::ON_SLOPE: - // std::cout << "ON_SLOPE\n"; vy_ = 0; handleDeathByFalling(); resetSoundControllersOnLanding(); updateCurrentSlope(); break; case State::JUMPING: - // std::cout << "JUMPING\n"; // Puede saltar desde ON_GROUND o ON_SLOPE if (previous_state_ == State::ON_GROUND || previous_state_ == State::ON_SLOPE) { vy_ = -MAX_VY; @@ -150,7 +147,6 @@ void Player::transitionToState(State state) { } break; case State::FALLING: - // std::cout << "FALLING\n"; fall_start_position_ = static_cast(y_); last_grounded_position_ = static_cast(y_); vy_ = MAX_VY; @@ -378,30 +374,27 @@ void Player::moveFalling(float delta_time) { } // Comprueba si está situado en alguno de los cuatro bordes de la habitación -void Player::handleBorders() { +auto Player::handleBorders() -> Room::Border { if (x_ < PlayArea::LEFT) { - border_ = Room::Border::LEFT; - is_on_border_ = true; + return Room::Border::LEFT; } - else if (x_ + WIDTH > PlayArea::RIGHT) { - border_ = Room::Border::RIGHT; - is_on_border_ = true; + if (x_ + WIDTH > PlayArea::RIGHT) { + return Room::Border::RIGHT; } - else if (y_ < PlayArea::TOP) { - border_ = Room::Border::TOP; - is_on_border_ = true; + if (y_ < PlayArea::TOP) { + return Room::Border::TOP; } - else if (y_ + HEIGHT > PlayArea::BOTTOM) { - border_ = Room::Border::BOTTOM; - is_on_border_ = true; + if (y_ + HEIGHT > PlayArea::BOTTOM) { + // Si llega en estado terminal, muere y no cruza + const bool SHOULD_DIE = static_cast(y_) - last_grounded_position_ > MAX_FALLING_HEIGHT; + if (SHOULD_DIE) { markAsDead(); } + return is_alive_ ? Room::Border::BOTTOM : Room::Border::NONE; } - else { - is_on_border_ = false; - } + return Room::Border::NONE; } // Cambia al jugador de un borde al opuesto. Util para el cambio de pantalla @@ -433,8 +426,8 @@ void Player::switchBorders() { break; } - is_on_border_ = false; - placeSprite(); + border_ = Room::Border::NONE; + syncSpriteAndCollider(); } // Aplica gravedad al jugador @@ -599,8 +592,8 @@ auto Player::handleKillingTiles() -> bool { 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 + markAsDead(); // Mata al jugador inmediatamente + return true; // Retorna en cuanto se detecta una colisión } return false; // No se encontró ninguna colisión @@ -772,13 +765,9 @@ void Player::placeSprite() { // Gestiona la muerta al ccaer desde muy alto void Player::handleDeathByFalling() { - if (Options::cheats.invincible == Options::Cheat::State::ENABLED) { - return; - } - 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 + markAsDead(); // Muere si cae más de 32 píxeles } } @@ -908,6 +897,15 @@ auto Player::getProjection(Direction direction, float displacement) -> SDL_FRect } } +// Marca al jugador como muerto +void Player::markAsDead() { + if (Options::cheats.invincible == Options::Cheat::State::ENABLED) { + is_alive_ = true; // No puede morir + } else { + is_alive_ = false; // Muere + } +} + #ifdef _DEBUG // Establece la posición del jugador directamente (debug) void Player::setDebugPosition(float x, float y) { diff --git a/source/game/entities/player.hpp b/source/game/entities/player.hpp index 1002cf8..35dcd7a 100644 --- a/source/game/entities/player.hpp +++ b/source/game/entities/player.hpp @@ -10,6 +10,7 @@ #include "core/rendering/surface_animated_sprite.hpp" // Para SAnimatedSprite #include "game/gameplay/room.hpp" +#include "game/options.hpp" // Para Cheat, Options, options #include "utils/defines.hpp" // Para BORDER_TOP, BLOCK #include "utils/utils.hpp" // Para Color struct JA_Sound_t; // lines 13-13 @@ -92,7 +93,7 @@ class Player { // --- 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 isOnBorder() const -> bool { return border_ != Room::Border::NONE; } // 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 @@ -100,8 +101,9 @@ class Player { auto getSpawnParams() -> SpawnData { return {.x = x_, .y = y_, .vx = vx_, .vy = vy_, .last_grounded_position = last_grounded_position_, .state = state_, .flip = 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 + //[[nodiscard]] auto isAlive() const -> bool { return is_alive_ || (Options::cheats.invincible == Options::Cheat::State::ENABLED); } // Comprueba si el jugador esta vivo + [[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 #ifdef _DEBUG // --- Funciones de debug --- @@ -141,7 +143,6 @@ class Player { const LineDiagonal* current_slope_{nullptr}; // Rampa actual sobe la que está el 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 @@ -209,11 +210,12 @@ class Player { // --- 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 + auto handleBorders() -> Room::Border; // 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(float delta_time); // Calcula y reproduce el sonido de salto void playFallSound(float delta_time); // Calcula y reproduce el sonido de caer void handleDeathByFalling(); // Gestiona la muerte al caer desde muy alto void updateVelocity(); // Calcula la velocidad en x + void markAsDead(); // Marca al jugador como muerto }; \ No newline at end of file diff --git a/source/game/gameplay/room.hpp b/source/game/gameplay/room.hpp index 18055e8..a108bda 100644 --- a/source/game/gameplay/room.hpp +++ b/source/game/gameplay/room.hpp @@ -24,7 +24,8 @@ class Room { TOP = 0, RIGHT = 1, BOTTOM = 2, - LEFT = 3 + LEFT = 3, + NONE = 4 }; enum class Tile { diff --git a/source/game/scenes/game.cpp b/source/game/scenes/game.cpp index c5b83f5..b8369a6 100644 --- a/source/game/scenes/game.cpp +++ b/source/game/scenes/game.cpp @@ -575,11 +575,18 @@ void Game::checkPlayerIsOnBorder() { if (player_->isOnBorder()) { const auto BORDER = player_->getBorder(); const auto ROOM_NAME = room_->getRoom(BORDER); + + // Si puede cambiar de habitación, cambia if (changeRoom(ROOM_NAME)) { player_->switchBorders(); spawn_data_ = player_->getSpawnParams(); - } else if (BORDER == Room::Border::BOTTOM) { + return; + } + + // Si ha llegado al fondo y no hay habitación, muere + if (BORDER == Room::Border::BOTTOM) { killPlayer(); + return; } } } diff --git a/source/game/scenes/game.hpp b/source/game/scenes/game.hpp index f30e04a..b1f9658 100644 --- a/source/game/scenes/game.hpp +++ b/source/game/scenes/game.hpp @@ -100,13 +100,13 @@ class Game { // --- Variables miembro --- // Objetos y punteros a recursos - std::shared_ptr board_; // Estructura con los datos del marcador - std::shared_ptr scoreboard_; // Objeto encargado de gestionar el marcador - std::shared_ptr room_tracker_; // Lleva el control de las habitaciones visitadas - std::shared_ptr room_; // Objeto encargado de gestionar cada habitación del juego - std::shared_ptr player_; // Objeto con el jugador - std::shared_ptr stats_; // Objeto encargado de gestionar las estadísticas - std::shared_ptr room_name_surface_; // Textura para escribir el nombre de la habitación + std::shared_ptr board_; // Estructura con los datos del marcador + std::shared_ptr scoreboard_; // Objeto encargado de gestionar el marcador + std::shared_ptr room_tracker_; // Lleva el control de las habitaciones visitadas + std::shared_ptr room_; // Objeto encargado de gestionar cada habitación del juego + std::shared_ptr player_; // Objeto con el jugador + std::shared_ptr stats_; // Objeto encargado de gestionar las estadísticas + std::shared_ptr room_name_surface_; // Textura para escribir el nombre de la habitación std::shared_ptr game_backbuffer_surface_; // Backbuffer para efectos de fade // Variables de estado del juego