feat(game_scene): integra PaintLayer i llegeix paint_tile del YAML del mapa
This commit is contained in:
1 parent
e3cf2eb773
commit
d0503ff8b1
2 files changed
+47
-3
No files matched your search
@@ -21,7 +21,9 @@
|
|||||||
#include "core/rendering/screen.hpp"
|
#include "core/rendering/screen.hpp"
|
||||||
#include "core/rendering/text.hpp"
|
#include "core/rendering/text.hpp"
|
||||||
#include "core/resources/resource_cache.hpp"
|
#include "core/resources/resource_cache.hpp"
|
||||||
|
#include "core/resources/resource_helper.hpp"
|
||||||
#include "core/system/event_buffer.hpp"
|
#include "core/system/event_buffer.hpp"
|
||||||
|
#include "external/fkyaml_node.hpp"
|
||||||
#include "game/entities/entity.hpp"
|
#include "game/entities/entity.hpp"
|
||||||
#include "game/entities/event_bus.hpp"
|
#include "game/entities/event_bus.hpp"
|
||||||
#include "game/entities/player.hpp"
|
#include "game/entities/player.hpp"
|
||||||
@@ -42,6 +44,21 @@ namespace {
|
|||||||
return Tilemap(yaml_path);
|
return Tilemap(yaml_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Llegeix un camp sencer opcional del YAML del mapa. Si no hi és,
|
||||||
|
// retorna `fallback` (per defecte -1, que al Player indica "no pinta").
|
||||||
|
// S'usa per `player1_paint_tile` i `player2_paint_tile`: cada jugador
|
||||||
|
// pinta amb l'índex declarat al mapa, i un mapa sense aquests camps
|
||||||
|
// simplement no deixa rastre visual.
|
||||||
|
auto readOptionalInt(const std::string& yaml_path, const std::string& key, int fallback = -1) -> int {
|
||||||
|
auto bytes = Resource::Helper::loadFile(yaml_path);
|
||||||
|
if (bytes.empty()) { return fallback; }
|
||||||
|
const auto* begin = reinterpret_cast<const char*>(bytes.data());
|
||||||
|
const auto* end = begin + bytes.size();
|
||||||
|
auto yaml = fkyaml::node::deserialize(begin, end);
|
||||||
|
if (!yaml.contains(key)) { return fallback; }
|
||||||
|
return yaml[key].get_value<int>();
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
auto GameScene::defaultConfig() -> Config {
|
auto GameScene::defaultConfig() -> Config {
|
||||||
@@ -103,10 +120,23 @@ GameScene::GameScene(Config config)
|
|||||||
static_cast<float>(Map::playfield_y) + (static_cast<float>(Map::outer_corridor) / 2.0F);
|
static_cast<float>(Map::playfield_y) + (static_cast<float>(Map::outer_corridor) / 2.0F);
|
||||||
const auto SPAWN_X = CORRIDOR_CENTER_X - (static_cast<float>(Player::sprite_w) / 2.0F);
|
const auto SPAWN_X = CORRIDOR_CENTER_X - (static_cast<float>(Player::sprite_w) / 2.0F);
|
||||||
const auto SPAWN_Y = CORRIDOR_CENTER_Y - static_cast<float>(Player::collision_y_offset) - (static_cast<float>(Player::collision_size) / 2.0F);
|
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, Map::makeInfo()));
|
// Índex de tile amb què pinta cada jugador — llegit del YAML del mapa
|
||||||
|
// (camps opcionals `player1_paint_tile` / `player2_paint_tile`). Si no
|
||||||
|
// hi són, `paint_tile_index_ = -1` i el Player no deixa rastre.
|
||||||
|
const int P1_PAINT = readOptionalInt(config_.map_yaml, "player1_paint_tile", -1);
|
||||||
|
players_.emplace_back(std::make_unique<Player>(ANIM_KEY, SPAWN_X, SPAWN_Y, CONTROLS_P1, Map::makeInfo(), P1_PAINT));
|
||||||
|
|
||||||
// Connectem el Player al bus perquè emeti `on_tile_entered` i els
|
// PaintLayer: font única del pintat del nivell. Es crea després de
|
||||||
// sarcòfags rebin les notificacions de pas per tile.
|
// `loadFromLevel` perquè l'EntityManager ja ha de tenir els sarcòfags
|
||||||
|
// registrats (tot i que el sarc escolta via fan-out, no directament
|
||||||
|
// al bus; l'ordre de subscripcions aquí és irrellevant per la
|
||||||
|
// correcció, però sí pel log d'arrencada). Connectat al bus del
|
||||||
|
// manager per subscriure's a `on_tile_entered` i publicar `tile_painted`.
|
||||||
|
paint_layer_ = std::make_unique<PaintLayer>(tilemap_, &entity_manager_.getBus());
|
||||||
|
|
||||||
|
// Connectem el Player al bus perquè emeti `on_tile_entered` i el
|
||||||
|
// PaintLayer (subscrit ja) processe el pintat; el fan-out cap als
|
||||||
|
// sarcòfags passa per `tile_painted`.
|
||||||
players_.back()->setEventBus(&entity_manager_.getBus());
|
players_.back()->setEventBus(&entity_manager_.getBus());
|
||||||
|
|
||||||
// Música de fons en bucle infinit. El track ja està al Resource::Cache
|
// Música de fons en bucle infinit. El track ja està al Resource::Cache
|
||||||
@@ -228,6 +258,10 @@ void GameScene::render() {
|
|||||||
#else
|
#else
|
||||||
constexpr bool SKIP_ACTORS = false;
|
constexpr bool SKIP_ACTORS = false;
|
||||||
#endif
|
#endif
|
||||||
|
// Capa de pintat: va entre el tilemap base i els actors, perquè els
|
||||||
|
// sarcòfags i el jugador la tapen. S'amaga al mode editor (decisió
|
||||||
|
// explícita: l'editor edita el tilemap, no la capa de pintat).
|
||||||
|
if (!SKIP_ACTORS && paint_layer_) { paint_layer_->render(); }
|
||||||
if (!SKIP_ACTORS) {
|
if (!SKIP_ACTORS) {
|
||||||
// Z-order interleaving entitats ↔ players per `getFeetY()` ascendent:
|
// Z-order interleaving entitats ↔ players per `getFeetY()` ascendent:
|
||||||
// els actors amb els peus més amunt queden dibuixats primer (al fons),
|
// els actors amb els peus més amunt queden dibuixats primer (al fons),
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
|
|
||||||
#include "core/scene/scene.hpp"
|
#include "core/scene/scene.hpp"
|
||||||
#include "game/entities/entity_manager.hpp"
|
#include "game/entities/entity_manager.hpp"
|
||||||
|
#include "game/map/paint_layer.hpp"
|
||||||
#include "game/map/tilemap.hpp"
|
#include "game/map/tilemap.hpp"
|
||||||
|
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
@@ -53,6 +54,15 @@ class GameScene : public Scene {
|
|||||||
// té els seus propis Controls i entra al vector amb una crida extra.
|
// té els seus propis Controls i entra al vector amb una crida extra.
|
||||||
std::vector<std::unique_ptr<Player>> players_;
|
std::vector<std::unique_ptr<Player>> players_;
|
||||||
|
|
||||||
|
// Capa de "pintat" del terra. Escolta `on_tile_entered` al bus,
|
||||||
|
// filtra pintabilitat (sòl transitable) i re-publica `tile_painted`
|
||||||
|
// per als sarcòfags. `unique_ptr` per controlar l'ordre de
|
||||||
|
// construcció/destrucció: es crea al ctor un cop `entity_manager_` i
|
||||||
|
// `tilemap_` estan llestos, i es destrueix abans que `entity_manager_`
|
||||||
|
// (on viu el bus al qual està subscrit). Declarat després d'aquests
|
||||||
|
// dos membres per garantir l'ordre invers a la destrucció.
|
||||||
|
std::unique_ptr<PaintLayer> paint_layer_;
|
||||||
|
|
||||||
// Pausa de gameplay. Quan `paused_` és true, l'update de jugadors i
|
// Pausa de gameplay. Quan `paused_` és true, l'update de jugadors i
|
||||||
// entitats es salta (el món es congela); l'input d'UI (GlobalInputs,
|
// entitats es salta (el món es congela); l'input d'UI (GlobalInputs,
|
||||||
// Notifier, RenderInfo) continua per no perdre hotkeys ni l'overlay de
|
// Notifier, RenderInfo) continua per no perdre hotkeys ni l'overlay de
|
||||||
|
|||||||
Reference in new issue
Block a user