feat(entities): fase 4 - moviment de la momia amb col·lisió, z-order per peus i contacte amb el jugador

This commit is contained in:
JailDesigner committed 2026-04-21 20:14:47 +02:00
1 parent e6b612d164
commit ee8dc25181
17 files changed
+378 -66

No files matched your search

+50
View File
@@ -18,6 +18,8 @@
// retornada coincideix amb les dimensions del bloc
// `collision:` del YAML; sense caixa, coincideix amb el
// sprite sencer (pixel_rect).
// T13 mummy step — camina en línia recta pel playfield i gira en topar
// un mur (insidePlayfield=false) o sarc (Map::collides).
//
// Execució (des de la ruta del repo):
// make build && cd build && ctest --output-on-failure
@@ -376,6 +378,53 @@ namespace {
REQUIRE(static_cast<int>(mummy.getFeetY()) == 224);
}
void testMummyStep() {
std::cout << "[T13] momia step amb col·lisió i gir\n";
// Cal Map::loadFrom (T9 ja el carrega, però el rerrumigo ací per
// aïllar la intenció del test).
Map::loadFrom("data/maps/pyramid.yaml");
// Momia al corredor exterior superior: playfield_y=48, alçada del
// corredor exterior = outer_corridor (16). Així el base box 12×12
// queda a y∈[52, 64] aprox. Collision box: offset_y=12 (sprite
// 12×24 amb peus 12×12 a baix). pixel_rect.x/y triat perquè els
// peus quedin al tile centrat (4, 3) del tilemap → peus a
// (col*16-8, row*16+0) i alineats bottom del tile.
fkyaml::node tmpl = EntityLoader::loadTemplate("mummy");
Mummy mummy(tmpl);
mummy.setCollisionBox({.offset_x = 0, .offset_y = 12, .width = 12, .height = 12});
// Posem els peus ben dins d'un corredor horitzontal lliure. El
// corredor superior exterior va de y=48 a y=64 (alçada 16). Amb
// collision_y=12, sprite 12×24 → pixel_rect.y perquè feetY=64.
// feetY = pixel_rect.y + offset_y + h = pixel_rect.y + 24 → pixel_rect.y = 40.
// X: fora d'un sarc; (x=60) és al corredor extern abans dels sarcs.
mummy.setPixelRect({.x = 60.0F, .y = 40.0F, .w = 12.0F, .h = 24.0F});
const auto BEFORE = mummy.getPixelRect();
// Velocitat llegida del YAML és 40 px/s. A 0.1s hauria d'avançar
// 4 px en X (direcció inicial right=+1,0). Com que està en un
// corredor lliure, el step s'aplica.
mummy.step(0.1F);
const auto AFTER = mummy.getPixelRect();
REQUIRE(AFTER.x > BEFORE.x);
REQUIRE(AFTER.y == BEFORE.y);
// Posem la momia contra la paret dreta del playfield: avançar un
// frame la trauria fora → el step ha de girar. No assumim cap nova
// direcció concreta (perpendiculars lliures poden ser vàlides); el
// contracte és "ja no continua cap a la dreta".
const float RIGHT_WALL = static_cast<float>(Map::playfield_x + Map::playfield_w);
mummy.setPixelRect({.x = RIGHT_WALL - 12.0F, .y = 40.0F, .w = 12.0F, .h = 24.0F});
const auto POS_BEFORE = mummy.getPixelRect();
mummy.step(0.1F);
const auto POS_AFTER = mummy.getPixelRect();
// No ha avançat cap a la dreta en el frame de gir.
REQUIRE(POS_AFTER.x == POS_BEFORE.x);
REQUIRE(POS_AFTER.y == POS_BEFORE.y);
// I ja no apunta cap a la dreta (ha triat perpendicular o U-turn).
REQUIRE(mummy.getDirX() <= 0.0F);
}
void testTorchAnimation() {
std::cout << "[T10] torch animation wired from yaml\n";
// Regressió: el torch.yaml declarava `frames: [0]` i el render no
@@ -414,6 +463,7 @@ auto main() -> int {
testLoadFromLevel();
testSarcophagusYaml();
testCollisionBox();
testMummyStep();
testTorchAnimation();
if (g_failures == 0) {