feat(collisions): filtre per altura — saltar esquiva momies, roques i altres jugadors
This commit is contained in:
1 parent
7b09a076b2
commit
cd50626b88
11 files changed
+88
-1
No files matched your search
@@ -63,8 +63,15 @@ void EntityManager::checkPlayerCollisions(const std::vector<Player*>& players) {
|
||||
for (const auto& entity : entities_) {
|
||||
if (!entity->collides()) { continue; }
|
||||
const auto BOX = entity->getCollisionRect();
|
||||
const int E_HEIGHT = entity->getHeight();
|
||||
for (auto* p : players) {
|
||||
if (p == nullptr) { continue; }
|
||||
// Filtre per altura: si el jugador està en l'aire i està per
|
||||
// damunt de l'alçada del cos de l'entitat, no hi ha contacte.
|
||||
// És el mecanisme del salt per esquivar momies, roques, etc.
|
||||
// Quan height és 0 (entitat sense altura declarada), el filtre
|
||||
// no es dispara mai i la col·lisió funciona com abans.
|
||||
if (p->isAirborne() && E_HEIGHT > 0 && p->getJumpZ() > static_cast<float>(E_HEIGHT)) { continue; }
|
||||
// Contacte actor-actor amb hit-box petita: la caixa base
|
||||
// 16×16 servia per moure (xoc amb murs), però per a l'event
|
||||
// "toca una entitat" volem precisió — que la momia mate quan
|
||||
@@ -109,6 +116,18 @@ namespace {
|
||||
return info;
|
||||
}
|
||||
|
||||
// Llig `collision.height` (alçada del cos en píxels) de la plantilla.
|
||||
// 0 si no està declarada — ho usen els filtres de col·lisió per altura
|
||||
// del salt: un jugador per damunt d'aquest valor no col·lisiona amb
|
||||
// l'entitat. Per a obstacles "tipus mur" (sarc, porta) el YAML els
|
||||
// dóna un valor molt alt per fer-los infranquejables.
|
||||
auto readHeight(const fkyaml::node& tmpl) -> int {
|
||||
if (!tmpl.contains("collision")) { return 0; }
|
||||
const auto& c = tmpl["collision"];
|
||||
if (!c.contains("height")) { return 0; }
|
||||
return c["height"].get_value<int>();
|
||||
}
|
||||
|
||||
// Bloc `collision: { size: [w, h], base_size: [bw, bh]?, offset: [x, y]? }`
|
||||
// de la plantilla d'entitat.
|
||||
// - Sense `base_size` ni `offset`: la caja queda alineada a la vora
|
||||
@@ -212,6 +231,7 @@ namespace {
|
||||
if (const auto BOX = readCollisionBox(tmpl, sprite_out.width, sprite_out.height); BOX.has_value()) {
|
||||
entity->setCollisionBox(*BOX);
|
||||
}
|
||||
entity->setHeight(readHeight(tmpl));
|
||||
anchor_out = readAnchor(tmpl);
|
||||
return entity;
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user