corregida logica de atravesar el fondo de la pantalla a velocitat terminal

This commit is contained in:
2025-11-22 09:29:20 +01:00
parent bd011a0ebb
commit 9ef7f4274d
7 changed files with 53 additions and 45 deletions

View File

@@ -64,7 +64,7 @@ constexpr bool ENABLED = true; // Sonido habilitado por defecto
// --- CHEATS --- // --- CHEATS ---
namespace Cheat { 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 INVINCIBLE = false; // Invencibilidad desactivada por defecto
constexpr bool JAIL_IS_OPEN = false; // Jail abierta desactivada por defecto constexpr bool JAIL_IS_OPEN = false; // Jail abierta desactivada por defecto
constexpr bool ALTERNATE_SKIN = false; // Skin alternativa desactivada por defecto constexpr bool ALTERNATE_SKIN = false; // Skin alternativa desactivada por defecto

View File

@@ -48,7 +48,7 @@ void Player::update(float delta_time) {
updateState(delta_time); updateState(delta_time);
move(delta_time); move(delta_time);
animate(delta_time); animate(delta_time);
handleBorders(); border_ = handleBorders();
} }
} }
@@ -125,21 +125,18 @@ void Player::transitionToState(State state) {
switch (state) { switch (state) {
case State::ON_GROUND: case State::ON_GROUND:
// std::cout << "ON_GROUND\n";
vy_ = 0; vy_ = 0;
handleDeathByFalling(); handleDeathByFalling();
resetSoundControllersOnLanding(); resetSoundControllersOnLanding();
current_slope_ = nullptr; current_slope_ = nullptr;
break; break;
case State::ON_SLOPE: case State::ON_SLOPE:
// std::cout << "ON_SLOPE\n";
vy_ = 0; vy_ = 0;
handleDeathByFalling(); handleDeathByFalling();
resetSoundControllersOnLanding(); resetSoundControllersOnLanding();
updateCurrentSlope(); updateCurrentSlope();
break; break;
case State::JUMPING: case State::JUMPING:
// std::cout << "JUMPING\n";
// Puede saltar desde ON_GROUND o ON_SLOPE // Puede saltar desde ON_GROUND o ON_SLOPE
if (previous_state_ == State::ON_GROUND || previous_state_ == State::ON_SLOPE) { if (previous_state_ == State::ON_GROUND || previous_state_ == State::ON_SLOPE) {
vy_ = -MAX_VY; vy_ = -MAX_VY;
@@ -150,7 +147,6 @@ void Player::transitionToState(State state) {
} }
break; break;
case State::FALLING: case State::FALLING:
// std::cout << "FALLING\n";
fall_start_position_ = static_cast<int>(y_); fall_start_position_ = static_cast<int>(y_);
last_grounded_position_ = static_cast<int>(y_); last_grounded_position_ = static_cast<int>(y_);
vy_ = MAX_VY; 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 // 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) { if (x_ < PlayArea::LEFT) {
border_ = Room::Border::LEFT; return Room::Border::LEFT;
is_on_border_ = true;
} }
else if (x_ + WIDTH > PlayArea::RIGHT) { if (x_ + WIDTH > PlayArea::RIGHT) {
border_ = Room::Border::RIGHT; return Room::Border::RIGHT;
is_on_border_ = true;
} }
else if (y_ < PlayArea::TOP) { if (y_ < PlayArea::TOP) {
border_ = Room::Border::TOP; return Room::Border::TOP;
is_on_border_ = true;
} }
else if (y_ + HEIGHT > PlayArea::BOTTOM) { if (y_ + HEIGHT > PlayArea::BOTTOM) {
border_ = Room::Border::BOTTOM; // Si llega en estado terminal, muere y no cruza
is_on_border_ = true; const bool SHOULD_DIE = static_cast<int>(y_) - last_grounded_position_ > MAX_FALLING_HEIGHT;
if (SHOULD_DIE) { markAsDead(); }
return is_alive_ ? Room::Border::BOTTOM : Room::Border::NONE;
} }
else { return Room::Border::NONE;
is_on_border_ = false;
}
} }
// Cambia al jugador de un borde al opuesto. Util para el cambio de pantalla // Cambia al jugador de un borde al opuesto. Util para el cambio de pantalla
@@ -433,8 +426,8 @@ void Player::switchBorders() {
break; break;
} }
is_on_border_ = false; border_ = Room::Border::NONE;
placeSprite(); syncSpriteAndCollider();
} }
// Aplica gravedad al jugador // Aplica gravedad al jugador
@@ -599,7 +592,7 @@ auto Player::handleKillingTiles() -> bool {
if (std::ranges::any_of(collider_points_, [this](const auto& c) { if (std::ranges::any_of(collider_points_, [this](const auto& c) {
return room_->getTile(c) == Room::Tile::KILL; return room_->getTile(c) == Room::Tile::KILL;
})) { })) {
is_alive_ = false; // Mata al jugador inmediatamente markAsDead(); // Mata al jugador inmediatamente
return true; // Retorna en cuanto se detecta una colisión return true; // Retorna en cuanto se detecta una colisión
} }
@@ -772,13 +765,9 @@ void Player::placeSprite() {
// Gestiona la muerta al ccaer desde muy alto // Gestiona la muerta al ccaer desde muy alto
void Player::handleDeathByFalling() { void Player::handleDeathByFalling() {
if (Options::cheats.invincible == Options::Cheat::State::ENABLED) {
return;
}
const int FALL_DISTANCE = static_cast<int>(y_) - last_grounded_position_; const int FALL_DISTANCE = static_cast<int>(y_) - last_grounded_position_;
if (previous_state_ == State::FALLING && FALL_DISTANCE > MAX_FALLING_HEIGHT) { 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 #ifdef _DEBUG
// Establece la posición del jugador directamente (debug) // Establece la posición del jugador directamente (debug)
void Player::setDebugPosition(float x, float y) { void Player::setDebugPosition(float x, float y) {

View File

@@ -10,6 +10,7 @@
#include "core/rendering/surface_animated_sprite.hpp" // Para SAnimatedSprite #include "core/rendering/surface_animated_sprite.hpp" // Para SAnimatedSprite
#include "game/gameplay/room.hpp" #include "game/gameplay/room.hpp"
#include "game/options.hpp" // Para Cheat, Options, options
#include "utils/defines.hpp" // Para BORDER_TOP, BLOCK #include "utils/defines.hpp" // Para BORDER_TOP, BLOCK
#include "utils/utils.hpp" // Para Color #include "utils/utils.hpp" // Para Color
struct JA_Sound_t; // lines 13-13 struct JA_Sound_t; // lines 13-13
@@ -92,7 +93,7 @@ class Player {
// --- Funciones --- // --- Funciones ---
void render(); // Pinta el enemigo en pantalla void render(); // Pinta el enemigo en pantalla
void update(float delta_time); // Actualiza las variables del objeto 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 [[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 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 getRect() -> SDL_FRect { return {x_, y_, WIDTH, HEIGHT}; } // Obtiene el rectangulo que delimita al jugador
@@ -100,6 +101,7 @@ 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 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 setColor(); // Establece el color del jugador
void setRoom(std::shared_ptr<Room> room) { room_ = std::move(room); } // Establece la habitación en la que se encuentra el jugador void setRoom(std::shared_ptr<Room> room) { room_ = std::move(room); } // Establece la habitación en la que se encuentra el jugador
//[[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 [[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 void setPaused(bool value) { is_paused_ = value; } // Pone el jugador en modo pausa
@@ -141,7 +143,6 @@ class Player {
const LineDiagonal* current_slope_{nullptr}; // Rampa actual sobe la que está el jugador const LineDiagonal* current_slope_{nullptr}; // Rampa actual sobe la que está el jugador
// --- Variables de juego --- // --- 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_alive_ = true; // Indica si el jugador esta vivo o no
bool is_paused_ = false; // Indica si el jugador esta en modo pausa 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 bool auto_movement_ = false; // Indica si esta siendo arrastrado por una superficie automatica
@@ -209,11 +210,12 @@ class Player {
// --- Funciones de finalización --- // --- Funciones de finalización ---
void animate(float delta_time); // Establece la animación del jugador 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 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 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 playJumpSound(float delta_time); // Calcula y reproduce el sonido de salto
void playFallSound(float delta_time); // Calcula y reproduce el sonido de caer void playFallSound(float delta_time); // Calcula y reproduce el sonido de caer
void handleDeathByFalling(); // Gestiona la muerte al caer desde muy alto void handleDeathByFalling(); // Gestiona la muerte al caer desde muy alto
void updateVelocity(); // Calcula la velocidad en x void updateVelocity(); // Calcula la velocidad en x
void markAsDead(); // Marca al jugador como muerto
}; };

View File

@@ -24,7 +24,8 @@ class Room {
TOP = 0, TOP = 0,
RIGHT = 1, RIGHT = 1,
BOTTOM = 2, BOTTOM = 2,
LEFT = 3 LEFT = 3,
NONE = 4
}; };
enum class Tile { enum class Tile {

View File

@@ -575,11 +575,18 @@ void Game::checkPlayerIsOnBorder() {
if (player_->isOnBorder()) { if (player_->isOnBorder()) {
const auto BORDER = player_->getBorder(); const auto BORDER = player_->getBorder();
const auto ROOM_NAME = room_->getRoom(BORDER); const auto ROOM_NAME = room_->getRoom(BORDER);
// Si puede cambiar de habitación, cambia
if (changeRoom(ROOM_NAME)) { if (changeRoom(ROOM_NAME)) {
player_->switchBorders(); player_->switchBorders();
spawn_data_ = player_->getSpawnParams(); 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(); killPlayer();
return;
} }
} }
} }