treballant en Player

This commit is contained in:
2025-11-14 10:42:30 +01:00
parent b8dd6e80d9
commit 29e0daffb0
9 changed files with 348 additions and 368 deletions

View File

@@ -49,24 +49,14 @@ void Player::handleInput() {
} else if (Input::get()->checkAction(InputAction::RIGHT)) {
wannaGo = Direction::RIGHT;
} else {
wannaGo = Direction::STAY;
wannaGo = Direction::NONE;
}
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) {
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_) {
case State::ON_GROUND:
moveOnGround(delta_time);
@@ -81,45 +71,11 @@ void Player::move(float delta_time) {
moveFalling(delta_time);
break;
}
}
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);
}
syncSpriteAndCollider(); // Actualiza la posición del sprite y las colisiones
}
void Player::handleConveyorBelts() {
if (!auto_movement_ and isOnConveyorBelt() and wannaGo == Direction::STAY) {
if (!auto_movement_ and isOnConveyorBelt() and wannaGo == Direction::NONE) {
auto_movement_ = true;
}
@@ -129,7 +85,6 @@ void Player::handleConveyorBelts() {
}
void Player::handleShouldFall() {
// TODO: También verificar ON_SLOPE
if (!isOnFloor() and (state_ == State::ON_GROUND || state_ == State::ON_SLOPE)) {
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
void Player::updateOnGround(float delta_time) {
(void)delta_time; // No usado en este método, pero se mantiene por consistencia
// Gestiona las cintas transportadoras
handleConveyorBelts();
// Verifica si debe caer (no tiene suelo)
handleShouldFall();
(void)delta_time; // No usado en este método, pero se mantiene por consistencia
handleConveyorBelts(); // Gestiona las cintas transportadoras
handleShouldFall(); // Verifica si debe caer (no tiene suelo)
// Verifica si el jugador quiere saltar
if (wannaJump) {
transitionToState(State::JUMPING);
}
if (wannaJump) { transitionToState(State::JUMPING); }
}
// Actualización lógica del estado ON_SLOPE
void Player::updateOnSlope(float delta_time) {
(void)delta_time; // No usado en este método, pero se mantiene por consistencia
// Verifica si debe caer (no tiene suelo)
handleShouldFall();
(void)delta_time; // No usado en este método, pero se mantiene por consistencia
handleShouldFall(); // Verifica si debe caer (no tiene suelo)
// Verifica si el jugador quiere saltar
if (wannaJump) {
transitionToState(State::JUMPING);
}
if (wannaJump) { transitionToState(State::JUMPING); }
}
// Actualización lógica del estado JUMPING
void Player::updateJumping(float delta_time) {
// Desactiva el movimiento automático durante el salto
auto_movement_ = false;
// Reproduce los sonidos de salto
playJumpSound(delta_time);
// Verifica si el salto ha terminado (alcanzó la altura inicial)
handleJumpEnd();
auto_movement_ = false; // Desactiva el movimiento automático durante el salto
playJumpSound(delta_time); // Reproduce los sonidos de salto
handleJumpEnd(); // Verifica si el salto ha terminado (alcanzó la altura inicial)
}
// Actualización lógica del estado FALLING
void Player::updateFalling(float delta_time) {
// Desactiva el movimiento automático durante la caída
auto_movement_ = false;
// Reproduce los sonidos de caída
playFallSound(delta_time);
auto_movement_ = false; // Desactiva el movimiento automático durante la caída
playFallSound(delta_time); // Reproduce los sonidos de caída
}
// ============================================================================
// NUEVO PARADIGMA: Métodos de movimiento por estado
// ============================================================================
// Movimiento físico del estado ON_GROUND
void Player::moveOnGround(float delta_time) {
// Movimiento horizontal en suelo plano (migrado de handleHorizontalMovement)
handleHorizontalMovement(delta_time);
// Determinama cuál debe ser la velocidad a partir de automovement o de wannaGo
updateVelocity();
// Actualiza geometría de colisión
updateColliderGeometry();
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 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
void Player::moveOnSlope(float delta_time) {
// Movimiento horizontal en rampa (migrado de handleHorizontalMovement)
// handleSlopeMovement() ya se llama desde dentro de moveHorizontal()
handleHorizontalMovement(delta_time);
// Determinama cuál debe ser la velocidad a partir de automovement o de wannaGo
updateVelocity();
// Actualiza geometría de colisión
updateColliderGeometry();
if (vx_ == 0.0F) { return; }
// 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
void Player::moveJumping(float delta_time) {
// Movimiento horizontal (migrado de handleHorizontalMovement)
handleHorizontalMovement(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);
// Movimiento vertical (migrado de handleVerticalMovement)
handleVerticalMovement(delta_time);
// Comprueba la colisión con las superficies
const int POS = DIRECTION == Direction::LEFT ? room_->checkRightSurfaces(PROJECTION) : room_->checkLeftSurfaces(PROJECTION);
// Actualiza geometría de colisión
updateColliderGeometry();
// 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
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
void Player::moveFalling(float delta_time) {
// Movimiento vertical (migrado de handleVerticalMovement)
handleVerticalMovement(delta_time);
// Crea el rectangulo de proyección en el eje Y para ver si colisiona
const float DISPLACEMENT = vy_ * delta_time;
const SDL_FRect PROJECTION = getProjection(Direction::DOWN, DISPLACEMENT);
// Actualiza geometría de colisión
updateColliderGeometry();
// 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 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
void Player::animate(float delta_time) {
if (vx_ != 0) {
@@ -595,25 +498,38 @@ void Player::playFallSound(float delta_time) {
// Comprueba si el jugador tiene suelo debajo de los pies
auto Player::isOnFloor() -> bool {
bool on_floor = false;
bool on_top_surface = false;
bool on_conveyor_belt = false;
updateFeet();
// Comprueba las superficies
on_floor |= room_->checkTopSurfaces(under_left_foot_);
on_floor |= room_->checkTopSurfaces(under_right_foot_);
on_top_surface |= room_->checkTopSurfaces(under_left_foot_);
on_top_surface |= room_->checkTopSurfaces(under_right_foot_);
// Comprueba las cintas transportadoras
on_floor |= room_->checkConveyorBelts(under_left_foot_);
on_floor |= room_->checkConveyorBelts(under_right_foot_);
on_conveyor_belt |= room_->checkConveyorBelts(under_left_foot_);
on_conveyor_belt |= room_->checkConveyorBelts(under_right_foot_);
// Comprueba las rampas
auto on_slope_l = room_->checkLeftSlopes(under_left_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 {
bool on_conveyor_belt = false;
updateFeet();
@@ -644,6 +560,18 @@ auto Player::isOnDownSlope() -> bool {
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
auto Player::handleKillingTiles() -> bool {
// 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");
}
// Actualiza collider_box y collision points
void Player::updateColliderGeometry() {
// Actualiza la posición del sprite y las colisiones
void Player::syncSpriteAndCollider() {
placeSprite(); // Coloca el sprite en la posición del jugador
collider_box_ = getRect(); // Actualiza el rectangulo de colisión
updateColliderPoints(); // Actualiza los puntos de colisión
@@ -831,20 +759,66 @@ void Player::updateVelocity() {
if (auto_movement_) {
// La cinta transportadora tiene el control
vx_ = HORIZONTAL_VELOCITY * room_->getConveyorBeltDirection();
sprite_->setFlip(vx_ < 0.0F ? Flip::LEFT : Flip::RIGHT);
} else {
// El jugador tiene el control
switch (wannaGo) {
case Direction::LEFT:
vx_ = -HORIZONTAL_VELOCITY;
sprite_->setFlip(Flip::LEFT);
break;
case Direction::RIGHT:
vx_ = HORIZONTAL_VELOCITY;
sprite_->setFlip(Flip::RIGHT);
break;
case Direction::STAY:
case Direction::NONE:
vx_ = 0.0F;
break;
default:
vx_ = 0.0F;
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};
}
}