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

@@ -151,7 +151,7 @@ Director::Director(std::vector<std::string> 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

View File

@@ -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

View File

@@ -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<int>(y_);
last_grounded_position_ = static_cast<int>(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<int>(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<int>(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) {

View File

@@ -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) { 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
};

View File

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

View File

@@ -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;
}
}
}

View File

@@ -100,13 +100,13 @@ class Game {
// --- Variables miembro ---
// Objetos y punteros a recursos
std::shared_ptr<Scoreboard::Data> board_; // Estructura con los datos del marcador
std::shared_ptr<Scoreboard> scoreboard_; // Objeto encargado de gestionar el marcador
std::shared_ptr<RoomTracker> room_tracker_; // Lleva el control de las habitaciones visitadas
std::shared_ptr<Room> room_; // Objeto encargado de gestionar cada habitación del juego
std::shared_ptr<Player> player_; // Objeto con el jugador
std::shared_ptr<Stats> stats_; // Objeto encargado de gestionar las estadísticas
std::shared_ptr<Surface> room_name_surface_; // Textura para escribir el nombre de la habitación
std::shared_ptr<Scoreboard::Data> board_; // Estructura con los datos del marcador
std::shared_ptr<Scoreboard> scoreboard_; // Objeto encargado de gestionar el marcador
std::shared_ptr<RoomTracker> room_tracker_; // Lleva el control de las habitaciones visitadas
std::shared_ptr<Room> room_; // Objeto encargado de gestionar cada habitación del juego
std::shared_ptr<Player> player_; // Objeto con el jugador
std::shared_ptr<Stats> stats_; // Objeto encargado de gestionar las estadísticas
std::shared_ptr<Surface> room_name_surface_; // Textura para escribir el nombre de la habitación
std::shared_ptr<Surface> game_backbuffer_surface_; // Backbuffer para efectos de fade
// Variables de estado del juego