casi acabat el Player pero -> canvi de PC

This commit is contained in:
2025-11-14 14:11:27 +01:00
parent 7f51f02d96
commit 8893e8f05b
2 changed files with 146 additions and 22 deletions

View File

@@ -29,6 +29,7 @@ Player::Player(const Data& player)
// Pinta el jugador en pantalla
void Player::render() {
sprite_->render(1, color_);
Screen::get()->getRendererSurface()->putPixel(under_right_foot_.x, under_right_foot_.y, 6);
}
// Actualiza las variables del objeto
@@ -103,17 +104,14 @@ void Player::transitionToState(State state) {
fall_sound_ctrl_.reset();
current_slope_ = nullptr;
break;
case State::ON_SLOPE: {
case State::ON_SLOPE:
std::cout << "ON_SLOPE\n";
vy_ = 0;
handleDeathByFalling();
jump_sound_ctrl_.reset();
fall_sound_ctrl_.reset();
const LineDiagonal* SLOPE_LEFT = room_->getSlopeAtPoint(under_left_foot_);
const LineDiagonal* SLOPE_RIGHT = room_->getSlopeAtPoint(under_right_foot_);
current_slope_ = SLOPE_LEFT ? SLOPE_LEFT : SLOPE_RIGHT;
updateCurrentSlope();
break;
}
case State::JUMPING:
std::cout << "JUMPING\n";
// Puede saltar desde ON_GROUND o ON_SLOPE
@@ -168,7 +166,9 @@ void Player::updateOnGround(float delta_time) {
// 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
handleShouldFall(); // Verifica si debe caer (no tiene suelo)
// NOTA: No llamamos handleShouldFall() aquí porque moveOnSlope() ya maneja
// todas las condiciones de salida de la rampa (out of bounds, transición a superficie plana)
// Verifica si el jugador quiere saltar
if (wannaJump) { transitionToState(State::JUMPING); }
@@ -225,14 +225,7 @@ void Player::moveOnGround(float delta_time) {
const int SLOPE_Y = vx_ < 0.0F ? room_->checkLeftSlopes(SIDE) : room_->checkRightSlopes(SIDE);
if (SLOPE_Y != Collision::NONE) {
// Hay rampa: sube al jugador para pegarlo a la rampa
// Esta es la nueva posición "ideal" a la que nos queremos teletransportar
const float NEW_Y = SLOPE_Y - HEIGHT;
// Solo aplicamos el "snap" si es para SUBIR (new_y < y_)
if (NEW_Y < y_) {
y_ = std::max(NEW_Y, y_ - 1.0F);
}
y_ = SLOPE_Y - HEIGHT;
transitionToState(State::ON_SLOPE);
}
}
@@ -244,9 +237,88 @@ void Player::moveOnSlope(float delta_time) {
if (vx_ == 0.0F) { return; }
// Implementar aqui el desplazamiento en x_ e y_ en funcion de la velocidad y la ecuacion de la recta
// Son LineDiagonal, de 45º. La linea esta en current_slope_ (comprobar que no sea nullptr)
// Verificar que tenemos una rampa válida
if (current_slope_ == nullptr) {
transitionToState(State::FALLING);
return;
}
// Determinar el tipo de rampa
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;
}
}
// Actualizar posición de los pies para cálculos
updateFeet();
// Seleccionar el pie apropiado según el tipo de rampa
// Left slopes (forma \) colisionan con el pie izquierdo
// Right slopes (forma /) colisionan con el pie derecho
const float FOOT_X = IS_LEFT_SLOPE ? under_left_foot_.x : under_right_foot_.x;
// Calcular la Y del pie basado en la ecuación de la rampa (45 grados)
// Left slope (\): y aumenta con x -> y = y1 + (x - x1)
// Right slope (/): y disminuye con x -> y = y1 - (x - x1)
float foot_y = 0.0F;
if (IS_LEFT_SLOPE) {
foot_y = current_slope_->y1 + (FOOT_X - current_slope_->x1);
} else {
foot_y = current_slope_->y1 - (FOOT_X - current_slope_->x1);
}
// Ajustar la posición Y del jugador (restar HEIGHT porque foot_y es la posición del pie)
y_ = foot_y - HEIGHT;
// Verificar si el pie ha salido de los límites horizontales de la rampa
// Usar min/max porque LEFT slopes tienen x1<x2 pero RIGHT slopes tienen x1>x2
const int MIN_X = std::min(current_slope_->x1, current_slope_->x2);
const int MAX_X = std::max(current_slope_->x1, current_slope_->x2);
const bool OUT_OF_BOUNDS = (FOOT_X < MIN_X) || (FOOT_X > MAX_X);
if (OUT_OF_BOUNDS) {
// Determinar si estamos saliendo por arriba o por abajo de la rampa
const bool EXITING_DOWNWARD = (FOOT_X > current_slope_->x2 && IS_LEFT_SLOPE) ||
(FOOT_X < current_slope_->x1 && !IS_LEFT_SLOPE);
if (EXITING_DOWNWARD) {
// Salida por abajo: bajar 1 pixel para ayudar detección de suelo
y_ += 1.0F;
}
// Si sale por arriba, mantener altura (ya está en foot_y - HEIGHT)
// El jugador ya no está en la rampa, limpiar referencia
current_slope_ = nullptr;
// Verificar si hay soporte debajo (suelo plano, conveyor belt, u otra slope)
if (isOnFloor()) {
// Hay soporte: transición a ON_GROUND (podría ser superficie, conveyor u otra rampa)
transitionToState(State::ON_GROUND);
} else {
// Sin soporte: empezar a caer
transitionToState(State::FALLING);
}
return;
}
// Verificar transición a superficie plana
if (isOnTopSurface()) {
transitionToState(State::ON_GROUND);
return;
@@ -509,15 +581,65 @@ auto Player::isOnConveyorBelt() -> bool {
}
// Comprueba si el jugador está sobre una rampa
// Retorna true SOLO si un pie está en rampa Y el otro pie está volando (sin soporte)
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_);
// Verificar qué pie está en qué tipo de rampa
const bool LEFT_FOOT_ON_LEFT_SLOPE = room_->checkLeftSlopes(under_left_foot_);
const bool RIGHT_FOOT_ON_RIGHT_SLOPE = room_->checkRightSlopes(under_right_foot_);
return on_slope;
// Verificar si cada pie está "volando" (sin soporte: ni top surface ni conveyor belt)
const bool LEFT_FOOT_FLYING = !(room_->checkTopSurfaces(under_left_foot_) ||
room_->checkConveyorBelts(under_left_foot_));
const bool RIGHT_FOOT_FLYING = !(room_->checkTopSurfaces(under_right_foot_) ||
room_->checkConveyorBelts(under_right_foot_));
// Retornar true si UN pie en rampa Y el OTRO volando
return (LEFT_FOOT_ON_LEFT_SLOPE && RIGHT_FOOT_FLYING) ||
(RIGHT_FOOT_ON_RIGHT_SLOPE && LEFT_FOOT_FLYING);
}
// Comprueba si current_slope_ es una rampa izquierda (ascendente a la izquierda)
// Las rampas izquierdas tienen forma \ con x1 < x2 (x aumenta de izq a der)
auto Player::isLeftSlope() -> bool {
if (current_slope_ == nullptr) {
return false;
}
// Left slopes (\): x1 < x2 (x aumenta de izquierda a derecha)
// Right slopes (/): x1 > x2 (x decrece de izquierda a derecha)
return current_slope_->x1 < current_slope_->x2;
}
// Actualiza current_slope_ con la rampa correcta según el pie que toca
void Player::updateCurrentSlope() {
updateFeet();
// Left slopes (\) ascendentes a izquierda tocan el pie izquierdo
if (room_->checkLeftSlopes(under_left_foot_)) {
current_slope_ = room_->getSlopeAtPoint(under_left_foot_);
}
// Right slopes (/) ascendentes a derecha tocan el pie derecho
else if (room_->checkRightSlopes(under_right_foot_)) {
current_slope_ = room_->getSlopeAtPoint(under_right_foot_);
}
// Fallback para casos edge
else {
current_slope_ = room_->getSlopeAtPoint(under_left_foot_);
if (current_slope_ == nullptr) {
current_slope_ = room_->getSlopeAtPoint(under_right_foot_);
}
}
// Debug output
if (current_slope_ != nullptr) {
const char* TYPE = isLeftSlope() ? "Left \\" : "Right /";
std::cout << "[SLOPE] " << TYPE
<< " from (" << current_slope_->x1 << "," << current_slope_->y1 << ")"
<< " to (" << current_slope_->x2 << "," << current_slope_->y2 << ")\n";
} else {
std::cout << "[SLOPE] nullptr\n";
}
}
// Comprueba que el jugador no toque ningun tile de los que matan

View File

@@ -189,6 +189,8 @@ class Player {
auto isOnTopSurface() -> bool; // Comprueba si el jugador está sobre una superficie
auto isOnConveyorBelt() -> bool; // Comprueba si el jugador esta sobre una cinta transportadora
auto isOnSlope() -> bool; // Comprueba si el jugador está sobre una rampa
auto isLeftSlope() -> bool; // Comprueba si current_slope_ es una rampa izquierda (ascendente a la izquierda)
void updateCurrentSlope(); // Actualiza current_slope_ con la rampa correcta y muestra debug info
// --- Funciones de actualización de geometría ---
void syncSpriteAndCollider(); // Actualiza collider_box y collision points