treballant en Player: abans d'entrar a moveOnSlope()
This commit is contained in:
@@ -96,33 +96,44 @@ 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();
|
||||||
jump_sound_ctrl_.reset();
|
jump_sound_ctrl_.reset();
|
||||||
fall_sound_ctrl_.reset();
|
fall_sound_ctrl_.reset();
|
||||||
|
current_slope_ = nullptr;
|
||||||
break;
|
break;
|
||||||
case State::ON_SLOPE:
|
case State::ON_SLOPE: {
|
||||||
|
std::cout << "ON_SLOPE\n";
|
||||||
vy_ = 0;
|
vy_ = 0;
|
||||||
handleDeathByFalling();
|
handleDeathByFalling();
|
||||||
jump_sound_ctrl_.reset();
|
jump_sound_ctrl_.reset();
|
||||||
fall_sound_ctrl_.reset();
|
fall_sound_ctrl_.reset();
|
||||||
|
const LineDiagonal* SLOPE_LEFT = room_->getSlopeAtPoint(under_left_foot_);
|
||||||
|
const LineDiagonal* SLOPE_RIGHT = room_->getSlopeAtPoint(under_right_foot_);
|
||||||
|
current_slope_ = SLOPE_LEFT ? SLOPE_LEFT : SLOPE_RIGHT;
|
||||||
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;
|
||||||
last_grounded_position_ = y_;
|
last_grounded_position_ = y_;
|
||||||
updateVelocity();
|
updateVelocity();
|
||||||
jump_sound_ctrl_.start();
|
jump_sound_ctrl_.start();
|
||||||
|
current_slope_ = nullptr;
|
||||||
}
|
}
|
||||||
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;
|
||||||
vx_ = 0.0F;
|
vx_ = 0.0F;
|
||||||
jump_sound_ctrl_.reset();
|
jump_sound_ctrl_.reset();
|
||||||
fall_sound_ctrl_.start(y_);
|
fall_sound_ctrl_.start(y_);
|
||||||
|
current_slope_ = nullptr;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -183,6 +194,7 @@ void Player::moveOnGround(float delta_time) {
|
|||||||
|
|
||||||
if (vx_ == 0.0F) { return; }
|
if (vx_ == 0.0F) { return; }
|
||||||
|
|
||||||
|
// Movimiento horizontal y colision con muros
|
||||||
const float DISPLACEMENT = vx_ * delta_time;
|
const float DISPLACEMENT = vx_ * delta_time;
|
||||||
if (vx_ < 0.0F) {
|
if (vx_ < 0.0F) {
|
||||||
const SDL_FRect PROJECTION = getProjection(Direction::LEFT, DISPLACEMENT);
|
const SDL_FRect PROJECTION = getProjection(Direction::LEFT, DISPLACEMENT);
|
||||||
@@ -201,6 +213,28 @@ void Player::moveOnGround(float delta_time) {
|
|||||||
x_ = POS - WIDTH;
|
x_ = POS - WIDTH;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Comprueba colision con rampas, corrige y cambia estado
|
||||||
|
const int SIDE_X = vx_ < 0.0F ? static_cast<int>(x_) : static_cast<int>(x_) + WIDTH - 1;
|
||||||
|
const LineVertical SIDE = {
|
||||||
|
.x = SIDE_X,
|
||||||
|
.y1 = static_cast<int>(y_) + HEIGHT - 2,
|
||||||
|
.y2 = static_cast<int>(y_) + HEIGHT - 1};
|
||||||
|
|
||||||
|
// Comprueba la rampa correspondiente según la dirección
|
||||||
|
const int SLOPE_Y = vx_ < 0.0F ? room_->checkLeftSlopes(SIDE) : room_->checkRightSlopes(SIDE);
|
||||||
|
if (SLOPE_Y != Collision::NONE) {
|
||||||
|
// Hay rampa: sube al jugador para pegarlo a la rampa
|
||||||
|
// Esta es la nueva posición "ideal" a la que nos queremos teletransportar
|
||||||
|
const float NEW_Y = SLOPE_Y - HEIGHT;
|
||||||
|
|
||||||
|
// Solo aplicamos el "snap" si es para SUBIR (new_y < y_)
|
||||||
|
if (NEW_Y < y_) {
|
||||||
|
y_ = std::max(NEW_Y, y_ - 1.0F);
|
||||||
|
}
|
||||||
|
|
||||||
|
transitionToState(State::ON_SLOPE);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Movimiento físico del estado ON_SLOPE
|
// Movimiento físico del estado ON_SLOPE
|
||||||
@@ -210,65 +244,13 @@ void Player::moveOnSlope(float delta_time) {
|
|||||||
|
|
||||||
if (vx_ == 0.0F) { return; }
|
if (vx_ == 0.0F) { return; }
|
||||||
|
|
||||||
// Movimiento horizontal
|
// Implementar aqui el desplazamiento en x_ e y_ en funcion de la velocidad y la ecuacion de la recta
|
||||||
const float DISPLACEMENT = vx_ * delta_time;
|
// Son LineDiagonal, de 45º. La linea esta en current_slope_ (comprobar que no sea nullptr)
|
||||||
if (vx_ < 0.0F) {
|
|
||||||
const SDL_FRect PROJECTION = getProjection(Direction::LEFT, DISPLACEMENT);
|
|
||||||
const int POS = room_->checkRightSurfaces(PROJECTION);
|
|
||||||
if (POS == Collision::NONE) {
|
|
||||||
x_ += DISPLACEMENT;
|
|
||||||
} else {
|
|
||||||
x_ = POS + 1;
|
|
||||||
}
|
|
||||||
} else if (vx_ > 0.0F) {
|
|
||||||
const SDL_FRect PROJECTION = getProjection(Direction::RIGHT, DISPLACEMENT);
|
|
||||||
const int POS = room_->checkLeftSurfaces(PROJECTION);
|
|
||||||
if (POS == Collision::NONE) {
|
|
||||||
x_ += DISPLACEMENT;
|
|
||||||
} else {
|
|
||||||
x_ = POS - WIDTH;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Movimiento vertical
|
if (isOnTopSurface()) {
|
||||||
// Regla: Si está bajando la rampa, se pega a la slope
|
transitionToState(State::ON_GROUND);
|
||||||
if (isOnDownSlope()) {
|
|
||||||
y_ += 1;
|
|
||||||
return;
|
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 = vx_ < 0.0F ? static_cast<int>(x_) : static_cast<int>(x_) + WIDTH - 1;
|
|
||||||
const LineVertical SIDE = {
|
|
||||||
.x = SIDE_X,
|
|
||||||
.y1 = static_cast<int>(y_) + HEIGHT - 2,
|
|
||||||
.y2 = static_cast<int>(y_) + HEIGHT - 1};
|
|
||||||
|
|
||||||
// Comprueba la rampa correspondiente según la dirección
|
|
||||||
const int SLOPE_Y = vx_ < 0.0F ? room_->checkLeftSlopes(SIDE) : room_->checkRightSlopes(SIDE);
|
|
||||||
|
|
||||||
if (SLOPE_Y != Collision::NONE) {
|
|
||||||
// Hay rampa: sube al jugador para pegarlo a la rampa
|
|
||||||
|
|
||||||
// --- INICIO DE LA CORRECCIÓN ---
|
|
||||||
|
|
||||||
// Esta es la nueva posición "ideal" a la que nos queremos teletransportar
|
|
||||||
const float new_y = SLOPE_Y - HEIGHT;
|
|
||||||
|
|
||||||
// Solo aplicamos el "snap" si es para SUBIR (new_y < y_)
|
|
||||||
if (new_y < y_) {
|
|
||||||
// "y_ - 1.0F" es la posición máxima que podemos subir en 1 frame.
|
|
||||||
// std::max coge la posición más alta (más baja en pantalla):
|
|
||||||
// - O la posición ideal (new_y)
|
|
||||||
// - O la posición actual - 1 píxel
|
|
||||||
// Esto "suaviza" el salto de 2 píxeles (p.ej. 84 -> 82) en dos
|
|
||||||
// fotogramas (84 -> 83, y luego 83 -> 82)
|
|
||||||
y_ = std::max(new_y, y_ - 1.0F);
|
|
||||||
}
|
|
||||||
|
|
||||||
// --- FIN DE LA CORRECCIÓN ---
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Movimiento físico del estado JUMPING
|
// Movimiento físico del estado JUMPING
|
||||||
@@ -404,21 +386,6 @@ void Player::handleBorders() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Comprueba el estado del jugador
|
|
||||||
void Player::handleState(float delta_time) {
|
|
||||||
// Reproduce sonidos según el estado
|
|
||||||
if (state_ == State::FALLING) {
|
|
||||||
playFallSound(delta_time);
|
|
||||||
} else if (state_ == State::ON_GROUND || state_ == State::ON_SLOPE) {
|
|
||||||
// Si no tiene suelo debajo y no está en rampa descendente -> FALLING
|
|
||||||
if (!isOnFloor() && !isOnConveyorBelt() && !isOnDownSlope()) {
|
|
||||||
transitionToState(State::FALLING); // setState() establece vx_=0, vy_=MAX_VY
|
|
||||||
}
|
|
||||||
} else if (state_ == State::JUMPING) {
|
|
||||||
playJumpSound(delta_time);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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
|
||||||
void Player::switchBorders() {
|
void Player::switchBorders() {
|
||||||
switch (border_) {
|
switch (border_) {
|
||||||
@@ -541,25 +508,6 @@ auto Player::isOnConveyorBelt() -> bool {
|
|||||||
return on_conveyor_belt;
|
return on_conveyor_belt;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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 left_foot = under_left_foot_;
|
|
||||||
SDL_FPoint right_foot = under_right_foot_;
|
|
||||||
left_foot.y += 1.0F;
|
|
||||||
right_foot.y += 1.0F;
|
|
||||||
|
|
||||||
// Comprueba las rampas
|
|
||||||
on_slope |= room_->checkLeftSlopes(left_foot);
|
|
||||||
on_slope |= room_->checkRightSlopes(right_foot);
|
|
||||||
|
|
||||||
return on_slope;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Comprueba si el jugador está sobre una rampa
|
// Comprueba si el jugador está sobre una rampa
|
||||||
auto Player::isOnSlope() -> bool {
|
auto Player::isOnSlope() -> bool {
|
||||||
bool on_slope = false;
|
bool on_slope = false;
|
||||||
|
|||||||
@@ -132,6 +132,7 @@ class Player {
|
|||||||
std::array<SDL_FPoint, 8> collider_points_{}; // Puntos de colisión con el mapa
|
std::array<SDL_FPoint, 8> collider_points_{}; // Puntos de colisión con el mapa
|
||||||
SDL_FPoint under_left_foot_ = {0.0F, 0.0F}; // El punto bajo la esquina inferior izquierda del jugador
|
SDL_FPoint under_left_foot_ = {0.0F, 0.0F}; // El punto bajo la esquina inferior izquierda del jugador
|
||||||
SDL_FPoint under_right_foot_ = {0.0F, 0.0F}; // El punto bajo la esquina inferior derecha del jugador
|
SDL_FPoint under_right_foot_ = {0.0F, 0.0F}; // El punto bajo la esquina inferior derecha del 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_on_border_ = false; // Indica si el jugador esta en uno de los cuatro bordes de la pantalla
|
||||||
@@ -174,7 +175,6 @@ class Player {
|
|||||||
void handleInput(); // Comprueba las entradas y modifica variables
|
void handleInput(); // Comprueba las entradas y modifica variables
|
||||||
|
|
||||||
// --- Funciones de gestión de estado ---
|
// --- Funciones de gestión de estado ---
|
||||||
void handleState(float delta_time); // Comprueba el estado del jugador y actualiza variables
|
|
||||||
void transitionToState(State state); // Cambia el estado del jugador
|
void transitionToState(State state); // Cambia el estado del jugador
|
||||||
|
|
||||||
// --- Funciones de física ---
|
// --- Funciones de física ---
|
||||||
@@ -188,7 +188,6 @@ class Player {
|
|||||||
auto isOnFloor() -> bool; // Comprueba si el jugador tiene suelo debajo de los pies
|
auto isOnFloor() -> bool; // Comprueba si el jugador tiene suelo debajo de los pies
|
||||||
auto isOnTopSurface() -> bool; // Comprueba si el jugador está sobre una superficie
|
auto isOnTopSurface() -> bool; // Comprueba si el jugador está sobre una superficie
|
||||||
auto isOnConveyorBelt() -> bool; // Comprueba si el jugador esta sobre una cinta transportadora
|
auto isOnConveyorBelt() -> bool; // Comprueba si el jugador esta sobre una cinta transportadora
|
||||||
auto isOnDownSlope() -> bool; // Comprueba si el jugador está sobre una rampa hacia abajo
|
|
||||||
auto isOnSlope() -> bool; // Comprueba si el jugador está sobre una rampa
|
auto isOnSlope() -> bool; // Comprueba si el jugador está sobre una rampa
|
||||||
|
|
||||||
// --- Funciones de actualización de geometría ---
|
// --- Funciones de actualización de geometría ---
|
||||||
|
|||||||
@@ -202,6 +202,26 @@ auto CollisionMap::checkRightSlopes(const SDL_FPoint& p) -> bool {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Obtiene puntero a slope en un punto (prioriza left_slopes_ sobre right_slopes_)
|
||||||
|
auto CollisionMap::getSlopeAtPoint(const SDL_FPoint& p) const -> const LineDiagonal* {
|
||||||
|
// Primero busca en rampas izquierdas
|
||||||
|
for (const auto& slope : left_slopes_) {
|
||||||
|
if (checkCollision(p, slope)) {
|
||||||
|
return &slope;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Luego busca en rampas derechas
|
||||||
|
for (const auto& slope : right_slopes_) {
|
||||||
|
if (checkCollision(p, slope)) {
|
||||||
|
return &slope;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// No hay colisión con ninguna slope
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
// === Helpers para recopilar tiles ===
|
// === Helpers para recopilar tiles ===
|
||||||
|
|
||||||
// Helper: recopila tiles inferiores (muros sin muro debajo)
|
// Helper: recopila tiles inferiores (muros sin muro debajo)
|
||||||
|
|||||||
@@ -63,6 +63,7 @@ class CollisionMap {
|
|||||||
auto checkLeftSlopes(const SDL_FPoint& p) -> bool; // Colisión punto con rampas izquierdas
|
auto checkLeftSlopes(const SDL_FPoint& p) -> bool; // Colisión punto con rampas izquierdas
|
||||||
auto checkRightSlopes(const LineVertical& line) -> int; // Colisión línea con rampas derechas (retorna Y)
|
auto checkRightSlopes(const LineVertical& line) -> int; // Colisión línea con rampas derechas (retorna Y)
|
||||||
auto checkRightSlopes(const SDL_FPoint& p) -> bool; // Colisión punto con rampas derechas
|
auto checkRightSlopes(const SDL_FPoint& p) -> bool; // Colisión punto con rampas derechas
|
||||||
|
auto getSlopeAtPoint(const SDL_FPoint& p) const -> const LineDiagonal*; // Obtiene puntero a slope en un punto
|
||||||
|
|
||||||
// --- Métodos estáticos ---
|
// --- Métodos estáticos ---
|
||||||
static auto getTileSize() -> int { return TILE_SIZE; } // Tamaño del tile en pixels
|
static auto getTileSize() -> int { return TILE_SIZE; } // Tamaño del tile en pixels
|
||||||
|
|||||||
@@ -246,6 +246,11 @@ auto Room::checkRightSlopes(const SDL_FPoint& p) -> bool {
|
|||||||
return collision_map_->checkRightSlopes(p);
|
return collision_map_->checkRightSlopes(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Obtiene puntero a slope en un punto
|
||||||
|
auto Room::getSlopeAtPoint(const SDL_FPoint& p) const -> const LineDiagonal* {
|
||||||
|
return collision_map_->getSlopeAtPoint(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Carga las variables desde un fichero de mapa (delegado a RoomLoader)
|
// Carga las variables desde un fichero de mapa (delegado a RoomLoader)
|
||||||
auto Room::loadRoomFile(const std::string& file_path, bool verbose) -> Data {
|
auto Room::loadRoomFile(const std::string& file_path, bool verbose) -> Data {
|
||||||
|
|||||||
@@ -86,6 +86,7 @@ class Room {
|
|||||||
auto checkLeftSlopes(const SDL_FPoint& p) -> bool; // Comprueba las colisiones
|
auto checkLeftSlopes(const SDL_FPoint& p) -> bool; // Comprueba las colisiones
|
||||||
auto checkRightSlopes(const LineVertical& line) -> int; // Comprueba las colisiones
|
auto checkRightSlopes(const LineVertical& line) -> int; // Comprueba las colisiones
|
||||||
auto checkRightSlopes(const SDL_FPoint& p) -> bool; // Comprueba las colisiones
|
auto checkRightSlopes(const SDL_FPoint& p) -> bool; // Comprueba las colisiones
|
||||||
|
auto getSlopeAtPoint(const SDL_FPoint& p) const -> const LineDiagonal*; // Obtiene puntero a slope en un punto
|
||||||
void setPaused(bool value); // Pone el mapa en modo pausa
|
void setPaused(bool value); // Pone el mapa en modo pausa
|
||||||
[[nodiscard]] auto getConveyorBeltDirection() const -> int { return conveyor_belt_direction_; } // Obten la direccion de las superficies automaticas
|
[[nodiscard]] auto getConveyorBeltDirection() const -> int { return conveyor_belt_direction_; } // Obten la direccion de las superficies automaticas
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user