From 505e819af1c60a6a767f26c4aefa6c9bf6a32b50 Mon Sep 17 00:00:00 2001 From: Sergio Valor Date: Mon, 20 Apr 2026 17:52:53 +0200 Subject: [PATCH] HC-06: rutes d'assets de GameScene a Defaults::Pyramid + Config MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Afegits `Defaults::Pyramid::{MAP_YAML, PLAYER_SPRITE, PLAYER_YAML, MUSIC_TRACK}` a utils/defaults.hpp. `GameScene` exposa `Config` i `defaultConfig()`; el ctor accepta Config (default = Defaults::Pyramid) i usa els camps enlloc dels literals. `Player` passa a rebre el anim_key per constructor en lloc de cablejar "player.yaml". Cache key = basename (convenció preexistent). Cada piràmide futura serà un Config distint. --- docs/audit-game.md | 2 +- source/game/entities/player.cpp | 4 +-- source/game/entities/player.hpp | 2 +- source/game/scenes/game_scene.cpp | 46 +++++++++++++++++++++---------- source/game/scenes/game_scene.hpp | 16 ++++++++++- source/utils/defaults.hpp | 10 +++++++ 6 files changed, 60 insertions(+), 20 deletions(-) diff --git a/docs/audit-game.md b/docs/audit-game.md index b2f20c7..cd96512 100644 --- a/docs/audit-game.md +++ b/docs/audit-game.md @@ -45,7 +45,7 @@ Els IDs es mantenen estables una vegada assignats. Cada entrada apunta al fitxer | HC-03 | `map.hpp:18-62` | Tota la geometria del mapa + 4 índexs de paleta en `.hpp` | Crítico | DONE | Bloc `geometry:` afegit a `pyramid.yaml`; `Map` exposa `inline static int` + `loadFrom(yaml)`; derivats (CORRIDOR/BOARD/ORIGIN/PLAYFIELD) recalculats al load. `constexpr` → `const` en els locals dependents a `player.cpp` i `game_scene.cpp`. Índexs de paleta queden per DEAD-02 | | HC-04 | `notification_presets.hpp:24-38` | `text_color`, `bg_color`, `time_ms` en `constexpr` | Menor | PENDING | Bloc `notifications:` a `config.yaml` o tema extern | | HC-05 | `ui_palette.hpp:12-21` | Índexs de paleta (`RENDER_INFO_TEXT=47`, `SHADOW=34`, `CANVAS_BG=65`) en `constexpr` | Menor | PENDING | Bloc `ui:` a `config.yaml` | -| HC-06 | `game_scene.cpp:24-26,52` | Rutes `data/maps/pyramid.yaml`, `data/player/player.*`, `pyramid_1.ogg` cablejades | Importante | PENDING | Paràmetre del ctor o `scenes.yaml` | +| HC-06 | `game_scene.cpp:24-26,52` | Rutes `data/maps/pyramid.yaml`, `data/player/player.*`, `pyramid_1.ogg` cablejades | Importante | DONE | Afegit `Defaults::Pyramid::{MAP_YAML,PLAYER_SPRITE,PLAYER_YAML,MUSIC_TRACK}`; `GameScene::Config` struct + `defaultConfig()` passa les rutes al ctor (default ve de Defaults). `Player` ctor accepta `anim_key` en lloc de cablejar `"player.yaml"`. Cache key = basename (mateix conveni que abans) | | HC-07 | `options.cpp:27,55` | Fallbacks `"letterbox"`/`"off"` com a strings màgics que dupliquen els enums | Menor | PENDING | Passar per `toString(Defaults::...)` | | HC-08 | `tilemap.cpp:135` | `0xFF000000U` com a màscara alfa | Menor | PENDING | Constant amb nom a `defines.hpp` | diff --git a/source/game/entities/player.cpp b/source/game/entities/player.cpp index 57f116f..25e1f49 100644 --- a/source/game/entities/player.cpp +++ b/source/game/entities/player.cpp @@ -45,8 +45,8 @@ void Player::loadFrom(const std::string& yaml_path) { collision_y_offset = (sprite_h - base_size) - collision_padding; } -Player::Player(float x, float y, const Controls& controls) - : AnimatedSprite(Resource::Cache::get().getAnimationData("player.yaml")), +Player::Player(const std::string& anim_key, float x, float y, const Controls& controls) + : AnimatedSprite(Resource::Cache::get().getAnimationData(anim_key)), controls_(controls) { setPos(x, y); setCurrentAnimation("stand"); diff --git a/source/game/entities/player.hpp b/source/game/entities/player.hpp index a362ef5..3ace095 100644 --- a/source/game/entities/player.hpp +++ b/source/game/entities/player.hpp @@ -36,7 +36,7 @@ class Player : public AnimatedSprite { // Ha de cridar-se abans d'instanciar Player; GameScene ho fa al ctor. static void loadFrom(const std::string& yaml_path); - Player(float x, float y, const Controls& controls); + Player(const std::string& anim_key, float x, float y, const Controls& controls); void update(float delta_time) override; diff --git a/source/game/scenes/game_scene.cpp b/source/game/scenes/game_scene.cpp index 273b97d..98e3196 100644 --- a/source/game/scenes/game_scene.cpp +++ b/source/game/scenes/game_scene.cpp @@ -4,7 +4,9 @@ #include #include +#include #include +#include #include #include "core/audio/audio.hpp" @@ -23,25 +25,39 @@ namespace { // La geometria ha de quedar inicialitzada abans que Tilemap parsejar el - // mateix YAML i abans que el ctor de Player consulte Map::PLAYFIELD_*. - // Cridar-la des d'una expressió que retorne la ruta permet encadenar-ho - // a l'init list sense fer Tilemap default-constructible. - auto loadMapGeometry(const char* yaml_path) -> const char* { + // mateix YAML i abans que el ctor de Player consulte Map::playfield_*. + // Construïm el Tilemap via un helper que primer carrega la geometria + // i després retorna el Tilemap per valor (move-construït). + auto makeTilemap(const std::string& yaml_path) -> Tilemap { Map::loadFrom(yaml_path); - return yaml_path; + return Tilemap(yaml_path); } } // namespace -GameScene::GameScene() - : tilemap_(loadMapGeometry("data/maps/pyramid.yaml")) { - Resource::Cache::get().loadSurface("player.gif", "data/player/player.gif"); - Resource::Cache::get().loadAnimation("player.yaml", "data/player/player.yaml"); +auto GameScene::defaultConfig() -> Config { + return { + .map_yaml = Defaults::Pyramid::MAP_YAML, + .player_sprite = Defaults::Pyramid::PLAYER_SPRITE, + .player_yaml = Defaults::Pyramid::PLAYER_YAML, + .music_track = Defaults::Pyramid::MUSIC_TRACK, + }; +} + +GameScene::GameScene(Config config) + : config_(std::move(config)), + tilemap_(makeTilemap(config_.map_yaml)) { + // Convenció: el Resource::Cache indexa per basename del fitxer, perquè + // la mateixa clau l'usa el parseador d'animació (YAML > tileSetFile). + const auto SPRITE_KEY = std::filesystem::path(config_.player_sprite).filename().string(); + const auto ANIM_KEY = std::filesystem::path(config_.player_yaml).filename().string(); + Resource::Cache::get().loadSurface(SPRITE_KEY, config_.player_sprite); + Resource::Cache::get().loadAnimation(ANIM_KEY, config_.player_yaml); // Geometria de col·lisió del jugador (caixa 16×16, base 12): carregada // del mateix YAML que l'animació. Ha d'estar feta abans d'instanciar // Player perquè el spawn consulta `collision_*`. - Player::loadFrom("data/player/player.yaml"); + Player::loadFrom(config_.player_yaml); // Jugador 0: fletxes del teclat (Defaults::KeysGame). Instanciar-ne un // segon només requereix afegir una altra entrada amb uns Controls @@ -61,13 +77,13 @@ GameScene::GameScene() static_cast(Map::playfield_y) + (static_cast(Map::outer_corridor) / 2.0F); const auto SPAWN_X = CORRIDOR_CENTER_X - (static_cast(Player::sprite_w) / 2.0F); const auto SPAWN_Y = CORRIDOR_CENTER_Y - static_cast(Player::collision_y_offset) - (static_cast(Player::collision_size) / 2.0F); - players_.emplace_back(std::make_unique(SPAWN_X, SPAWN_Y, CONTROLS_P1)); + players_.emplace_back(std::make_unique(ANIM_KEY, SPAWN_X, SPAWN_Y, CONTROLS_P1)); - // Música de fons de la piràmide 1 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. + // 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. if (Audio::get() != nullptr) { - Audio::get()->playMusic("pyramid_1.ogg", -1); + Audio::get()->playMusic(config_.music_track, -1); } } diff --git a/source/game/scenes/game_scene.hpp b/source/game/scenes/game_scene.hpp index 5a3fbb2..1d7df1b 100644 --- a/source/game/scenes/game_scene.hpp +++ b/source/game/scenes/game_scene.hpp @@ -1,6 +1,7 @@ #pragma once #include +#include #include #include "core/scene/scene.hpp" @@ -10,13 +11,26 @@ class Player; class GameScene : public Scene { public: - GameScene(); + // Conjunt de rutes que defineixen una piràmide concreta (mapa + tilemap + // + sprites del jugador + música). Cada piràmide serà un Config distint; + // `defaultConfig()` retorna la primera (Defaults::Pyramid). + struct Config { + std::string map_yaml; + std::string player_sprite; + std::string player_yaml; + std::string music_track; + }; + + [[nodiscard]] static auto defaultConfig() -> Config; + + explicit GameScene(Config config = defaultConfig()); ~GameScene() override; void update(int delta_ms) override; void render() override; private: + Config config_; Tilemap tilemap_; // Vector des del principi: AEE suportarà multijugador local; cada Player diff --git a/source/utils/defaults.hpp b/source/utils/defaults.hpp index 03b1188..f50de28 100644 --- a/source/utils/defaults.hpp +++ b/source/utils/defaults.hpp @@ -84,4 +84,14 @@ namespace Defaults { constexpr float SPEED_PX_PER_S = 60.0F; // Velocitat base del jugador (sense sprint / slow-zones). } // namespace Player + // Rutes d'assets per piràmide. Centralitzats ací perquè `GameScene` no + // en contingui cap literal; afegir una piràmide nova serà un altre + // conjunt de constants + un Config distint passat al ctor. + namespace Pyramid { + constexpr const char* MAP_YAML = "data/maps/pyramid.yaml"; + constexpr const char* PLAYER_SPRITE = "data/player/player.gif"; + constexpr const char* PLAYER_YAML = "data/player/player.yaml"; + constexpr const char* MUSIC_TRACK = "pyramid_1.ogg"; + } // namespace Pyramid + } // namespace Defaults