classe Player refactoritzada per chanclot
This commit is contained in:
@@ -113,16 +113,14 @@ void Player::transitionToState(State state) {
|
||||
//std::cout << "ON_GROUND\n";
|
||||
vy_ = 0;
|
||||
handleDeathByFalling();
|
||||
jump_sound_ctrl_.reset();
|
||||
fall_sound_ctrl_.reset();
|
||||
resetSoundControllersOnLanding();
|
||||
current_slope_ = nullptr;
|
||||
break;
|
||||
case State::ON_SLOPE:
|
||||
//std::cout << "ON_SLOPE\n";
|
||||
vy_ = 0;
|
||||
handleDeathByFalling();
|
||||
jump_sound_ctrl_.reset();
|
||||
fall_sound_ctrl_.reset();
|
||||
resetSoundControllersOnLanding();
|
||||
updateCurrentSlope();
|
||||
break;
|
||||
case State::JUMPING:
|
||||
@@ -208,24 +206,7 @@ void Player::moveOnGround(float delta_time) {
|
||||
if (vx_ == 0.0F) { return; }
|
||||
|
||||
// Movimiento horizontal y colision con muros
|
||||
const float DISPLACEMENT = vx_ * delta_time;
|
||||
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;
|
||||
}
|
||||
}
|
||||
applyHorizontalMovement(delta_time);
|
||||
|
||||
// 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;
|
||||
@@ -263,24 +244,7 @@ void Player::moveOnSlope(float delta_time) {
|
||||
const bool IS_LEFT_SLOPE = isLeftSlope();
|
||||
|
||||
// Movimiento horizontal con colisión lateral
|
||||
const float DISPLACEMENT = vx_ * delta_time;
|
||||
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;
|
||||
}
|
||||
}
|
||||
applyHorizontalMovement(delta_time);
|
||||
|
||||
// Seleccionar el pie apropiado según el tipo de rampa
|
||||
// Left slopes (forma \) colisionan con el pie izquierdo
|
||||
@@ -340,23 +304,7 @@ void Player::moveOnSlope(float delta_time) {
|
||||
// Movimiento físico del estado JUMPING
|
||||
void Player::moveJumping(float delta_time) {
|
||||
// Movimiento horizontal
|
||||
if (vx_ != 0.0F) {
|
||||
const float DISPLACEMENT_X = vx_ * delta_time;
|
||||
const Direction DIRECTION = vx_ > 0.0F ? Direction::RIGHT : Direction::LEFT;
|
||||
const SDL_FRect PROJECTION = getProjection(DIRECTION, DISPLACEMENT_X);
|
||||
|
||||
// Comprueba la colisión con las superficies
|
||||
const int POS = DIRECTION == Direction::LEFT ? room_->checkRightSurfaces(PROJECTION) : room_->checkLeftSurfaces(PROJECTION);
|
||||
|
||||
// Calcula la nueva posición
|
||||
if (POS == Collision::NONE) {
|
||||
// No hay colisión: mueve al jugador
|
||||
x_ += DISPLACEMENT_X;
|
||||
} else {
|
||||
// Hay colisión: reposiciona al jugador en el punto de colisión
|
||||
x_ = DIRECTION == Direction::LEFT ? POS + 1 : POS - WIDTH;
|
||||
}
|
||||
}
|
||||
applyHorizontalMovement(delta_time);
|
||||
|
||||
// Movimiento vertical
|
||||
applyGravity(delta_time);
|
||||
@@ -384,28 +332,16 @@ void Player::moveJumping(float delta_time) {
|
||||
// Crea el rectangulo de proyección en el eje Y para ver si colisiona
|
||||
const SDL_FRect PROJECTION = getProjection(Direction::DOWN, DISPLACEMENT_Y);
|
||||
|
||||
// Comprueba la colisión con las superficies y las cintas transportadoras
|
||||
// JUMPING colisiona con rampas solo si vx_ == 0
|
||||
if (vx_ == 0.0F) {
|
||||
handleLandingFromAir(DISPLACEMENT_Y, PROJECTION);
|
||||
} else {
|
||||
// Comprueba la colisión con las superficies y las cintas transportadoras (sin rampas)
|
||||
const float POS = std::max(room_->checkTopSurfaces(PROJECTION), room_->checkAutoSurfaces(PROJECTION));
|
||||
if (POS != Collision::NONE) {
|
||||
// Si hay colisión lo mueve hasta donde no colisiona y pasa a estar sobre la superficie
|
||||
y_ = POS - HEIGHT;
|
||||
transitionToState(State::ON_GROUND); // Aterrizó en superficie plana o conveyor belt
|
||||
}
|
||||
// Comprueba la colisión con las rampas
|
||||
else {
|
||||
// JUMPING colisiona con rampas solo si vx_ == 0
|
||||
if (vx_ == 0.0F) {
|
||||
auto rect = toSDLRect(PROJECTION);
|
||||
const LineVertical LEFT_SIDE = {.x = rect.x, .y1 = rect.y, .y2 = rect.y + rect.h};
|
||||
const LineVertical RIGHT_SIDE = {.x = rect.x + rect.w - 1, .y1 = rect.y, .y2 = rect.y + rect.h};
|
||||
const float POINT = std::max(room_->checkRightSlopes(RIGHT_SIDE), room_->checkLeftSlopes(LEFT_SIDE));
|
||||
if (POINT != Collision::NONE) {
|
||||
y_ = POINT - HEIGHT;
|
||||
transitionToState(State::ON_SLOPE); // Aterrizó en rampa
|
||||
} else {
|
||||
// No hay colisón con una rampa
|
||||
y_ += DISPLACEMENT_Y;
|
||||
}
|
||||
transitionToState(State::ON_GROUND);
|
||||
} else {
|
||||
// Esta saltando con movimiento horizontal y no hay colisión con los muros
|
||||
// Calcula la nueva posición (atraviesa rampas)
|
||||
@@ -421,26 +357,8 @@ void Player::moveFalling(float delta_time) {
|
||||
const float DISPLACEMENT = vy_ * delta_time;
|
||||
const SDL_FRect PROJECTION = getProjection(Direction::DOWN, DISPLACEMENT);
|
||||
|
||||
// Comprueba la colisión con las superficies y las cintas transportadoras
|
||||
const float POS = std::max(room_->checkTopSurfaces(PROJECTION), room_->checkAutoSurfaces(PROJECTION));
|
||||
if (POS != Collision::NONE) {
|
||||
// Si hay colisión lo mueve hasta donde no colisiona y pasa a estar sobre la superficie
|
||||
y_ = POS - HEIGHT;
|
||||
transitionToState(State::ON_GROUND); // Aterrizó en superficie plana o conveyor belt
|
||||
}
|
||||
// Comprueba la colisión con las rampas
|
||||
else {
|
||||
auto rect = toSDLRect(PROJECTION);
|
||||
const LineVertical LEFT_SIDE = {.x = rect.x, .y1 = rect.y, .y2 = rect.y + rect.h};
|
||||
const LineVertical RIGHT_SIDE = {.x = rect.x + rect.w - 1, .y1 = rect.y, .y2 = rect.y + rect.h};
|
||||
const float POINT = std::max(room_->checkRightSlopes(RIGHT_SIDE), room_->checkLeftSlopes(LEFT_SIDE));
|
||||
if (POINT != Collision::NONE) {
|
||||
y_ = POINT - HEIGHT;
|
||||
transitionToState(State::ON_SLOPE); // Aterrizó en rampa
|
||||
} else {
|
||||
y_ += DISPLACEMENT;
|
||||
}
|
||||
}
|
||||
// Comprueba aterrizaje en superficies y rampas
|
||||
handleLandingFromAir(DISPLACEMENT, PROJECTION);
|
||||
}
|
||||
|
||||
// Comprueba si está situado en alguno de los cuatro bordes de la habitación
|
||||
@@ -869,6 +787,63 @@ void Player::updateVelocity() {
|
||||
}
|
||||
}
|
||||
|
||||
// Aplica movimiento horizontal con colisión de muros
|
||||
void Player::applyHorizontalMovement(float delta_time) {
|
||||
if (vx_ == 0.0F) { return; }
|
||||
|
||||
const float DISPLACEMENT = vx_ * delta_time;
|
||||
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 {
|
||||
const SDL_FRect PROJECTION = getProjection(Direction::RIGHT, DISPLACEMENT);
|
||||
const int POS = room_->checkLeftSurfaces(PROJECTION);
|
||||
if (POS == Collision::NONE) {
|
||||
x_ += DISPLACEMENT;
|
||||
} else {
|
||||
x_ = POS - WIDTH;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Detecta aterrizaje en superficies y rampas
|
||||
auto Player::handleLandingFromAir(float displacement, const SDL_FRect& projection) -> bool {
|
||||
// Comprueba la colisión con las superficies y las cintas transportadoras
|
||||
const float POS = std::max(room_->checkTopSurfaces(projection), room_->checkAutoSurfaces(projection));
|
||||
if (POS != Collision::NONE) {
|
||||
// Si hay colisión lo mueve hasta donde no colisiona y pasa a estar sobre la superficie
|
||||
y_ = POS - HEIGHT;
|
||||
transitionToState(State::ON_GROUND);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Comprueba la colisión con las rampas
|
||||
auto rect = toSDLRect(projection);
|
||||
const LineVertical LEFT_SIDE = {.x = rect.x, .y1 = rect.y, .y2 = rect.y + rect.h};
|
||||
const LineVertical RIGHT_SIDE = {.x = rect.x + rect.w - 1, .y1 = rect.y, .y2 = rect.y + rect.h};
|
||||
const float POINT = std::max(room_->checkRightSlopes(RIGHT_SIDE), room_->checkLeftSlopes(LEFT_SIDE));
|
||||
if (POINT != Collision::NONE) {
|
||||
y_ = POINT - HEIGHT;
|
||||
transitionToState(State::ON_SLOPE);
|
||||
return true;
|
||||
}
|
||||
|
||||
// No hay colisión
|
||||
y_ += displacement;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Resetea los controladores de sonido al aterrizar
|
||||
void Player::resetSoundControllersOnLanding() {
|
||||
jump_sound_ctrl_.reset();
|
||||
fall_sound_ctrl_.reset();
|
||||
}
|
||||
|
||||
// Devuelve el rectangulo de proyeccion
|
||||
auto Player::getProjection(Direction direction, float displacement) -> SDL_FRect {
|
||||
switch (direction) {
|
||||
|
||||
@@ -183,6 +183,9 @@ class Player {
|
||||
// --- Funciones de movimiento y colisión ---
|
||||
void move(float delta_time); // Orquesta el movimiento del jugador
|
||||
auto getProjection(Direction direction, float displacement) -> SDL_FRect; // Devuelve el rectangulo de proyeccion
|
||||
void applyHorizontalMovement(float delta_time); // Aplica movimiento horizontal con colisión de muros
|
||||
auto handleLandingFromAir(float displacement, const SDL_FRect& projection) -> bool; // Detecta aterrizaje en superficies y rampas
|
||||
void resetSoundControllersOnLanding(); // Resetea los controladores de sonido al aterrizar
|
||||
|
||||
// --- Funciones de detección de superficies ---
|
||||
auto isOnFloor() -> bool; // Comprueba si el jugador tiene suelo debajo de los pies
|
||||
|
||||
Reference in New Issue
Block a user