feat(entities): integració del sistema d'entitats al GameScene

This commit is contained in:
JailDesigner committed 2026-04-21 13:55:21 +02:00
1 parent 96b71b0f65
commit 7191a08618
16 files changed
+683 -15

No files matched your search

+34
View File
@@ -5,8 +5,10 @@
#include <algorithm>
#include <cstddef>
#include <filesystem>
#include <iostream>
#include <iterator>
#include <utility>
#include <variant>
#include <vector>
#include "core/audio/audio.hpp"
@@ -15,6 +17,7 @@
#include "core/rendering/render_info.hpp"
#include "core/rendering/screen.hpp"
#include "core/resources/resource_cache.hpp"
#include "game/entities/event_bus.hpp"
#include "game/entities/player.hpp"
#include "game/map/map.hpp"
#include "game/options.hpp"
@@ -59,6 +62,23 @@ GameScene::GameScene(Config config)
// Player perquè el spawn consulta `collision_*`.
Player::loadFrom(config_.player_yaml);
// Carrega les entitats del nivell (antorxa, sarcòfags, porta, momia,
// etc.). Requereix que Map::loadFrom ja s'hagi cridat (ho fa
// `makeTilemap`), perquè consulta `Map::tile_size` i `getSarcRect`.
// Les surfaces de les entitats es carreguen al Resource::Cache aquí.
entity_manager_.loadFromLevel(config_.map_yaml);
// Subscripcions bàsiques al bus del nivell: de moment només logs, sense
// tocar ni la vida del jugador ni l'estat de la escena. Serà la base
// sobre la qual cablejar HUD i fi de nivell més endavant.
entity_manager_.getBus().subscribe("level_complete", [](const Event& /*ev*/) {
std::cout << "[LEVEL COMPLETE]" << '\n';
});
entity_manager_.getBus().subscribe("player_hit", [](const Event& ev) {
const auto* dmg = std::get_if<int>(&ev.payload);
std::cout << "[PLAYER HIT] dmg=" << (dmg != nullptr ? *dmg : 0) << '\n';
});
// Jugador 0: fletxes del teclat (Defaults::KeysGame). Instanciar-ne un
// segon només requereix afegir una altra entrada amb uns Controls
// distints (p.ex. WASD).
@@ -79,6 +99,10 @@ GameScene::GameScene(Config config)
const auto SPAWN_Y = CORRIDOR_CENTER_Y - static_cast<float>(Player::collision_y_offset) - (static_cast<float>(Player::collision_size) / 2.0F);
players_.emplace_back(std::make_unique<Player>(ANIM_KEY, SPAWN_X, SPAWN_Y, CONTROLS_P1));
// Connectem el Player al bus perquè emeti `on_tile_entered` i els
// sarcòfags rebin les notificacions de pas per tile.
players_.back()->setEventBus(&entity_manager_.getBus());
// Música de fons en bucle infinit. El track ja està al Resource::Cache
// (preload al Director), així que playMusic només mou el punter cap a
// jail_audio i obri l'stream. Audio::get() està garantit no-null:
@@ -94,6 +118,11 @@ void GameScene::update(int delta_ms) {
const float DT = static_cast<float>(delta_ms) / 1000.0F;
for (auto& player : players_) { player->update(DT); }
// El tick d'entitats DESPRÉS del tick dels jugadors: si el jugador ha
// emès `on_tile_entered` aquest frame, l'EntityManager ja l'ha encaminat
// als sarcòfags via la subscripció del bus, i aquest `update` pot
// aplicar la transició OPENING → OPEN en el mateix frame.
entity_manager_.update(DT);
RenderInfo::get().update(delta_ms, Options::buildRenderInfoFrame(UiColor::RENDER_INFO_TEXT, UiColor::RENDER_INFO_SHADOW));
Notifier::get().update(delta_ms);
}
@@ -108,6 +137,11 @@ void GameScene::render() {
// col·lisions del jugador.
tilemap_.render();
// Entitats (sarcòfags, porta, momia, antorxa...) dibuixades per sobre
// dels tiles però sota dels players. Z-order fi (interleaving per feetY
// amb els sarcs) queda per a una tasca posterior; "sin pulido".
entity_manager_.renderAll();
// Amb un sol jugador, l'ordre és irrellevant i ens estalviem el vector
// temporal. Quan n'hi haja més d'un (o quan els sarcs siguen sprites)
// caldrà ordenar per `getFeetY()` ascendent i interleaveing amb les
+6
View File
@@ -5,6 +5,7 @@
#include <vector>
#include "core/scene/scene.hpp"
#include "game/entities/entity_manager.hpp"
#include "game/map/tilemap.hpp"
class Player;
@@ -33,6 +34,11 @@ class GameScene : public Scene {
Config config_;
Tilemap tilemap_;
// Gestor d'entitats del nivell (sarcòfags, porta, momia, antorxa,
// etc.). Viu aquí perquè la seua vida coincideix amb la de la escena;
// cada entitat del nivell es carrega al ctor via loadFromLevel.
EntityManager entity_manager_;
// Vector des del principi: AEE suportarà multijugador local; cada Player
// té els seus propis Controls i entra al vector amb una crida extra.
std::vector<std::unique_ptr<Player>> players_;