barrallantse en la colisió en les habitacions dels costats
fix: surface no clipejava be la copia de surfaces a surfaces que eixien per la dreta amb el flip activat
This commit is contained in:
@@ -239,7 +239,7 @@ void Player::moveHorizontal(float delta_time) {
|
||||
auto [tc, ox, oy] = getCollisionContext();
|
||||
float new_x = x_ + (vx_ * delta_time);
|
||||
|
||||
// Colisión con paredes
|
||||
// Colisión con paredes (room actual)
|
||||
if (vx_ < 0.0F) {
|
||||
float wall = tc.checkWallLeft(new_x + ox, y_ + oy, WIDTH, HEIGHT);
|
||||
if (wall != Collision::NONE) {
|
||||
@@ -252,6 +252,10 @@ void Player::moveHorizontal(float delta_time) {
|
||||
}
|
||||
}
|
||||
|
||||
// Cross-room: comprobar muros en rooms adyacentes
|
||||
auto cross = getCrossRoomChecks();
|
||||
checkCrossRoomWallH(new_x, cross);
|
||||
|
||||
x_ = new_x;
|
||||
|
||||
// Si estamos en una slope, ajustar Y para seguirla
|
||||
@@ -352,6 +356,8 @@ void Player::moveVertical(float delta_time) {
|
||||
auto [tc, ox, oy] = getCollisionContext();
|
||||
float displacement = vy_ * delta_time;
|
||||
|
||||
float old_y = y_;
|
||||
|
||||
if (vy_ < 0.0F) {
|
||||
// Subiendo: comprobar techo
|
||||
float new_y = y_ + displacement;
|
||||
@@ -385,6 +391,10 @@ void Player::moveVertical(float delta_time) {
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
// Cross-room: comprobar suelo/techo en rooms adyacentes
|
||||
auto cross = getCrossRoomChecks();
|
||||
checkCrossRoomFloor(old_y, cross);
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
@@ -423,6 +433,12 @@ void Player::checkFalling() {
|
||||
transitionToState(State::ON_SLOPE);
|
||||
return;
|
||||
}
|
||||
|
||||
// Cross-room: comprobar suelo en rooms adyacentes antes de declarar caída
|
||||
if (hasCrossRoomGround(getCrossRoomChecks())) {
|
||||
return;
|
||||
}
|
||||
|
||||
vy_ = 0.0F;
|
||||
transitionToState(State::ON_AIR);
|
||||
}
|
||||
@@ -553,6 +569,109 @@ void Player::syncSpriteAndCollider() {
|
||||
collider_box_ = getRect();
|
||||
}
|
||||
|
||||
// Cross-room collision: asigna una room adyacente por índice
|
||||
void Player::setBorderRoom(int index, std::shared_ptr<Room> room) {
|
||||
if (index >= 0 && index < BORDER_ROOM_COUNT) {
|
||||
border_rooms_[index] = std::move(room);
|
||||
}
|
||||
}
|
||||
|
||||
// Cross-room collision: limpia todas las rooms adyacentes
|
||||
void Player::clearBorderRooms() {
|
||||
for (auto& r : border_rooms_) {
|
||||
r.reset();
|
||||
}
|
||||
}
|
||||
|
||||
// Cross-room: construye la lista de rooms adyacentes que solapan con la bbox del jugador
|
||||
auto Player::getCrossRoomChecks() const -> CrossRoomChecks {
|
||||
// Offsets por room: TOP, RIGHT, BOTTOM, LEFT, TR, BR, BL, TL
|
||||
static constexpr float PW = static_cast<float>(PlayArea::WIDTH);
|
||||
static constexpr float PH = static_cast<float>(PlayArea::HEIGHT);
|
||||
static constexpr struct { float ox; float oy; } OFFSETS[BORDER_ROOM_COUNT] = {
|
||||
{0, PH}, {-PW, 0}, {0, -PH}, {PW, 0}, {-PW, PH}, {-PW, -PH}, {PW, -PH}, {PW, PH}
|
||||
};
|
||||
|
||||
bool over_top = y_ < 0.0F;
|
||||
bool over_right = (x_ + WIDTH) > PlayArea::RIGHT;
|
||||
bool over_bottom = (y_ + HEIGHT) > PlayArea::BOTTOM;
|
||||
bool over_left = x_ < 0.0F;
|
||||
bool needed[BORDER_ROOM_COUNT] = {
|
||||
over_top, over_right, over_bottom, over_left,
|
||||
over_top && over_right, over_bottom && over_right,
|
||||
over_bottom && over_left, over_top && over_left
|
||||
};
|
||||
|
||||
CrossRoomChecks result;
|
||||
for (int i = 0; i < BORDER_ROOM_COUNT; ++i) {
|
||||
if (needed[i] && border_rooms_[i]) {
|
||||
result.entries[result.count++] = {&border_rooms_[i]->getTileCollider(), OFFSETS[i].ox, OFFSETS[i].oy};
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// Cross-room: comprueba muros horizontales en rooms adyacentes
|
||||
void Player::checkCrossRoomWallH(float& new_x, const CrossRoomChecks& checks) const {
|
||||
for (int i = 0; i < checks.count; ++i) {
|
||||
const auto& [tc, ox, oy] = checks.entries[i];
|
||||
if (vx_ < 0.0F) {
|
||||
float wall = tc->checkWallLeft(new_x + ox, y_ + oy, WIDTH, HEIGHT);
|
||||
if (wall != Collision::NONE) {
|
||||
float corrected = wall - ox;
|
||||
if (corrected > new_x) { new_x = corrected; }
|
||||
}
|
||||
} else if (vx_ > 0.0F) {
|
||||
float wall = tc->checkWallRight(new_x + ox, y_ + oy, WIDTH, HEIGHT);
|
||||
if (wall != Collision::NONE) {
|
||||
float corrected = wall - WIDTH - ox;
|
||||
if (corrected < new_x) { new_x = corrected; }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Cross-room: comprueba suelo/techo en rooms adyacentes (usa old_y para rango correcto de checkFloor)
|
||||
void Player::checkCrossRoomFloor(float old_y, const CrossRoomChecks& checks) {
|
||||
for (int i = 0; i < checks.count; ++i) {
|
||||
const auto& [tc, ox, oy] = checks.entries[i];
|
||||
if (vy_ < 0.0F) {
|
||||
float ceiling = tc->checkCeiling(x_ + ox, y_ + oy, WIDTH);
|
||||
if (ceiling != Collision::NONE) {
|
||||
float corrected = ceiling - oy;
|
||||
if (corrected > y_) {
|
||||
y_ = corrected;
|
||||
vy_ = 0.0F;
|
||||
}
|
||||
}
|
||||
} else if (vy_ > 0.0F) {
|
||||
float old_foot = old_y + oy + HEIGHT;
|
||||
float new_foot = y_ + oy + HEIGHT;
|
||||
auto hit = tc->checkFloor(x_ + ox, old_foot, WIDTH, new_foot);
|
||||
if (hit.y != Collision::NONE) {
|
||||
float corrected = hit.y - HEIGHT - oy;
|
||||
if (corrected < y_) {
|
||||
y_ = corrected;
|
||||
vy_ = 0.0F;
|
||||
transitionToState(State::ON_GROUND);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Cross-room: comprueba si hay suelo bajo el jugador en alguna room adyacente
|
||||
auto Player::hasCrossRoomGround(const CrossRoomChecks& checks) const -> bool {
|
||||
for (int i = 0; i < checks.count; ++i) {
|
||||
const auto& [tc, ox, oy] = checks.entries[i];
|
||||
float foot = y_ + oy + HEIGHT;
|
||||
if (tc->hasGroundBelow(x_ + ox, foot, WIDTH)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Aplica el desplazamiento de una plataforma móvil al jugador
|
||||
void Player::applyPlatformDisplacement(float dx, float surface_y) {
|
||||
y_ = surface_y - HEIGHT; // Snap vertical al top de la plataforma
|
||||
|
||||
Reference in New Issue
Block a user