DUP-02: snapToHorizontalLane/VerticalLane unificats en snapToLane
Les dues funcions compartien l'algorisme complet — només canvien l'eix actiu (getPosY/setPosY vs getPosX/setPosX) i els paràmetres del Map. `snapToLane` pren base, pitch, max_idx i dos member-fn pointers i és cridat pels dos wrappers amb els valors corresponents.
This commit is contained in:
1 parent
53bf3a1ff2
commit
206ba07a6f
3 files changed
+43
-33
No files matched your search
+1
-1
@@ -31,7 +31,7 @@ Els IDs es mantenen estables una vegada assignats. Cada entrada apunta al fitxer
|
|||||||
| ID | Fitxer:línia | Troballa | Severitat | Estat | Notes |
|
| ID | Fitxer:línia | Troballa | Severitat | Estat | Notes |
|
||||||
|----|--------------|----------|-----------|-------|-------|
|
|----|--------------|----------|-----------|-------|-------|
|
||||||
| DUP-01 | `options.cpp:152-335,443-547` | PostFX i CrtPi tenen `default*Presets/parse*Preset/write*Preset/load*FromFile/save*ToFile/set*File` duplicats | Importante | DONE | Afegits `loadPresetsFromFile<T>` i `savePresetsToFile<T>` a l'anonymous namespace; els 4 entry-points passen a ser one-liners que injecten parse/write/defaults per tipus. Els fitxers `postfx.yaml`/`crtpi.yaml` regenerats són idèntics a l'anterior. `std::cerr` manté el comportament — INCONS-02 el corregirà |
|
| DUP-01 | `options.cpp:152-335,443-547` | PostFX i CrtPi tenen `default*Presets/parse*Preset/write*Preset/load*FromFile/save*ToFile/set*File` duplicats | Importante | DONE | Afegits `loadPresetsFromFile<T>` i `savePresetsToFile<T>` a l'anonymous namespace; els 4 entry-points passen a ser one-liners que injecten parse/write/defaults per tipus. Els fitxers `postfx.yaml`/`crtpi.yaml` regenerats són idèntics a l'anterior. `std::cerr` manté el comportament — INCONS-02 el corregirà |
|
||||||
| DUP-02 | `player.cpp:100-140` | `snapToHorizontalLane` i `snapToVerticalLane` són el mateix algorisme amb eixos permutats | Importante | PENDING | Unificar en `snapToLane(Axis, delta_time)` |
|
| DUP-02 | `player.cpp:100-140` | `snapToHorizontalLane` i `snapToVerticalLane` són el mateix algorisme amb eixos permutats | Importante | DONE | `snapToLane(dt, base, pitch, max_idx, get_pos, set_pos)` pren member-fn pointers; els dos wrappers deleguen només amb `Map::pitch_*`/`grid_*` distints |
|
||||||
| DUP-03 | `options.cpp:14-62` | Tres parelles `enumToString`/`enumFromString` amb la mateixa forma | Menor | PENDING | Taula `constexpr` + helpers genèrics |
|
| DUP-03 | `options.cpp:14-62` | Tres parelles `enumToString`/`enumFromString` amb la mateixa forma | Menor | PENDING | Taula `constexpr` + helpers genèrics |
|
||||||
| DUP-04 | `options.cpp:79-149` | Cada `parse*` repeteix `if (node.contains) { ... get_value<T> }` | Menor | PENDING | Helper `readField<T>(node, key, dst)` |
|
| DUP-04 | `options.cpp:79-149` | Cada `parse*` repeteix `if (node.contains) { ... get_value<T> }` | Menor | PENDING | Helper `readField<T>(node, key, dst)` |
|
||||||
| DUP-05 | `player.cpp:81-88` | Càlcul `MIN_/MAX_` + `clamp` per eix és la mateixa fórmula que el snap | Menor | PENDING | Fold en helper |
|
| DUP-05 | `player.cpp:81-88` | Càlcul `MIN_/MAX_` + `clamp` per eix és la mateixa fórmula que el snap | Menor | PENDING | Fold en helper |
|
||||||
|
|||||||
@@ -126,44 +126,46 @@ auto Player::baseBox() const -> SDL_FRect {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
void Player::snapToHorizontalLane(float delta_time) {
|
void Player::snapToLane(
|
||||||
// Lanes en posY: base + i·pitch_y per a i ∈ [0, grid_rows]. Correspon a
|
float delta_time,
|
||||||
// la caixa de col·lisió ocupant exactament un passadís horitzontal.
|
float base,
|
||||||
const auto BASE = static_cast<float>(Map::playfield_y - collision_y_offset);
|
float pitch,
|
||||||
const auto PITCH = static_cast<float>(Map::pitch_y);
|
int max_idx,
|
||||||
|
float (Player::*get_pos)() const,
|
||||||
|
void (Player::*set_pos)(float)) {
|
||||||
|
// Lanes en pos_axis: base + i·pitch per a i ∈ [0, max_idx]. Correspon a
|
||||||
|
// la caixa de col·lisió ocupant exactament un passadís perpendicular.
|
||||||
const auto THRESHOLD = static_cast<float>(collision_size) / 2.0F;
|
const auto THRESHOLD = static_cast<float>(collision_size) / 2.0F;
|
||||||
|
|
||||||
const auto IDX = std::clamp(
|
const auto IDX = std::clamp(
|
||||||
static_cast<int>(std::round((getPosY() - BASE) / PITCH)),
|
static_cast<int>(std::round(((this->*get_pos)() - base) / pitch)),
|
||||||
0,
|
0,
|
||||||
Map::grid_rows);
|
max_idx);
|
||||||
const float LANE = BASE + (static_cast<float>(IDX) * PITCH);
|
const float LANE = base + (static_cast<float>(IDX) * pitch);
|
||||||
const float DY = LANE - getPosY();
|
const float DELTA = LANE - (this->*get_pos)();
|
||||||
|
|
||||||
if (std::abs(DY) > 0.0F && std::abs(DY) <= THRESHOLD) {
|
if (std::abs(DELTA) > 0.0F && std::abs(DELTA) <= THRESHOLD) {
|
||||||
const float STEP = std::min(std::abs(DY), SPEED_PX_PER_S * delta_time);
|
const float STEP = std::min(std::abs(DELTA), SPEED_PX_PER_S * delta_time);
|
||||||
const float SAVED = getPosY();
|
const float SAVED = (this->*get_pos)();
|
||||||
setPosY(getPosY() + std::copysign(STEP, DY));
|
(this->*set_pos)(SAVED + std::copysign(STEP, DELTA));
|
||||||
if (Map::collides(baseBox())) { setPosY(SAVED); }
|
if (Map::collides(baseBox())) { (this->*set_pos)(SAVED); }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Player::snapToHorizontalLane(float delta_time) {
|
||||||
|
snapToLane(delta_time,
|
||||||
|
static_cast<float>(Map::playfield_y - collision_y_offset),
|
||||||
|
static_cast<float>(Map::pitch_y),
|
||||||
|
Map::grid_rows,
|
||||||
|
&Player::getPosY,
|
||||||
|
&Player::setPosY);
|
||||||
|
}
|
||||||
|
|
||||||
void Player::snapToVerticalLane(float delta_time) {
|
void Player::snapToVerticalLane(float delta_time) {
|
||||||
const auto BASE = static_cast<float>(Map::playfield_x - collision_x_offset);
|
snapToLane(delta_time,
|
||||||
const auto PITCH = static_cast<float>(Map::pitch_x);
|
static_cast<float>(Map::playfield_x - collision_x_offset),
|
||||||
const auto THRESHOLD = static_cast<float>(collision_size) / 2.0F;
|
static_cast<float>(Map::pitch_x),
|
||||||
|
Map::grid_cols,
|
||||||
const auto IDX = std::clamp(
|
&Player::getPosX,
|
||||||
static_cast<int>(std::round((getPosX() - BASE) / PITCH)),
|
&Player::setPosX);
|
||||||
0,
|
|
||||||
Map::grid_cols);
|
|
||||||
const float LANE = BASE + (static_cast<float>(IDX) * PITCH);
|
|
||||||
const float DX = LANE - getPosX();
|
|
||||||
|
|
||||||
if (std::abs(DX) > 0.0F && std::abs(DX) <= THRESHOLD) {
|
|
||||||
const float STEP = std::min(std::abs(DX), SPEED_PX_PER_S * delta_time);
|
|
||||||
const float SAVED = getPosX();
|
|
||||||
setPosX(getPosX() + std::copysign(STEP, DX));
|
|
||||||
if (Map::collides(baseBox())) { setPosX(SAVED); }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -55,9 +55,17 @@ class Player : public AnimatedSprite {
|
|||||||
// Snap cap al passadís perpendicular a la direcció premuda. Si la caixa
|
// Snap cap al passadís perpendicular a la direcció premuda. Si la caixa
|
||||||
// de col·lisió està a ≤ collision_size/2 d'una lane, s'hi aproxima
|
// de col·lisió està a ≤ collision_size/2 d'una lane, s'hi aproxima
|
||||||
// gradualment (a velocitat de moviment). Permet canviar de direcció
|
// gradualment (a velocitat de moviment). Permet canviar de direcció
|
||||||
// sense haver d'alinear-se píxel-perfect en l'encreuament.
|
// sense haver d'alinear-se píxel-perfect en l'encreuament. Els dos
|
||||||
|
// wrappers deleguen a `snapToLane` només canviant l'eix actiu.
|
||||||
void snapToHorizontalLane(float delta_time);
|
void snapToHorizontalLane(float delta_time);
|
||||||
void snapToVerticalLane(float delta_time);
|
void snapToVerticalLane(float delta_time);
|
||||||
|
void snapToLane(
|
||||||
|
float delta_time,
|
||||||
|
float base,
|
||||||
|
float pitch,
|
||||||
|
int max_idx,
|
||||||
|
float (Player::*get_pos)() const,
|
||||||
|
void (Player::*set_pos)(float));
|
||||||
|
|
||||||
Controls controls_;
|
Controls controls_;
|
||||||
};
|
};
|
||||||
Reference in new issue
Block a user