refactor tile_collider: extreu floorYForTile i elimina NOLINT obsolet a checkSlopeBelow

This commit is contained in:
2026-05-17 22:06:13 +02:00
parent cbd7f17978
commit d99902b9be
2 changed files with 33 additions and 35 deletions
+30 -35
View File
@@ -98,46 +98,41 @@ auto TileCollider::checkCeiling(float x, float y, float w) const -> float {
// WALL: bloquea si los pies estaban por encima (como PASSABLE).
// PASSABLE: solo si los pies estaban por encima del borde superior del tile.
// SLOPE: siempre bloquea (las slopes son sólidas, como muros en diagonal).
// NOLINTNEXTLINE(readability-function-cognitive-complexity)
// Calcula la y del suelo per a un tile concret. Retorna Collision::NONE si el tile
// no actua com a suelo en aquest cas (segons el tipus i el rang del moviment).
auto TileCollider::floorYForTile(Tile tile, int col, int row, float x, float w, float foot_y_current, float foot_y_new) const -> float {
if (tile == Tile::WALL || tile == Tile::PASSABLE) {
const float TILE_TOP = toPixel(row);
// WALL/PASSABLE només compten si els peus estaven per damunt abans del moviment
return (foot_y_current <= TILE_TOP) ? TILE_TOP : Collision::NONE;
}
if (tile == Tile::SLOPE_L || tile == Tile::SLOPE_R) {
const float CHECK_X = (tile == Tile::SLOPE_L) ? x : x + w - 1;
const float SLOPE_Y = getSlopeY(col, row, CHECK_X);
// Slopes són sòlides: aterrar sempre que els peus arriben a la superfície
return (foot_y_new >= SLOPE_Y) ? SLOPE_Y : Collision::NONE;
}
return Collision::NONE;
}
auto TileCollider::checkFloor(float x, float foot_y_current, float w, float foot_y_new) const -> FloorHit {
int start_row = toTile(static_cast<int>(foot_y_current));
int end_row = toTile(static_cast<int>(foot_y_new));
int left_col = toTile(static_cast<int>(x));
int right_col = toTile(static_cast<int>(x + w - 1));
const int START_ROW = toTile(static_cast<int>(foot_y_current));
const int END_ROW = toTile(static_cast<int>(foot_y_new));
const int LEFT_COL = toTile(static_cast<int>(x));
const int RIGHT_COL = toTile(static_cast<int>(x + w - 1));
FloorHit best;
for (int row = start_row; row <= end_row; ++row) {
for (int col = left_col; col <= right_col; ++col) {
auto tile = getTileAt(col, row);
float floor_y = Collision::NONE;
if (tile == Tile::WALL) {
float tile_top = toPixel(row);
if (foot_y_current <= tile_top) {
floor_y = tile_top;
}
} else if (tile == Tile::PASSABLE) {
float tile_top = toPixel(row);
// Solo cuenta como suelo si los pies estaban por encima antes del movimiento
if (foot_y_current <= tile_top) {
floor_y = tile_top;
}
} else if (tile == Tile::SLOPE_L || tile == Tile::SLOPE_R) {
float check_x = (tile == Tile::SLOPE_L) ? x : x + w - 1;
float slope_y = getSlopeY(col, row, check_x);
// Slopes son sólidas: aterrizar siempre que los pies lleguen a la superficie
if (foot_y_new >= slope_y) {
floor_y = slope_y;
}
}
if (floor_y != Collision::NONE && (best.y == Collision::NONE || floor_y < best.y)) {
best = {.y = floor_y, .type = tile, .tile_x = col, .tile_y = row};
for (int row = START_ROW; row <= END_ROW; ++row) {
for (int col = LEFT_COL; col <= RIGHT_COL; ++col) {
const auto TILE = getTileAt(col, row);
const float FLOOR_Y = floorYForTile(TILE, col, row, x, w, foot_y_current, foot_y_new);
if (FLOOR_Y == Collision::NONE) { continue; }
if (best.y == Collision::NONE || FLOOR_Y < best.y) {
best = {.y = FLOOR_Y, .type = TILE, .tile_x = col, .tile_y = row};
}
}
}
return best;
}
@@ -196,7 +191,7 @@ auto TileCollider::isInsideAnySlope(float x, float foot_y, float w) const -> boo
// Busca una slope directamente debajo del jugador (para transición ground→slope).
// Escanea la fila de los pies Y la fila superior: las slopes en escalera siempre
// tienen el tile de entrada una fila arriba del suelo desde el que se accede.
// NOLINTNEXTLINE(readability-function-cognitive-complexity)
auto TileCollider::checkSlopeBelow(float x, float foot_y, float w) const -> SlopeInfo {
int foot_row = toTile(static_cast<int>(foot_y));
int left_col = toTile(static_cast<int>(x));
+3
View File
@@ -70,4 +70,7 @@ class TileCollider {
int border_px_; // Offset en píxeles (CollisionBorder::PX)
const std::vector<int>& tile_map_;
// Calcula la y del suelo per a un tile concret (helper de checkFloor)
[[nodiscard]] auto floorYForTile(Tile tile, int col, int row, float x, float w, float foot_y_current, float foot_y_new) const -> float;
};