classe Player refactoritzada per chanclot
This commit is contained in:
@@ -113,16 +113,14 @@ void Player::transitionToState(State state) {
|
|||||||
//std::cout << "ON_GROUND\n";
|
//std::cout << "ON_GROUND\n";
|
||||||
vy_ = 0;
|
vy_ = 0;
|
||||||
handleDeathByFalling();
|
handleDeathByFalling();
|
||||||
jump_sound_ctrl_.reset();
|
resetSoundControllersOnLanding();
|
||||||
fall_sound_ctrl_.reset();
|
|
||||||
current_slope_ = nullptr;
|
current_slope_ = nullptr;
|
||||||
break;
|
break;
|
||||||
case State::ON_SLOPE:
|
case State::ON_SLOPE:
|
||||||
//std::cout << "ON_SLOPE\n";
|
//std::cout << "ON_SLOPE\n";
|
||||||
vy_ = 0;
|
vy_ = 0;
|
||||||
handleDeathByFalling();
|
handleDeathByFalling();
|
||||||
jump_sound_ctrl_.reset();
|
resetSoundControllersOnLanding();
|
||||||
fall_sound_ctrl_.reset();
|
|
||||||
updateCurrentSlope();
|
updateCurrentSlope();
|
||||||
break;
|
break;
|
||||||
case State::JUMPING:
|
case State::JUMPING:
|
||||||
@@ -208,24 +206,7 @@ void Player::moveOnGround(float delta_time) {
|
|||||||
if (vx_ == 0.0F) { return; }
|
if (vx_ == 0.0F) { return; }
|
||||||
|
|
||||||
// Movimiento horizontal y colision con muros
|
// Movimiento horizontal y colision con muros
|
||||||
const float DISPLACEMENT = vx_ * delta_time;
|
applyHorizontalMovement(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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Comprueba colision con rampas, corrige y cambia estado
|
// 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 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();
|
const bool IS_LEFT_SLOPE = isLeftSlope();
|
||||||
|
|
||||||
// Movimiento horizontal con colisión lateral
|
// Movimiento horizontal con colisión lateral
|
||||||
const float DISPLACEMENT = vx_ * delta_time;
|
applyHorizontalMovement(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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Seleccionar el pie apropiado según el tipo de rampa
|
// Seleccionar el pie apropiado según el tipo de rampa
|
||||||
// Left slopes (forma \) colisionan con el pie izquierdo
|
// Left slopes (forma \) colisionan con el pie izquierdo
|
||||||
@@ -340,23 +304,7 @@ void Player::moveOnSlope(float delta_time) {
|
|||||||
// Movimiento físico del estado JUMPING
|
// Movimiento físico del estado JUMPING
|
||||||
void Player::moveJumping(float delta_time) {
|
void Player::moveJumping(float delta_time) {
|
||||||
// Movimiento horizontal
|
// Movimiento horizontal
|
||||||
if (vx_ != 0.0F) {
|
applyHorizontalMovement(delta_time);
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Movimiento vertical
|
// Movimiento vertical
|
||||||
applyGravity(delta_time);
|
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
|
// Crea el rectangulo de proyección en el eje Y para ver si colisiona
|
||||||
const SDL_FRect PROJECTION = getProjection(Direction::DOWN, DISPLACEMENT_Y);
|
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
|
||||||
const float POS = std::max(room_->checkTopSurfaces(PROJECTION), room_->checkAutoSurfaces(PROJECTION));
|
if (vx_ == 0.0F) {
|
||||||
if (POS != Collision::NONE) {
|
handleLandingFromAir(DISPLACEMENT_Y, PROJECTION);
|
||||||
// Si hay colisión lo mueve hasta donde no colisiona y pasa a estar sobre la superficie
|
} else {
|
||||||
y_ = POS - HEIGHT;
|
// Comprueba la colisión con las superficies y las cintas transportadoras (sin rampas)
|
||||||
transitionToState(State::ON_GROUND); // Aterrizó en superficie plana o conveyor belt
|
const float POS = std::max(room_->checkTopSurfaces(PROJECTION), room_->checkAutoSurfaces(PROJECTION));
|
||||||
}
|
if (POS != Collision::NONE) {
|
||||||
// Comprueba la colisión con las rampas
|
// Si hay colisión lo mueve hasta donde no colisiona y pasa a estar sobre la superficie
|
||||||
else {
|
y_ = POS - HEIGHT;
|
||||||
// JUMPING colisiona con rampas solo si vx_ == 0
|
transitionToState(State::ON_GROUND);
|
||||||
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;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
// Esta saltando con movimiento horizontal y no hay colisión con los muros
|
// Esta saltando con movimiento horizontal y no hay colisión con los muros
|
||||||
// Calcula la nueva posición (atraviesa rampas)
|
// Calcula la nueva posición (atraviesa rampas)
|
||||||
@@ -421,26 +357,8 @@ void Player::moveFalling(float delta_time) {
|
|||||||
const float DISPLACEMENT = vy_ * delta_time;
|
const float DISPLACEMENT = vy_ * delta_time;
|
||||||
const SDL_FRect PROJECTION = getProjection(Direction::DOWN, DISPLACEMENT);
|
const SDL_FRect PROJECTION = getProjection(Direction::DOWN, DISPLACEMENT);
|
||||||
|
|
||||||
// Comprueba la colisión con las superficies y las cintas transportadoras
|
// Comprueba aterrizaje en superficies y rampas
|
||||||
const float POS = std::max(room_->checkTopSurfaces(PROJECTION), room_->checkAutoSurfaces(PROJECTION));
|
handleLandingFromAir(DISPLACEMENT, 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 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
|
||||||
@@ -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
|
// Devuelve el rectangulo de proyeccion
|
||||||
auto Player::getProjection(Direction direction, float displacement) -> SDL_FRect {
|
auto Player::getProjection(Direction direction, float displacement) -> SDL_FRect {
|
||||||
switch (direction) {
|
switch (direction) {
|
||||||
|
|||||||
@@ -181,8 +181,11 @@ class Player {
|
|||||||
void applyGravity(float delta_time); // Aplica gravedad al jugador
|
void applyGravity(float delta_time); // Aplica gravedad al jugador
|
||||||
|
|
||||||
// --- Funciones de movimiento y colisión ---
|
// --- Funciones de movimiento y colisión ---
|
||||||
void move(float delta_time); // Orquesta el movimiento del jugador
|
void move(float delta_time); // Orquesta el movimiento del jugador
|
||||||
auto getProjection(Direction direction, float displacement) -> SDL_FRect; // Devuelve el rectangulo de proyeccion
|
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 ---
|
// --- Funciones de detección de superficies ---
|
||||||
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
|
||||||
|
|||||||
Reference in New Issue
Block a user