feat(entities): afegeix stone i column com a muros decoratius
This commit is contained in:
1 parent
1c49248b72
commit
6749780356
18 files changed
+448
-36
No files matched your search
@@ -395,6 +395,17 @@ namespace {
|
||||
}
|
||||
entity->setPixelRect({.x = rect_x, .y = rect_y, .w = sprite.width, .h = sprite.height});
|
||||
|
||||
// Variant del atlas: el spawn pot fixar un sub-sprite estàtic via
|
||||
// `frame: N`. El render del manager ja sap clipar (col, row) a
|
||||
// partir d'un índex lineal i la mida del frame; ací només cal
|
||||
// muntar un `AnimationComponent` d'un sol frame i imposar-lo a la
|
||||
// entitat. Cap entitat existent al joc emet aquest camp; només
|
||||
// els muros decoratius amb variants (stone, column, ...) l'usen.
|
||||
if (spawn.contains("frame")) {
|
||||
const int FRAME = spawn["frame"].get_value<int>();
|
||||
entity->setAnimation(AnimationComponent({FRAME}, 1.0F, false));
|
||||
}
|
||||
|
||||
manager.add(std::move(entity));
|
||||
return true;
|
||||
}
|
||||
@@ -459,31 +470,45 @@ void EntityManager::loadFromLevel(const std::string& level_yaml_path) {
|
||||
if (addSpawn(spawn) != nullptr) { ++loaded; }
|
||||
}
|
||||
|
||||
// Broadcast inicial: marca com a "pintats" tots els tiles ocupats per
|
||||
// decals de sòl (Hole, i futurs pinchos plans, plaques, charcos...).
|
||||
// Imprescindible perquè el jugador no pot trepitjar aquests tiles
|
||||
// (cauria al forat) i els sarcòfags vecins no podrien completar el
|
||||
// perímetre — la sala seria incompletable. Usa el canal semàntic
|
||||
// `tile_painted` (lògica de joc), no `on_tile_entered` (presència
|
||||
// física del jugador). Ho fem aquí, després del bucle de spawns,
|
||||
// perquè tots els sarcòfags ja estan registrats al fan-out (la
|
||||
// subscripció del manager és al ctor, anterior a qualsevol load).
|
||||
// Broadcast inicial: marca com a "pintats" tots els tiles que el
|
||||
// jugador no pot trepitjar mai, de manera que el perímetre dels
|
||||
// sarcòfags vecins ja els consideri visitats i la sala sigui
|
||||
// completable. Inclou dues famílies:
|
||||
// - Decals de sòl (Hole, i futurs pinchos plans, plaques, charcos):
|
||||
// trigger-on-overlap que mataria/atraparia al jugador en trepitjar.
|
||||
// - Entitats sòlides genèriques (debris, columnes...): obstacles
|
||||
// físics que `Map::collides` bloqueja, així `isPaintable` retorna
|
||||
// false per als seus tiles i ningú els pot pintar.
|
||||
// Usa el canal semàntic `tile_painted` (lògica de joc), no
|
||||
// `on_tile_entered` (presència física). Es fa aquí, després del bucle
|
||||
// de spawns, perquè tots els sarcòfags ja estan registrats al fan-out
|
||||
// (la subscripció del manager és al ctor, anterior a qualsevol load).
|
||||
int decal_broadcast = 0;
|
||||
// Els decals de sòl (Hole, futurs pinchos plans...) són StaticHazards;
|
||||
// iterem tot `entities_` i el filtre per `isFloorDecal()` els tria.
|
||||
for (const auto& entity : entities_) {
|
||||
if (!entity->isFloorDecal()) { continue; }
|
||||
const bool IS_DECAL = entity->isFloorDecal();
|
||||
const bool IS_SOLID = entity->blocksMovement();
|
||||
if (!IS_DECAL && !IS_SOLID) { continue; }
|
||||
const auto BOX = entity->getCollisionRect();
|
||||
const auto [COL, ROW] = Map::pixelToTile(BOX.x, BOX.y);
|
||||
bus_.publish(Event{
|
||||
.name = "tile_painted",
|
||||
.payload = TilePos{.col = COL, .row = ROW},
|
||||
.player_id = -1,
|
||||
});
|
||||
++decal_broadcast;
|
||||
// Per a entitats que ocupen més d'un tile (futurs murs 32×16,
|
||||
// 16×32, etc.), iterem tota la zona coberta pel rect. Per a decals
|
||||
// i blocs d'un sol tile cau a un sol broadcast (mateix comportament
|
||||
// que abans).
|
||||
const auto [COL0, ROW0] = Map::pixelToTile(BOX.x, BOX.y);
|
||||
const int COLS = (Map::tile_size > 0) ? std::max(1, static_cast<int>(BOX.w) / Map::tile_size) : 1;
|
||||
const int ROWS = (Map::tile_size > 0) ? std::max(1, static_cast<int>(BOX.h) / Map::tile_size) : 1;
|
||||
for (int dr = 0; dr < ROWS; ++dr) {
|
||||
for (int dc = 0; dc < COLS; ++dc) {
|
||||
bus_.publish(Event{
|
||||
.name = "tile_painted",
|
||||
.payload = TilePos{.col = COL0 + dc, .row = ROW0 + dr},
|
||||
.player_id = -1,
|
||||
});
|
||||
++decal_broadcast;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (decal_broadcast > 0) {
|
||||
Log::info("EntityManager", "{} tile_painted broadcast inicial (decals de sòl)", decal_broadcast);
|
||||
Log::info("EntityManager", "{} tile_painted broadcast inicial (decals + murs)", decal_broadcast);
|
||||
}
|
||||
|
||||
Log::info("EntityManager", "{} entitats + {} actors pending des de {}", loaded, pending_actors_.size(), level_yaml_path);
|
||||
|
||||
Reference in new issue
Block a user