treballant en Player
This commit is contained in:
@@ -9,7 +9,8 @@
|
|||||||
"Bash(cat:*)",
|
"Bash(cat:*)",
|
||||||
"Bash(git add:*)",
|
"Bash(git add:*)",
|
||||||
"Bash(git commit:*)",
|
"Bash(git commit:*)",
|
||||||
"Bash(git checkout:*)"
|
"Bash(git checkout:*)",
|
||||||
|
"Bash(sort:*)"
|
||||||
],
|
],
|
||||||
"deny": [],
|
"deny": [],
|
||||||
"ask": []
|
"ask": []
|
||||||
|
|||||||
@@ -49,24 +49,14 @@ void Player::handleInput() {
|
|||||||
} else if (Input::get()->checkAction(InputAction::RIGHT)) {
|
} else if (Input::get()->checkAction(InputAction::RIGHT)) {
|
||||||
wannaGo = Direction::RIGHT;
|
wannaGo = Direction::RIGHT;
|
||||||
} else {
|
} else {
|
||||||
wannaGo = Direction::STAY;
|
wannaGo = Direction::NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
wannaJump = Input::get()->checkAction(InputAction::JUMP);
|
wannaJump = Input::get()->checkAction(InputAction::JUMP);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ANTIGUO move() - Comentado durante migración a paradigma de estados
|
// La lógica de movimiento está distribuida en move
|
||||||
/*
|
|
||||||
void Player::move(float delta_time) {
|
void Player::move(float delta_time) {
|
||||||
handleHorizontalMovement(delta_time);
|
|
||||||
handleVerticalMovement(delta_time);
|
|
||||||
updateColliderGeometry();
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
// NUEVO: La lógica de movimiento está distribuida en move*() y se llama desde update*()
|
|
||||||
void Player::move(float delta_time) {
|
|
||||||
// Este método ahora es un dispatcher que llama al método de movimiento correspondiente
|
|
||||||
switch (state_) {
|
switch (state_) {
|
||||||
case State::ON_GROUND:
|
case State::ON_GROUND:
|
||||||
moveOnGround(delta_time);
|
moveOnGround(delta_time);
|
||||||
@@ -81,45 +71,11 @@ void Player::move(float delta_time) {
|
|||||||
moveFalling(delta_time);
|
moveFalling(delta_time);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
syncSpriteAndCollider(); // Actualiza la posición del sprite y las colisiones
|
||||||
|
|
||||||
void Player::handleHorizontalMovement(float delta_time) {
|
|
||||||
// TODO: Verificar si esto debe aplicar solo a ON_GROUND o también ON_SLOPE
|
|
||||||
if (state_ == State::ON_GROUND || state_ == State::ON_SLOPE) {
|
|
||||||
// Determinama cuál debe ser la velocidad a partir de automovement o de wannaGo
|
|
||||||
updateVelocity();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Aplica el movimiento y el flip basado en la velocidad resultante
|
|
||||||
if (vx_ < 0.0F) {
|
|
||||||
moveHorizontal(delta_time, Direction::LEFT);
|
|
||||||
sprite_->setFlip(SDL_FLIP_HORIZONTAL);
|
|
||||||
} else if (vx_ > 0.0F) {
|
|
||||||
moveHorizontal(delta_time, Direction::RIGHT);
|
|
||||||
sprite_->setFlip(SDL_FLIP_NONE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Player::handleVerticalMovement(float delta_time) {
|
|
||||||
// No hay movimiento vertical en estados terrestres
|
|
||||||
if (state_ == State::ON_GROUND || state_ == State::ON_SLOPE) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (state_ == State::JUMPING) {
|
|
||||||
applyGravity(delta_time);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Movimiento vertical
|
|
||||||
if (vy_ < 0.0F) {
|
|
||||||
moveVerticalUp(delta_time);
|
|
||||||
} else if (vy_ > 0.0F) {
|
|
||||||
moveVerticalDown(delta_time);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Player::handleConveyorBelts() {
|
void Player::handleConveyorBelts() {
|
||||||
if (!auto_movement_ and isOnConveyorBelt() and wannaGo == Direction::STAY) {
|
if (!auto_movement_ and isOnConveyorBelt() and wannaGo == Direction::NONE) {
|
||||||
auto_movement_ = true;
|
auto_movement_ = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -129,7 +85,6 @@ void Player::handleConveyorBelts() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Player::handleShouldFall() {
|
void Player::handleShouldFall() {
|
||||||
// TODO: También verificar ON_SLOPE
|
|
||||||
if (!isOnFloor() and (state_ == State::ON_GROUND || state_ == State::ON_SLOPE)) {
|
if (!isOnFloor() and (state_ == State::ON_GROUND || state_ == State::ON_SLOPE)) {
|
||||||
transitionToState(State::FALLING);
|
transitionToState(State::FALLING);
|
||||||
}
|
}
|
||||||
@@ -189,126 +144,237 @@ void Player::updateState(float delta_time) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ============================================================================
|
|
||||||
// NUEVO PARADIGMA: Métodos de actualización por estado
|
|
||||||
// ============================================================================
|
|
||||||
|
|
||||||
// ANTIGUO updateState() - Comentado durante migración
|
|
||||||
/*
|
|
||||||
void Player::updateState(float delta_time) {
|
|
||||||
switch (state_) {
|
|
||||||
case State::STANDING:
|
|
||||||
handleConveyorBelts();
|
|
||||||
handleShouldFall();
|
|
||||||
if (wannaJump) {
|
|
||||||
transitionToState(State::JUMPING);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case State::JUMPING:
|
|
||||||
auto_movement_ = false;
|
|
||||||
playJumpSound(delta_time);
|
|
||||||
handleJumpEnd();
|
|
||||||
break;
|
|
||||||
case State::FALLING:
|
|
||||||
auto_movement_ = false;
|
|
||||||
playFallSound(delta_time);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Actualización lógica del estado ON_GROUND
|
// Actualización lógica del estado ON_GROUND
|
||||||
void Player::updateOnGround(float delta_time) {
|
void Player::updateOnGround(float delta_time) {
|
||||||
(void)delta_time; // No usado en este método, pero se mantiene por consistencia
|
(void)delta_time; // No usado en este método, pero se mantiene por consistencia
|
||||||
|
handleConveyorBelts(); // Gestiona las cintas transportadoras
|
||||||
// Gestiona las cintas transportadoras
|
handleShouldFall(); // Verifica si debe caer (no tiene suelo)
|
||||||
handleConveyorBelts();
|
|
||||||
|
|
||||||
// Verifica si debe caer (no tiene suelo)
|
|
||||||
handleShouldFall();
|
|
||||||
|
|
||||||
// Verifica si el jugador quiere saltar
|
// Verifica si el jugador quiere saltar
|
||||||
if (wannaJump) {
|
if (wannaJump) { transitionToState(State::JUMPING); }
|
||||||
transitionToState(State::JUMPING);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Actualización lógica del estado ON_SLOPE
|
// Actualización lógica del estado ON_SLOPE
|
||||||
void Player::updateOnSlope(float delta_time) {
|
void Player::updateOnSlope(float delta_time) {
|
||||||
(void)delta_time; // No usado en este método, pero se mantiene por consistencia
|
(void)delta_time; // No usado en este método, pero se mantiene por consistencia
|
||||||
|
handleShouldFall(); // Verifica si debe caer (no tiene suelo)
|
||||||
// Verifica si debe caer (no tiene suelo)
|
|
||||||
handleShouldFall();
|
|
||||||
|
|
||||||
// Verifica si el jugador quiere saltar
|
// Verifica si el jugador quiere saltar
|
||||||
if (wannaJump) {
|
if (wannaJump) { transitionToState(State::JUMPING); }
|
||||||
transitionToState(State::JUMPING);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Actualización lógica del estado JUMPING
|
// Actualización lógica del estado JUMPING
|
||||||
void Player::updateJumping(float delta_time) {
|
void Player::updateJumping(float delta_time) {
|
||||||
// Desactiva el movimiento automático durante el salto
|
auto_movement_ = false; // Desactiva el movimiento automático durante el salto
|
||||||
auto_movement_ = false;
|
playJumpSound(delta_time); // Reproduce los sonidos de salto
|
||||||
|
handleJumpEnd(); // Verifica si el salto ha terminado (alcanzó la altura inicial)
|
||||||
// Reproduce los sonidos de salto
|
|
||||||
playJumpSound(delta_time);
|
|
||||||
|
|
||||||
// Verifica si el salto ha terminado (alcanzó la altura inicial)
|
|
||||||
handleJumpEnd();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Actualización lógica del estado FALLING
|
// Actualización lógica del estado FALLING
|
||||||
void Player::updateFalling(float delta_time) {
|
void Player::updateFalling(float delta_time) {
|
||||||
// Desactiva el movimiento automático durante la caída
|
auto_movement_ = false; // Desactiva el movimiento automático durante la caída
|
||||||
auto_movement_ = false;
|
playFallSound(delta_time); // Reproduce los sonidos de caída
|
||||||
|
|
||||||
// Reproduce los sonidos de caída
|
|
||||||
playFallSound(delta_time);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ============================================================================
|
|
||||||
// NUEVO PARADIGMA: Métodos de movimiento por estado
|
|
||||||
// ============================================================================
|
|
||||||
|
|
||||||
// Movimiento físico del estado ON_GROUND
|
// Movimiento físico del estado ON_GROUND
|
||||||
void Player::moveOnGround(float delta_time) {
|
void Player::moveOnGround(float delta_time) {
|
||||||
// Movimiento horizontal en suelo plano (migrado de handleHorizontalMovement)
|
// Determinama cuál debe ser la velocidad a partir de automovement o de wannaGo
|
||||||
handleHorizontalMovement(delta_time);
|
updateVelocity();
|
||||||
|
|
||||||
// Actualiza geometría de colisión
|
if (vx_ == 0.0F) { return; }
|
||||||
updateColliderGeometry();
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Movimiento físico del estado ON_SLOPE
|
// Movimiento físico del estado ON_SLOPE
|
||||||
void Player::moveOnSlope(float delta_time) {
|
void Player::moveOnSlope(float delta_time) {
|
||||||
// Movimiento horizontal en rampa (migrado de handleHorizontalMovement)
|
// Determinama cuál debe ser la velocidad a partir de automovement o de wannaGo
|
||||||
// handleSlopeMovement() ya se llama desde dentro de moveHorizontal()
|
updateVelocity();
|
||||||
handleHorizontalMovement(delta_time);
|
|
||||||
|
|
||||||
// Actualiza geometría de colisión
|
if (vx_ == 0.0F) { return; }
|
||||||
updateColliderGeometry();
|
|
||||||
|
// Movimiento horizontal
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Movimiento vertical
|
||||||
|
// Regla: Si está bajando la rampa, se pega a la slope
|
||||||
|
if (isOnDownSlope()) {
|
||||||
|
y_ += 1;
|
||||||
|
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
|
||||||
void Player::moveJumping(float delta_time) {
|
void Player::moveJumping(float delta_time) {
|
||||||
// Movimiento horizontal (migrado de handleHorizontalMovement)
|
// Movimiento horizontal
|
||||||
handleHorizontalMovement(delta_time);
|
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);
|
||||||
|
|
||||||
// Movimiento vertical (migrado de handleVerticalMovement)
|
// Comprueba la colisión con las superficies
|
||||||
handleVerticalMovement(delta_time);
|
const int POS = DIRECTION == Direction::LEFT ? room_->checkRightSurfaces(PROJECTION) : room_->checkLeftSurfaces(PROJECTION);
|
||||||
|
|
||||||
// Actualiza geometría de colisión
|
// Calcula la nueva posición
|
||||||
updateColliderGeometry();
|
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
|
||||||
|
applyGravity(delta_time);
|
||||||
|
|
||||||
|
const float DISPLACEMENT_Y = vy_ * delta_time;
|
||||||
|
// Movimiento vertical hacia arriba
|
||||||
|
if (vy_ < 0.0F) {
|
||||||
|
const SDL_FRect PROJECTION = getProjection(Direction::UP, DISPLACEMENT_Y);
|
||||||
|
|
||||||
|
// Comprueba la colisión
|
||||||
|
const int POS = room_->checkBottomSurfaces(PROJECTION);
|
||||||
|
|
||||||
|
// Calcula la nueva posición
|
||||||
|
if (POS == Collision::NONE) {
|
||||||
|
// Si no hay colisión
|
||||||
|
y_ += DISPLACEMENT_Y;
|
||||||
|
} else {
|
||||||
|
// Si hay colisión lo mueve hasta donde no colisiona -> FALLING
|
||||||
|
y_ = POS + 1;
|
||||||
|
transitionToState(State::FALLING);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Movimiento vertical hacia abajo
|
||||||
|
else if (vy_ > 0.0F) {
|
||||||
|
// 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
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Esta saltando con movimiento horizontal y no hay colisión con los muros
|
||||||
|
// Calcula la nueva posición (atraviesa rampas)
|
||||||
|
y_ += DISPLACEMENT_Y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Movimiento físico del estado FALLING
|
// Movimiento físico del estado FALLING
|
||||||
void Player::moveFalling(float delta_time) {
|
void Player::moveFalling(float delta_time) {
|
||||||
// Movimiento vertical (migrado de handleVerticalMovement)
|
// Crea el rectangulo de proyección en el eje Y para ver si colisiona
|
||||||
handleVerticalMovement(delta_time);
|
const float DISPLACEMENT = vy_ * delta_time;
|
||||||
|
const SDL_FRect PROJECTION = getProjection(Direction::DOWN, DISPLACEMENT);
|
||||||
|
|
||||||
// Actualiza geometría de colisión
|
// Comprueba la colisión con las superficies y las cintas transportadoras
|
||||||
updateColliderGeometry();
|
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 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
|
||||||
@@ -394,169 +460,6 @@ void Player::applyGravity(float delta_time) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Maneja el movimiento sobre rampas
|
|
||||||
void Player::handleSlopeMovement(Direction direction) {
|
|
||||||
// No procesa rampas durante el salto (permite atravesarlas cuando salta con movimiento horizontal)
|
|
||||||
// Pero SÍ procesa en STANDING y FALLING (para pegarse a las rampas)
|
|
||||||
if (state_ == State::JUMPING) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Regla: Si está bajando la rampa, se pega a la slope
|
|
||||||
if (isOnDownSlope()) {
|
|
||||||
y_ += 1;
|
|
||||||
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 = direction == Direction::LEFT ? 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 = direction == Direction::LEFT ? 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 ---
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Maneja el movimiento horizontal
|
|
||||||
void Player::moveHorizontal(float delta_time, Direction direction) {
|
|
||||||
const float DISPLACEMENT = vx_ * delta_time;
|
|
||||||
|
|
||||||
// Crea el rectangulo de proyección en el eje X para ver si colisiona
|
|
||||||
SDL_FRect proj;
|
|
||||||
switch (direction) {
|
|
||||||
case Direction::LEFT:
|
|
||||||
// Movimiento a la izquierda
|
|
||||||
proj = {
|
|
||||||
.x = x_ + DISPLACEMENT,
|
|
||||||
.y = y_,
|
|
||||||
.w = std::ceil(std::fabs(DISPLACEMENT)),
|
|
||||||
.h = HEIGHT};
|
|
||||||
break;
|
|
||||||
|
|
||||||
case Direction::RIGHT:
|
|
||||||
// Movimiento a la derecha
|
|
||||||
proj = {
|
|
||||||
.x = x_ + WIDTH,
|
|
||||||
.y = y_,
|
|
||||||
.w = std::ceil(DISPLACEMENT),
|
|
||||||
.h = HEIGHT};
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Comprueba la colisión con las superficies
|
|
||||||
const int POS = direction == Direction::LEFT ? room_->checkRightSurfaces(proj) : room_->checkLeftSurfaces(proj);
|
|
||||||
|
|
||||||
// Calcula la nueva posición
|
|
||||||
if (POS == Collision::NONE) {
|
|
||||||
// No hay colisión: mueve al jugador
|
|
||||||
x_ += DISPLACEMENT;
|
|
||||||
} else {
|
|
||||||
// Hay colisión: reposiciona al jugador en el punto de colisión
|
|
||||||
x_ = direction == Direction::LEFT ? POS + 1 : POS - WIDTH;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Maneja el movimiento sobre rampas
|
|
||||||
handleSlopeMovement(direction);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Maneja el movimiento vertical hacia arriba
|
|
||||||
void Player::moveVerticalUp(float delta_time) {
|
|
||||||
// Crea el rectangulo de proyección en el eje Y para ver si colisiona
|
|
||||||
const float DISPLACEMENT = vy_ * delta_time;
|
|
||||||
SDL_FRect proj = {
|
|
||||||
.x = x_,
|
|
||||||
.y = y_ + DISPLACEMENT,
|
|
||||||
.w = WIDTH,
|
|
||||||
.h = std::ceil(std::fabs(DISPLACEMENT)) // Para evitar que tenga una altura de 0 pixels
|
|
||||||
};
|
|
||||||
|
|
||||||
// Comprueba la colisión
|
|
||||||
const int POS = room_->checkBottomSurfaces(proj);
|
|
||||||
|
|
||||||
// Calcula la nueva posición
|
|
||||||
if (POS == Collision::NONE) {
|
|
||||||
// Si no hay colisión
|
|
||||||
y_ += DISPLACEMENT;
|
|
||||||
} else {
|
|
||||||
// Si hay colisión lo mueve hasta donde no colisiona
|
|
||||||
// Regla: Si está JUMPING y tropieza contra el techo -> FALLING
|
|
||||||
y_ = POS + 1;
|
|
||||||
transitionToState(State::FALLING);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Maneja el movimiento vertical hacia abajo
|
|
||||||
void Player::moveVerticalDown(float delta_time) {
|
|
||||||
// Crea el rectangulo de proyección en el eje Y para ver si colisiona
|
|
||||||
const float DISPLACEMENT = vy_ * delta_time;
|
|
||||||
SDL_FRect proj = {
|
|
||||||
.x = x_,
|
|
||||||
.y = y_ + HEIGHT,
|
|
||||||
.w = WIDTH,
|
|
||||||
.h = std::ceil(DISPLACEMENT) // Para evitar que tenga una altura de 0 pixels
|
|
||||||
};
|
|
||||||
|
|
||||||
// Comprueba la colisión con las superficies normales y las automáticas
|
|
||||||
const float POS = std::max(room_->checkTopSurfaces(proj), room_->checkAutoSurfaces(proj));
|
|
||||||
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
|
|
||||||
} else {
|
|
||||||
// Si no hay colisión con los muros, comprueba la colisión con las rampas
|
|
||||||
// CORRECCIÓN: FALLING siempre se pega a rampas, JUMPING se pega solo si vx_ == 0
|
|
||||||
if (state_ == State::FALLING || (state_ == State::JUMPING && vx_ == 0.0F)) {
|
|
||||||
// No está saltando O salta recto: se pega a las rampas
|
|
||||||
auto rect = toSDLRect(proj);
|
|
||||||
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) {
|
|
||||||
// No está saltando y hay colisión con una rampa
|
|
||||||
// Calcula la nueva posición
|
|
||||||
y_ = POINT - HEIGHT;
|
|
||||||
transitionToState(State::ON_SLOPE); // Aterrizó en rampa
|
|
||||||
} else {
|
|
||||||
// No está saltando y no hay colisón con una rampa
|
|
||||||
// Calcula la nueva posición
|
|
||||||
y_ += DISPLACEMENT;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// Esta saltando con movimiento horizontal y no hay colisión con los muros
|
|
||||||
// Calcula la nueva posición (atraviesa rampas)
|
|
||||||
y_ += DISPLACEMENT;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Establece la animación del jugador
|
// Establece la animación del jugador
|
||||||
void Player::animate(float delta_time) {
|
void Player::animate(float delta_time) {
|
||||||
if (vx_ != 0) {
|
if (vx_ != 0) {
|
||||||
@@ -595,25 +498,38 @@ void Player::playFallSound(float delta_time) {
|
|||||||
|
|
||||||
// Comprueba si el jugador tiene suelo debajo de los pies
|
// Comprueba si el jugador tiene suelo debajo de los pies
|
||||||
auto Player::isOnFloor() -> bool {
|
auto Player::isOnFloor() -> bool {
|
||||||
bool on_floor = false;
|
bool on_top_surface = false;
|
||||||
|
bool on_conveyor_belt = false;
|
||||||
updateFeet();
|
updateFeet();
|
||||||
|
|
||||||
// Comprueba las superficies
|
// Comprueba las superficies
|
||||||
on_floor |= room_->checkTopSurfaces(under_left_foot_);
|
on_top_surface |= room_->checkTopSurfaces(under_left_foot_);
|
||||||
on_floor |= room_->checkTopSurfaces(under_right_foot_);
|
on_top_surface |= room_->checkTopSurfaces(under_right_foot_);
|
||||||
|
|
||||||
// Comprueba las cintas transportadoras
|
// Comprueba las cintas transportadoras
|
||||||
on_floor |= room_->checkConveyorBelts(under_left_foot_);
|
on_conveyor_belt |= room_->checkConveyorBelts(under_left_foot_);
|
||||||
on_floor |= room_->checkConveyorBelts(under_right_foot_);
|
on_conveyor_belt |= room_->checkConveyorBelts(under_right_foot_);
|
||||||
|
|
||||||
// Comprueba las rampas
|
// Comprueba las rampas
|
||||||
auto on_slope_l = room_->checkLeftSlopes(under_left_foot_);
|
auto on_slope_l = room_->checkLeftSlopes(under_left_foot_);
|
||||||
auto on_slope_r = room_->checkRightSlopes(under_right_foot_);
|
auto on_slope_r = room_->checkRightSlopes(under_right_foot_);
|
||||||
|
|
||||||
return on_floor || on_slope_l || on_slope_r;
|
return on_top_surface || on_conveyor_belt || on_slope_l || on_slope_r;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Comprueba si el jugador esta sobre una superficie automática
|
// Comprueba si el jugador está sobre una superficie
|
||||||
|
auto Player::isOnTopSurface() -> bool {
|
||||||
|
bool on_top_surface = false;
|
||||||
|
updateFeet();
|
||||||
|
|
||||||
|
// Comprueba las superficies
|
||||||
|
on_top_surface |= room_->checkTopSurfaces(under_left_foot_);
|
||||||
|
on_top_surface |= room_->checkTopSurfaces(under_right_foot_);
|
||||||
|
|
||||||
|
return on_top_surface;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Comprueba si el jugador esta sobre una cinta transportadora
|
||||||
auto Player::isOnConveyorBelt() -> bool {
|
auto Player::isOnConveyorBelt() -> bool {
|
||||||
bool on_conveyor_belt = false;
|
bool on_conveyor_belt = false;
|
||||||
updateFeet();
|
updateFeet();
|
||||||
@@ -644,6 +560,18 @@ auto Player::isOnDownSlope() -> bool {
|
|||||||
return on_slope;
|
return on_slope;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Comprueba si el jugador está sobre una rampa
|
||||||
|
auto Player::isOnSlope() -> bool {
|
||||||
|
bool on_slope = false;
|
||||||
|
updateFeet();
|
||||||
|
|
||||||
|
// Comprueba las rampas
|
||||||
|
on_slope |= room_->checkLeftSlopes(under_left_foot_);
|
||||||
|
on_slope |= room_->checkRightSlopes(under_right_foot_);
|
||||||
|
|
||||||
|
return on_slope;
|
||||||
|
}
|
||||||
|
|
||||||
// Comprueba que el jugador no toque ningun tile de los que matan
|
// Comprueba que el jugador no toque ningun tile de los que matan
|
||||||
auto Player::handleKillingTiles() -> bool {
|
auto Player::handleKillingTiles() -> bool {
|
||||||
// Comprueba si hay contacto con algún tile que mata
|
// Comprueba si hay contacto con algún tile que mata
|
||||||
@@ -806,8 +734,8 @@ void Player::initSprite(const std::string& animations_path) {
|
|||||||
sprite_->setCurrentAnimation("walk");
|
sprite_->setCurrentAnimation("walk");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Actualiza collider_box y collision points
|
// Actualiza la posición del sprite y las colisiones
|
||||||
void Player::updateColliderGeometry() {
|
void Player::syncSpriteAndCollider() {
|
||||||
placeSprite(); // Coloca el sprite en la posición del jugador
|
placeSprite(); // Coloca el sprite en la posición del jugador
|
||||||
collider_box_ = getRect(); // Actualiza el rectangulo de colisión
|
collider_box_ = getRect(); // Actualiza el rectangulo de colisión
|
||||||
updateColliderPoints(); // Actualiza los puntos de colisión
|
updateColliderPoints(); // Actualiza los puntos de colisión
|
||||||
@@ -831,20 +759,66 @@ void Player::updateVelocity() {
|
|||||||
if (auto_movement_) {
|
if (auto_movement_) {
|
||||||
// La cinta transportadora tiene el control
|
// La cinta transportadora tiene el control
|
||||||
vx_ = HORIZONTAL_VELOCITY * room_->getConveyorBeltDirection();
|
vx_ = HORIZONTAL_VELOCITY * room_->getConveyorBeltDirection();
|
||||||
|
sprite_->setFlip(vx_ < 0.0F ? Flip::LEFT : Flip::RIGHT);
|
||||||
} else {
|
} else {
|
||||||
// El jugador tiene el control
|
// El jugador tiene el control
|
||||||
switch (wannaGo) {
|
switch (wannaGo) {
|
||||||
case Direction::LEFT:
|
case Direction::LEFT:
|
||||||
vx_ = -HORIZONTAL_VELOCITY;
|
vx_ = -HORIZONTAL_VELOCITY;
|
||||||
|
sprite_->setFlip(Flip::LEFT);
|
||||||
break;
|
break;
|
||||||
case Direction::RIGHT:
|
case Direction::RIGHT:
|
||||||
vx_ = HORIZONTAL_VELOCITY;
|
vx_ = HORIZONTAL_VELOCITY;
|
||||||
|
sprite_->setFlip(Flip::RIGHT);
|
||||||
break;
|
break;
|
||||||
case Direction::STAY:
|
case Direction::NONE:
|
||||||
vx_ = 0.0F;
|
vx_ = 0.0F;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
vx_ = 0.0F;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Devuelve el rectangulo de proyeccion
|
||||||
|
auto Player::getProjection(Direction direction, float displacement) -> SDL_FRect {
|
||||||
|
switch (direction) {
|
||||||
|
case Direction::LEFT:
|
||||||
|
return {
|
||||||
|
.x = x_ + displacement,
|
||||||
|
.y = y_,
|
||||||
|
.w = std::ceil(std::fabs(displacement)), // Para evitar que tenga una anchura de 0 pixels
|
||||||
|
.h = HEIGHT};
|
||||||
|
|
||||||
|
case Direction::RIGHT:
|
||||||
|
return {
|
||||||
|
.x = x_ + WIDTH,
|
||||||
|
.y = y_,
|
||||||
|
.w = std::ceil(displacement), // Para evitar que tenga una anchura de 0 pixels
|
||||||
|
.h = HEIGHT};
|
||||||
|
|
||||||
|
case Direction::UP:
|
||||||
|
return {
|
||||||
|
.x = x_,
|
||||||
|
.y = y_ + displacement,
|
||||||
|
.w = WIDTH,
|
||||||
|
.h = std::ceil(std::fabs(displacement)) // Para evitar que tenga una altura de 0 pixels
|
||||||
|
};
|
||||||
|
|
||||||
|
case Direction::DOWN:
|
||||||
|
return {
|
||||||
|
.x = x_,
|
||||||
|
.y = y_ + HEIGHT,
|
||||||
|
.w = WIDTH,
|
||||||
|
.h = std::ceil(displacement) // Para evitar que tenga una altura de 0 pixels
|
||||||
|
};
|
||||||
|
|
||||||
|
default:
|
||||||
|
return {
|
||||||
|
.x = 0.0F,
|
||||||
|
.y = 0.0F,
|
||||||
|
.w = 0.0F,
|
||||||
|
.h = 0.0F};
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -27,7 +27,9 @@ class Player {
|
|||||||
enum class Direction {
|
enum class Direction {
|
||||||
LEFT,
|
LEFT,
|
||||||
RIGHT,
|
RIGHT,
|
||||||
STAY
|
UP,
|
||||||
|
DOWN,
|
||||||
|
NONE
|
||||||
};
|
};
|
||||||
|
|
||||||
// --- Constantes de física (públicas para permitir cálculos en structs) ---
|
// --- Constantes de física (públicas para permitir cálculos en structs) ---
|
||||||
@@ -118,7 +120,7 @@ class Player {
|
|||||||
float vx_ = 0.0F; // Velocidad/desplazamiento del jugador en el eje X
|
float vx_ = 0.0F; // Velocidad/desplazamiento del jugador en el eje X
|
||||||
float vy_ = 0.0F; // Velocidad/desplazamiento del jugador en el eje Y
|
float vy_ = 0.0F; // Velocidad/desplazamiento del jugador en el eje Y
|
||||||
|
|
||||||
Direction wannaGo = Direction::STAY;
|
Direction wannaGo = Direction::NONE;
|
||||||
bool wannaJump = false;
|
bool wannaJump = false;
|
||||||
|
|
||||||
// --- Variables de estado ---
|
// --- Variables de estado ---
|
||||||
@@ -143,27 +145,25 @@ class Player {
|
|||||||
Uint8 color_ = 0; // Color del jugador
|
Uint8 color_ = 0; // Color del jugador
|
||||||
std::array<JA_Sound_t*, 24> jumping_sound_{}; // Array con todos los sonidos del salto
|
std::array<JA_Sound_t*, 24> jumping_sound_{}; // Array con todos los sonidos del salto
|
||||||
std::array<JA_Sound_t*, 14> falling_sound_{}; // Array con todos los sonidos de la caída
|
std::array<JA_Sound_t*, 14> falling_sound_{}; // Array con todos los sonidos de la caída
|
||||||
JumpSoundController jump_sound_ctrl_; // Controlador de sonidos de salto
|
JumpSoundController jump_sound_ctrl_; // Controlador de sonidos de salto
|
||||||
FallSoundController fall_sound_ctrl_; // Controlador de sonidos de caída
|
FallSoundController fall_sound_ctrl_; // Controlador de sonidos de caída
|
||||||
int fall_start_position_ = 0; // Posición Y al iniciar la caída
|
int fall_start_position_ = 0; // Posición Y al iniciar la caída
|
||||||
|
|
||||||
void handleHorizontalMovement(float delta_time);
|
|
||||||
void handleVerticalMovement(float delta_time);
|
|
||||||
void handleConveyorBelts();
|
void handleConveyorBelts();
|
||||||
void handleShouldFall();
|
void handleShouldFall();
|
||||||
void updateState(float delta_time);
|
void updateState(float delta_time);
|
||||||
|
|
||||||
// --- Métodos de actualización por estado (nuevo paradigma) ---
|
// --- Métodos de actualización por estado ---
|
||||||
void updateOnGround(float delta_time); // Actualización lógica estado ON_GROUND
|
void updateOnGround(float delta_time); // Actualización lógica estado ON_GROUND
|
||||||
void updateOnSlope(float delta_time); // Actualización lógica estado ON_SLOPE
|
void updateOnSlope(float delta_time); // Actualización lógica estado ON_SLOPE
|
||||||
void updateJumping(float delta_time); // Actualización lógica estado JUMPING
|
void updateJumping(float delta_time); // Actualización lógica estado JUMPING
|
||||||
void updateFalling(float delta_time); // Actualización lógica estado FALLING
|
void updateFalling(float delta_time); // Actualización lógica estado FALLING
|
||||||
|
|
||||||
// --- Métodos de movimiento por estado (nuevo paradigma) ---
|
// --- Métodos de movimiento por estado ---
|
||||||
void moveOnGround(float delta_time); // Movimiento físico estado ON_GROUND
|
void moveOnGround(float delta_time); // Movimiento físico estado ON_GROUND
|
||||||
void moveOnSlope(float delta_time); // Movimiento físico estado ON_SLOPE
|
void moveOnSlope(float delta_time); // Movimiento físico estado ON_SLOPE
|
||||||
void moveJumping(float delta_time); // Movimiento físico estado JUMPING
|
void moveJumping(float delta_time); // Movimiento físico estado JUMPING
|
||||||
void moveFalling(float delta_time); // Movimiento físico estado FALLING
|
void moveFalling(float delta_time); // Movimiento físico estado FALLING
|
||||||
|
|
||||||
// --- Funciones de inicialización ---
|
// --- Funciones de inicialización ---
|
||||||
void initSprite(const std::string& animations_path); // Inicializa el sprite del jugador
|
void initSprite(const std::string& animations_path); // Inicializa el sprite del jugador
|
||||||
@@ -181,22 +181,21 @@ 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
|
||||||
void moveHorizontal(float delta_time, Direction direction); // Maneja el movimiento horizontal (-1: izq, 1: der)
|
auto getProjection(Direction direction, float displacement) -> SDL_FRect; // Devuelve el rectangulo de proyeccion
|
||||||
void moveVerticalUp(float delta_time); // Maneja el movimiento vertical hacia arriba
|
|
||||||
void moveVerticalDown(float delta_time); // Maneja el movimiento vertical hacia abajo
|
|
||||||
void handleSlopeMovement(Direction direction); // Maneja el movimiento sobre rampas
|
|
||||||
|
|
||||||
// --- 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
|
||||||
auto isOnConveyorBelt() -> bool; // Comprueba si el jugador esta sobre una superficie automática
|
auto isOnTopSurface() -> bool; // Comprueba si el jugador está sobre una superficie
|
||||||
|
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 isOnDownSlope() -> bool; // Comprueba si el jugador está sobre una rampa hacia abajo
|
||||||
|
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 ---
|
||||||
void updateColliderGeometry(); // Actualiza collider_box y collision points
|
void syncSpriteAndCollider(); // Actualiza collider_box y collision points
|
||||||
void updateColliderPoints(); // Actualiza los puntos de colisión
|
void updateColliderPoints(); // Actualiza los puntos de colisión
|
||||||
void updateFeet(); // Actualiza los puntos de los pies
|
void updateFeet(); // Actualiza los puntos de los pies
|
||||||
void placeSprite(); // Coloca el sprite en la posición del jugador
|
void placeSprite(); // Coloca el sprite en la posición del jugador
|
||||||
|
|
||||||
// --- 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
|
||||||
|
|||||||
@@ -103,7 +103,7 @@ auto CollisionMap::getSlopeHeight(SDL_FPoint p, Tile slope) -> int {
|
|||||||
// === Queries de colisión ===
|
// === Queries de colisión ===
|
||||||
|
|
||||||
// Comprueba las colisiones con paredes derechas
|
// Comprueba las colisiones con paredes derechas
|
||||||
auto CollisionMap::checkRightSurfaces(SDL_FRect& rect) -> int {
|
auto CollisionMap::checkRightSurfaces(const SDL_FRect& rect) -> int {
|
||||||
for (const auto& s : right_walls_) {
|
for (const auto& s : right_walls_) {
|
||||||
if (checkCollision(s, rect)) {
|
if (checkCollision(s, rect)) {
|
||||||
return s.x;
|
return s.x;
|
||||||
@@ -113,7 +113,7 @@ auto CollisionMap::checkRightSurfaces(SDL_FRect& rect) -> int {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Comprueba las colisiones con paredes izquierdas
|
// Comprueba las colisiones con paredes izquierdas
|
||||||
auto CollisionMap::checkLeftSurfaces(SDL_FRect& rect) -> int {
|
auto CollisionMap::checkLeftSurfaces(const SDL_FRect& rect) -> int {
|
||||||
for (const auto& s : left_walls_) {
|
for (const auto& s : left_walls_) {
|
||||||
if (checkCollision(s, rect)) {
|
if (checkCollision(s, rect)) {
|
||||||
return s.x;
|
return s.x;
|
||||||
@@ -123,7 +123,7 @@ auto CollisionMap::checkLeftSurfaces(SDL_FRect& rect) -> int {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Comprueba las colisiones con techos
|
// Comprueba las colisiones con techos
|
||||||
auto CollisionMap::checkTopSurfaces(SDL_FRect& rect) -> int {
|
auto CollisionMap::checkTopSurfaces(const SDL_FRect& rect) -> int {
|
||||||
for (const auto& s : top_floors_) {
|
for (const auto& s : top_floors_) {
|
||||||
if (checkCollision(s, rect)) {
|
if (checkCollision(s, rect)) {
|
||||||
return s.y;
|
return s.y;
|
||||||
@@ -133,14 +133,14 @@ auto CollisionMap::checkTopSurfaces(SDL_FRect& rect) -> int {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Comprueba las colisiones punto con techos
|
// Comprueba las colisiones punto con techos
|
||||||
auto CollisionMap::checkTopSurfaces(SDL_FPoint& p) -> bool {
|
auto CollisionMap::checkTopSurfaces(const SDL_FPoint& p) -> bool {
|
||||||
return std::ranges::any_of(top_floors_, [&](const auto& s) {
|
return std::ranges::any_of(top_floors_, [&](const auto& s) {
|
||||||
return checkCollision(s, p);
|
return checkCollision(s, p);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Comprueba las colisiones con suelos
|
// Comprueba las colisiones con suelos
|
||||||
auto CollisionMap::checkBottomSurfaces(SDL_FRect& rect) -> int {
|
auto CollisionMap::checkBottomSurfaces(const SDL_FRect& rect) -> int {
|
||||||
for (const auto& s : bottom_floors_) {
|
for (const auto& s : bottom_floors_) {
|
||||||
if (checkCollision(s, rect)) {
|
if (checkCollision(s, rect)) {
|
||||||
return s.y;
|
return s.y;
|
||||||
@@ -150,7 +150,7 @@ auto CollisionMap::checkBottomSurfaces(SDL_FRect& rect) -> int {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Comprueba las colisiones con conveyor belts
|
// Comprueba las colisiones con conveyor belts
|
||||||
auto CollisionMap::checkAutoSurfaces(SDL_FRect& rect) -> int {
|
auto CollisionMap::checkAutoSurfaces(const SDL_FRect& rect) -> int {
|
||||||
for (const auto& s : conveyor_belt_floors_) {
|
for (const auto& s : conveyor_belt_floors_) {
|
||||||
if (checkCollision(s, rect)) {
|
if (checkCollision(s, rect)) {
|
||||||
return s.y;
|
return s.y;
|
||||||
@@ -160,7 +160,7 @@ auto CollisionMap::checkAutoSurfaces(SDL_FRect& rect) -> int {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Comprueba las colisiones punto con conveyor belts
|
// Comprueba las colisiones punto con conveyor belts
|
||||||
auto CollisionMap::checkConveyorBelts(SDL_FPoint& p) -> bool {
|
auto CollisionMap::checkConveyorBelts(const SDL_FPoint& p) -> bool {
|
||||||
return std::ranges::any_of(conveyor_belt_floors_, [&](const auto& s) {
|
return std::ranges::any_of(conveyor_belt_floors_, [&](const auto& s) {
|
||||||
return checkCollision(s, p);
|
return checkCollision(s, p);
|
||||||
});
|
});
|
||||||
@@ -178,7 +178,7 @@ auto CollisionMap::checkLeftSlopes(const LineVertical& line) -> int {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Comprueba las colisiones punto con rampas izquierdas
|
// Comprueba las colisiones punto con rampas izquierdas
|
||||||
auto CollisionMap::checkLeftSlopes(SDL_FPoint& p) -> bool {
|
auto CollisionMap::checkLeftSlopes(const SDL_FPoint& p) -> bool {
|
||||||
return std::ranges::any_of(left_slopes_, [&](const auto& slope) {
|
return std::ranges::any_of(left_slopes_, [&](const auto& slope) {
|
||||||
return checkCollision(p, slope);
|
return checkCollision(p, slope);
|
||||||
});
|
});
|
||||||
@@ -196,7 +196,7 @@ auto CollisionMap::checkRightSlopes(const LineVertical& line) -> int {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Comprueba las colisiones punto con rampas derechas
|
// Comprueba las colisiones punto con rampas derechas
|
||||||
auto CollisionMap::checkRightSlopes(SDL_FPoint& p) -> bool {
|
auto CollisionMap::checkRightSlopes(const SDL_FPoint& p) -> bool {
|
||||||
return std::ranges::any_of(right_slopes_, [&](const auto& slope) {
|
return std::ranges::any_of(right_slopes_, [&](const auto& slope) {
|
||||||
return checkCollision(p, slope);
|
return checkCollision(p, slope);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -48,21 +48,21 @@ class CollisionMap {
|
|||||||
auto getTile(int index) const -> Tile; // Devuelve el tipo de tile en un índice del tilemap
|
auto getTile(int index) const -> Tile; // Devuelve el tipo de tile en un índice del tilemap
|
||||||
|
|
||||||
// --- Queries de colisión con superficies ---
|
// --- Queries de colisión con superficies ---
|
||||||
auto checkRightSurfaces(SDL_FRect& rect) -> int; // Colisión con paredes derechas (retorna X)
|
auto checkRightSurfaces(const SDL_FRect& rect) -> int; // Colisión con paredes derechas (retorna X)
|
||||||
auto checkLeftSurfaces(SDL_FRect& rect) -> int; // Colisión con paredes izquierdas (retorna X)
|
auto checkLeftSurfaces(const SDL_FRect& rect) -> int; // Colisión con paredes izquierdas (retorna X)
|
||||||
auto checkTopSurfaces(SDL_FRect& rect) -> int; // Colisión con techos (retorna Y)
|
auto checkTopSurfaces(const SDL_FRect& rect) -> int; // Colisión con techos (retorna Y)
|
||||||
auto checkTopSurfaces(SDL_FPoint& p) -> bool; // Colisión punto con techos
|
auto checkTopSurfaces(const SDL_FPoint& p) -> bool; // Colisión punto con techos
|
||||||
auto checkBottomSurfaces(SDL_FRect& rect) -> int; // Colisión con suelos (retorna Y)
|
auto checkBottomSurfaces(const SDL_FRect& rect) -> int; // Colisión con suelos (retorna Y)
|
||||||
|
|
||||||
// --- Queries de colisión con superficies automáticas (conveyor belts) ---
|
// --- Queries de colisión con superficies automáticas (conveyor belts) ---
|
||||||
auto checkAutoSurfaces(SDL_FRect& rect) -> int; // Colisión con conveyor belts (retorna Y)
|
auto checkAutoSurfaces(const SDL_FRect& rect) -> int; // Colisión con conveyor belts (retorna Y)
|
||||||
auto checkConveyorBelts(SDL_FPoint& p) -> bool; // Colisión punto con conveyor belts
|
auto checkConveyorBelts(const SDL_FPoint& p) -> bool; // Colisión punto con conveyor belts
|
||||||
|
|
||||||
// --- Queries de colisión con rampas ---
|
// --- Queries de colisión con rampas ---
|
||||||
auto checkLeftSlopes(const LineVertical& line) -> int; // Colisión línea con rampas izquierdas (retorna Y)
|
auto checkLeftSlopes(const LineVertical& line) -> int; // Colisión línea con rampas izquierdas (retorna Y)
|
||||||
auto checkLeftSlopes(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(SDL_FPoint& p) -> bool; // Colisión punto con rampas derechas
|
auto checkRightSlopes(const SDL_FPoint& p) -> bool; // Colisión punto con rampas derechas
|
||||||
|
|
||||||
// --- 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
|
||||||
|
|||||||
@@ -192,37 +192,37 @@ auto Room::getSlopeHeight(SDL_FPoint p, Tile slope) -> int {
|
|||||||
// === Métodos de colisión (delegados a CollisionMap) ===
|
// === Métodos de colisión (delegados a CollisionMap) ===
|
||||||
|
|
||||||
// Comprueba las colisiones con paredes derechas
|
// Comprueba las colisiones con paredes derechas
|
||||||
auto Room::checkRightSurfaces(SDL_FRect& rect) -> int {
|
auto Room::checkRightSurfaces(const SDL_FRect& rect) -> int {
|
||||||
return collision_map_->checkRightSurfaces(rect);
|
return collision_map_->checkRightSurfaces(rect);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Comprueba las colisiones con paredes izquierdas
|
// Comprueba las colisiones con paredes izquierdas
|
||||||
auto Room::checkLeftSurfaces(SDL_FRect& rect) -> int {
|
auto Room::checkLeftSurfaces(const SDL_FRect& rect) -> int {
|
||||||
return collision_map_->checkLeftSurfaces(rect);
|
return collision_map_->checkLeftSurfaces(rect);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Comprueba las colisiones con techos
|
// Comprueba las colisiones con techos
|
||||||
auto Room::checkTopSurfaces(SDL_FRect& rect) -> int {
|
auto Room::checkTopSurfaces(const SDL_FRect& rect) -> int {
|
||||||
return collision_map_->checkTopSurfaces(rect);
|
return collision_map_->checkTopSurfaces(rect);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Comprueba las colisiones punto con techos
|
// Comprueba las colisiones punto con techos
|
||||||
auto Room::checkTopSurfaces(SDL_FPoint& p) -> bool {
|
auto Room::checkTopSurfaces(const SDL_FPoint& p) -> bool {
|
||||||
return collision_map_->checkTopSurfaces(p);
|
return collision_map_->checkTopSurfaces(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Comprueba las colisiones con suelos
|
// Comprueba las colisiones con suelos
|
||||||
auto Room::checkBottomSurfaces(SDL_FRect& rect) -> int {
|
auto Room::checkBottomSurfaces(const SDL_FRect& rect) -> int {
|
||||||
return collision_map_->checkBottomSurfaces(rect);
|
return collision_map_->checkBottomSurfaces(rect);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Comprueba las colisiones con conveyor belts
|
// Comprueba las colisiones con conveyor belts
|
||||||
auto Room::checkAutoSurfaces(SDL_FRect& rect) -> int {
|
auto Room::checkAutoSurfaces(const SDL_FRect& rect) -> int {
|
||||||
return collision_map_->checkAutoSurfaces(rect);
|
return collision_map_->checkAutoSurfaces(rect);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Comprueba las colisiones punto con conveyor belts
|
// Comprueba las colisiones punto con conveyor belts
|
||||||
auto Room::checkConveyorBelts(SDL_FPoint& p) -> bool {
|
auto Room::checkConveyorBelts(const SDL_FPoint& p) -> bool {
|
||||||
return collision_map_->checkConveyorBelts(p);
|
return collision_map_->checkConveyorBelts(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -232,7 +232,7 @@ auto Room::checkLeftSlopes(const LineVertical& line) -> int {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Comprueba las colisiones punto con rampas izquierdas
|
// Comprueba las colisiones punto con rampas izquierdas
|
||||||
auto Room::checkLeftSlopes(SDL_FPoint& p) -> bool {
|
auto Room::checkLeftSlopes(const SDL_FPoint& p) -> bool {
|
||||||
return collision_map_->checkLeftSlopes(p);
|
return collision_map_->checkLeftSlopes(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -242,7 +242,7 @@ auto Room::checkRightSlopes(const LineVertical& line) -> int {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Comprueba las colisiones punto con rampas derechas
|
// Comprueba las colisiones punto con rampas derechas
|
||||||
auto Room::checkRightSlopes(SDL_FPoint& p) -> bool {
|
auto Room::checkRightSlopes(const SDL_FPoint& p) -> bool {
|
||||||
return collision_map_->checkRightSlopes(p);
|
return collision_map_->checkRightSlopes(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -75,17 +75,17 @@ class Room {
|
|||||||
auto itemCollision(SDL_FRect& rect) -> bool; // Indica si hay colision con un objeto a partir de un rectangulo
|
auto itemCollision(SDL_FRect& rect) -> bool; // Indica si hay colision con un objeto a partir de un rectangulo
|
||||||
static auto getTileSize() -> int { return TILE_SIZE; } // Obten el tamaño del tile
|
static auto getTileSize() -> int { return TILE_SIZE; } // Obten el tamaño del tile
|
||||||
static auto getSlopeHeight(SDL_FPoint p, Tile slope) -> int; // Obten la coordenada de la cuesta a partir de un punto perteneciente a ese tile
|
static auto getSlopeHeight(SDL_FPoint p, Tile slope) -> int; // Obten la coordenada de la cuesta a partir de un punto perteneciente a ese tile
|
||||||
auto checkRightSurfaces(SDL_FRect& rect) -> int; // Comprueba las colisiones
|
auto checkRightSurfaces(const SDL_FRect& rect) -> int; // Comprueba las colisiones
|
||||||
auto checkLeftSurfaces(SDL_FRect& rect) -> int; // Comprueba las colisiones
|
auto checkLeftSurfaces(const SDL_FRect& rect) -> int; // Comprueba las colisiones
|
||||||
auto checkTopSurfaces(SDL_FRect& rect) -> int; // Comprueba las colisiones
|
auto checkTopSurfaces(const SDL_FRect& rect) -> int; // Comprueba las colisiones
|
||||||
auto checkBottomSurfaces(SDL_FRect& rect) -> int; // Comprueba las colisiones
|
auto checkBottomSurfaces(const SDL_FRect& rect) -> int; // Comprueba las colisiones
|
||||||
auto checkAutoSurfaces(SDL_FRect& rect) -> int; // Comprueba las colisiones
|
auto checkAutoSurfaces(const SDL_FRect& rect) -> int; // Comprueba las colisiones
|
||||||
auto checkTopSurfaces(SDL_FPoint& p) -> bool; // Comprueba las colisiones
|
auto checkTopSurfaces(const SDL_FPoint& p) -> bool; // Comprueba las colisiones
|
||||||
auto checkConveyorBelts(SDL_FPoint& p) -> bool; // Comprueba las colisiones
|
auto checkConveyorBelts(const SDL_FPoint& p) -> bool; // Comprueba las colisiones
|
||||||
auto checkLeftSlopes(const LineVertical& line) -> int; // Comprueba las colisiones
|
auto checkLeftSlopes(const LineVertical& line) -> int; // Comprueba las colisiones
|
||||||
auto checkLeftSlopes(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(SDL_FPoint& p) -> bool; // Comprueba las colisiones
|
auto checkRightSlopes(const SDL_FPoint& p) -> bool; // Comprueba las colisiones
|
||||||
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
|
||||||
|
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ enum class Options {
|
|||||||
|
|
||||||
// --- Variables de estado globales ---
|
// --- Variables de estado globales ---
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
inline Scene current = Scene::LOADING_SCREEN; // Escena actual
|
inline Scene current = Scene::GAME; // Escena actual
|
||||||
inline Options options = Options::LOGO_TO_LOADING_SCREEN; // Opciones de la escena actual
|
inline Options options = Options::LOGO_TO_LOADING_SCREEN; // Opciones de la escena actual
|
||||||
#else
|
#else
|
||||||
inline Scene current = Scene::LOGO; // Escena actual
|
inline Scene current = Scene::LOGO; // Escena actual
|
||||||
|
|||||||
@@ -47,3 +47,9 @@ namespace Collision
|
|||||||
{
|
{
|
||||||
constexpr int NONE = -1;
|
constexpr int NONE = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace Flip
|
||||||
|
{
|
||||||
|
constexpr SDL_FlipMode LEFT = SDL_FLIP_HORIZONTAL;
|
||||||
|
constexpr SDL_FlipMode RIGHT = SDL_FLIP_NONE;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user