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:
1 parent
e6b612d164
commit
ee8dc25181
17 files changed
+378
-66
No files matched your search
@@ -19,6 +19,7 @@
|
||||
#include "game/entities/entity_factory.hpp"
|
||||
#include "game/entities/entity_loader.hpp"
|
||||
#include "game/entities/entity_manager.hpp"
|
||||
#include "game/entities/player.hpp"
|
||||
#include "game/map/map.hpp"
|
||||
|
||||
// Render centralitzat al manager per confinar la dependència cap a
|
||||
@@ -32,26 +33,42 @@
|
||||
// surface per l'amplada del frame — així un GIF de 4 frames pot venir com
|
||||
// a 1×4, 4×1 o 2×2 indistintament. `renderAll` clipa la cel·la del frame
|
||||
// actual amb un `src_rect`. Entitats sense animació es dibuixen al frame 0.
|
||||
void EntityManager::renderEntity(const Entity& e) {
|
||||
const auto& surface = e.getSurface();
|
||||
if (surface == nullptr) { return; }
|
||||
const auto RECT = e.getPixelRect();
|
||||
const auto& anim = e.getAnimation();
|
||||
const int FRAME = anim.has_value() ? anim->currentFrame() : 0;
|
||||
const int FRAME_W = static_cast<int>(RECT.w);
|
||||
const int FRAME_H = static_cast<int>(RECT.h);
|
||||
const int COLS = (FRAME_W > 0) ? (surface->getWidth() / FRAME_W) : 1;
|
||||
const int COLS_SAFE = (COLS > 0) ? COLS : 1;
|
||||
const int COL = FRAME % COLS_SAFE;
|
||||
const int ROW = FRAME / COLS_SAFE;
|
||||
const SDL_FRect SRC{
|
||||
.x = static_cast<float>(COL * FRAME_W),
|
||||
.y = static_cast<float>(ROW * FRAME_H),
|
||||
.w = RECT.w,
|
||||
.h = RECT.h,
|
||||
};
|
||||
surface->render(static_cast<int>(RECT.x), static_cast<int>(RECT.y), &SRC);
|
||||
}
|
||||
|
||||
void EntityManager::renderAll() {
|
||||
for (const auto& e : entities_) {
|
||||
const auto& surface = e->getSurface();
|
||||
if (surface == nullptr) { continue; }
|
||||
const auto RECT = e->getPixelRect();
|
||||
const auto& anim = e->getAnimation();
|
||||
const int FRAME = anim.has_value() ? anim->currentFrame() : 0;
|
||||
const int FRAME_W = static_cast<int>(RECT.w);
|
||||
const int FRAME_H = static_cast<int>(RECT.h);
|
||||
const int COLS = (FRAME_W > 0) ? (surface->getWidth() / FRAME_W) : 1;
|
||||
const int COLS_SAFE = (COLS > 0) ? COLS : 1;
|
||||
const int COL = FRAME % COLS_SAFE;
|
||||
const int ROW = FRAME / COLS_SAFE;
|
||||
const SDL_FRect SRC{
|
||||
.x = static_cast<float>(COL * FRAME_W),
|
||||
.y = static_cast<float>(ROW * FRAME_H),
|
||||
.w = RECT.w,
|
||||
.h = RECT.h,
|
||||
};
|
||||
surface->render(static_cast<int>(RECT.x), static_cast<int>(RECT.y), &SRC);
|
||||
for (const auto& e : entities_) { renderEntity(*e); }
|
||||
}
|
||||
|
||||
void EntityManager::checkPlayerCollisions(const std::vector<Player*>& players) {
|
||||
if (players.empty()) { return; }
|
||||
for (const auto& entity : entities_) {
|
||||
if (!entity->collides()) { continue; }
|
||||
const auto BOX = entity->getCollisionRect();
|
||||
for (auto* p : players) {
|
||||
if (p == nullptr) { continue; }
|
||||
const auto PBOX = p->getBaseBox();
|
||||
const bool OVERLAP = PBOX.x + PBOX.w > BOX.x && BOX.x + BOX.w > PBOX.x && PBOX.y + PBOX.h > BOX.y && BOX.y + BOX.h > PBOX.y;
|
||||
if (OVERLAP) { entity->onPlayerContact(p); }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -209,6 +226,17 @@ namespace {
|
||||
};
|
||||
entity->setPixelRect(RENDER);
|
||||
|
||||
// La caixa de col·lisió del sarc és la lògica (48×16 inferior), no el
|
||||
// rect del sprite sencer: si un jugador passa just per damunt (pels
|
||||
// 16 px superiors del sprite, que són "alçada" sense cos), no s'ha
|
||||
// de disparar cap contacte. Offset relatiu al render rect.
|
||||
entity->setCollisionBox({
|
||||
.offset_x = 0,
|
||||
.offset_y = static_cast<int>(LOGICAL.y - RENDER.y),
|
||||
.width = static_cast<int>(LOGICAL.w),
|
||||
.height = static_cast<int>(LOGICAL.h),
|
||||
});
|
||||
|
||||
// Downcast segur: la factory ens garanteix que "sarcophagus" crea
|
||||
// un `Sarcophagus`. Usant el retorn de `release` al ctor del nou
|
||||
// `unique_ptr` evitem el lint `bugprone-unused-return-value`.
|
||||
|
||||
Reference in new issue
Block a user