diff --git a/data/maps/pyramid.yaml b/data/maps/pyramid.yaml index f80bd28..8fe8e16 100644 --- a/data/maps/pyramid.yaml +++ b/data/maps/pyramid.yaml @@ -3,13 +3,11 @@ # en el tilemap però només 1.5 visibles al canvas, així que la textura es # dibuixa amb un origen de x=-8). Vertical no cal overscan: 15·16 = 240. # -# Símbols del grid: -# W = paret (tile 99 del tileset, o (3,3) en 0-indexed) -# F = sòl (llista = un tile aleatori entre aquests per cada casella) -# . = cap tile (els sarcòfags seran actors, ací deixem transparent) -# -# Índexs lineals: els tiles van d'esquerra a dreta, de dalt a baix. Amb un -# tileset de 512×256 i tiles de 16×16 hi ha 32 tiles per fila. +# Format del tilemap: +# `data` és una llista de files; cada fila és una llista d'índexs del +# tileset (lineal esq→dre, dalt→baix). Amb un tileset de 512×256 i tiles +# de 16×16 hi ha 32 tiles per fila. Un valor negatiu (p.ex. -1) deixa +# la cel·la buida (transparent), útil per caselles que ocuparà un actor. tileset: data/tilesets/tomb.gif tile_size: 16 @@ -31,38 +29,22 @@ geometry: back_wall_h: 24 side_wall_w: 24 -legend: - W: 292 - X: 169 - Y: 1 - Z: 202 - T: 200 - R: 262 - G: 263 - H: 230 - I: 231 - J: 233 - A: 2 - B: 34 - C: 33 - D: 32 - -data: | - YYYYYYYYYYYYYYYYYYYYY - YHJJJJJJJJJJJJJJJJJIY - YZWWWWWWWWWWWWWWWWWTY - YZDDADDBBDDADDDDBDDTY - YZDAAADAAADAAABAAADTY - YZDDDCCDDDDDADDDBDDTY - YZDAAADAAAAAAADAAADTY - YZDDCCDDDDDADDBDDDDTY - YZDAAADAAADAAADAAADTY - YZDDDDCCDDDDADDDDDDTY - YZDAAADAAADAAADAAADTY - YZDDDABDDDDADCDDBDDTY - YZDAAADAAADAAADAAADTY - YZDDBBDDADDDBCDDDDDTY - YRXXXXXXXXXXXXXXXXXGY +data: + - [ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1] + - [ 1,230,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,231, 1] + - [ 1,202,292,292,292,292,292,292,292,292,292,292,292,292,292,292,292,292,292,200, 1] + - [ 1,202, 32, 32, 2, 32, 32, 34, 34, 32, 32, 2, 32, 32, 32, 32, 34, 32, 32,200, 1] + - [ 1,202, 32, 2, 2, 2, 32, 2, 2, 2, 32, 2, 2, 2, 34, 2, 2, 2, 32,200, 1] + - [ 1,202, 32, 32, 32, 33, 33, 32, 32, 32, 32, 32, 2, 32, 32, 32, 34, 32, 32,200, 1] + - [ 1,202, 32, 2, 2, 2, 32, 2, 2, 2, 2, 2, 2, 2, 32, 2, 2, 2, 32,200, 1] + - [ 1,202, 32, 32, 33, 33, 32, 32, 32, 32, 32, 2, 32, 32, 34, 32, 32, 32, 32,200, 1] + - [ 1,202, 32, 2, 2, 2, 32, 2, 2, 2, 32, 2, 2, 2, 32, 2, 2, 2, 32,200, 1] + - [ 1,202, 32, 32, 32, 32, 33, 33, 32, 32, 32, 32, 2, 32, 32, 32, 32, 32, 32,200, 1] + - [ 1,202, 32, 2, 2, 2, 32, 2, 2, 2, 32, 2, 2, 2, 32, 2, 2, 2, 32,200, 1] + - [ 1,202, 32, 32, 32, 2, 34, 32, 32, 32, 32, 2, 32, 33, 32, 32, 34, 32, 32,200, 1] + - [ 1,202, 32, 2, 2, 2, 32, 2, 2, 2, 32, 2, 2, 2, 32, 2, 2, 2, 32,200, 1] + - [ 1,202, 32, 32, 34, 34, 32, 32, 2, 32, 32, 32, 34, 33, 32, 32, 32, 32, 32,200, 1] + - [ 1,262,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,263, 1] # Spawns d'entitats per a aquest nivell. Es llegeixen des de # EntityManager::loadFromLevel al GameScene. Convencions: @@ -75,7 +57,7 @@ data: | # # Dos sarcòfags en cantonades oposades → perímetres aïllats (cap tile en # comú). La porta va al centre inferior, on el tilemap té els tiles -# d'obertura (R/G). La momia al corredor central. L'antorxa al costat +# d'obertura (262/263). La momia al corredor central. L'antorxa al costat # superior esquerre per verificar render d'una entitat decorativa. entities: - type: torch diff --git a/data/maps/test_entities.yaml b/data/maps/test_entities.yaml index 86163fa..4a46d7c 100644 --- a/data/maps/test_entities.yaml +++ b/data/maps/test_entities.yaml @@ -2,6 +2,8 @@ # per a poder carregar Map sense errors, però el seu propòsit real són # els spawns de sota: l'smoke verifica que EntityLoader::readSpawns els # retorna correctament i que EntityManager pot instanciar-los i wire-ar-los. +# +# Format del tilemap: vegeu pyramid.yaml. tileset: data/tilesets/tomb.gif tile_size: 16 @@ -18,18 +20,14 @@ geometry: back_wall_h: 24 side_wall_w: 24 -legend: - Y: 1 - X: 169 - -data: | - YYYYYYYYYYYYYY - YXXXXXXXXXXXXY - YXXXXXXXXXXXXY - YXXXXXXXXXXXXY - YXXXXXXXXXXXXY - YXXXXXXXXXXXXY - YYYYYYYYYYYYYY +data: + - [ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1] + - [ 1,169,169,169,169,169,169,169,169,169,169,169,169, 1] + - [ 1,169,169,169,169,169,169,169,169,169,169,169,169, 1] + - [ 1,169,169,169,169,169,169,169,169,169,169,169,169, 1] + - [ 1,169,169,169,169,169,169,169,169,169,169,169,169, 1] + - [ 1,169,169,169,169,169,169,169,169,169,169,169,169, 1] + - [ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1] entities: - type: torch diff --git a/source/game/map/tilemap.cpp b/source/game/map/tilemap.cpp index 857a2d2..9a3c1ee 100644 --- a/source/game/map/tilemap.cpp +++ b/source/game/map/tilemap.cpp @@ -2,11 +2,10 @@ #include #include +#include #include -#include #include -#include -#include +#include #include "core/rendering/screen.hpp" #include "core/rendering/surface.hpp" @@ -16,35 +15,6 @@ namespace { - // Cada símbol del grid es mapeja a (col, fila) dins del tileset. - using TileCoord = std::pair; - using Legend = std::unordered_map; - - auto splitLines(const std::string& text) -> std::vector { - std::vector lines; - std::istringstream iss(text); - std::string line; - while (std::getline(iss, line)) { - if (!line.empty()) { lines.push_back(line); } - } - return lines; - } - - // La llegenda usa índexs lineals del tileset (esq→dre, dalt→baix). - // Els convertim a (col, fila) amb el nombre de tiles per fila del tileset. - auto parseLegend(const fkyaml::node& node, int tileset_cols) -> Legend { - Legend legend; - for (auto it = node.begin(); it != node.end(); ++it) { - const auto KEY_STR = it.key().get_value(); - if (KEY_STR.empty()) { continue; } - const auto INDEX = it.value().get_value(); - const int COL = INDEX % tileset_cols; - const int ROW = INDEX / tileset_cols; - legend[KEY_STR.front()] = {COL, ROW}; - } - return legend; - } - // Copia un tile (col, fila) del tileset al buffer ARGB a la posició de // destí (dest_x, dest_y). Els píxels amb l'índex de transparència del // tileset es deixen com estan al buffer (alpha=0 per defecte). @@ -84,17 +54,21 @@ Tilemap::Tilemap(const std::string& yaml_path) { // Carreguem el tileset al cache (idempotent) i el pillem per accedir // als seus píxels i paleta. La paleta del tileset ve del GIF mateix. - // Ens cal abans de la llegenda per saber quants tiles per fila té. + // Ens cal abans de llegir `data` per saber quants tiles per fila té. const auto& cache_name = TILESET_PATH; Resource::Cache::get().loadSurface(cache_name, TILESET_PATH); const auto TILESET = Resource::Cache::get().getSurface(cache_name); const int TILESET_COLS = TILESET->getWidth() / TILE_SIZE; - const auto LEGEND = parseLegend(yaml["legend"], TILESET_COLS); - const auto LINES = splitLines(yaml["data"].get_value()); - - const int ROWS = static_cast(LINES.size()); - const int COLS = ROWS > 0 ? static_cast(LINES.front().size()) : 0; + // `data` és una seqüència de seqüències d'enters: cada fila és una + // llista d'índexs lineals al tileset (esq→dre, dalt→baix). Un valor + // negatiu (per convenció -1) deixa la cel·la buida (alpha=0). + const auto& data = yaml["data"]; + if (!data.is_sequence() || data.empty()) { + throw std::runtime_error("Tilemap: `data` buit o amb format incorrecte a " + yaml_path); + } + const int ROWS = static_cast(data.size()); + const int COLS = static_cast(data[0].size()); width_px_ = COLS * TILE_SIZE; height_px_ = ROWS * TILE_SIZE; pixels_.assign( @@ -102,12 +76,14 @@ Tilemap::Tilemap(const std::string& yaml_path) { 0U); for (int row = 0; row < ROWS; ++row) { - const auto& line = LINES[row]; - for (int col = 0; col < COLS && col < static_cast(line.size()); ++col) { - const char SYMBOL = line[col]; - const auto IT = LEGEND.find(SYMBOL); - if (IT == LEGEND.end()) { continue; } - blitTile(*TILESET, TILE_SIZE, IT->second.first, IT->second.second, pixels_, width_px_, col * TILE_SIZE, row * TILE_SIZE); + const auto& line = data[row]; + const int LINE_COLS = static_cast(line.size()); + for (int col = 0; col < COLS && col < LINE_COLS; ++col) { + const int INDEX = line[col].get_value(); + if (INDEX < 0) { continue; } + const int SRC_COL = INDEX % TILESET_COLS; + const int SRC_ROW = INDEX / TILESET_COLS; + blitTile(*TILESET, TILE_SIZE, SRC_COL, SRC_ROW, pixels_, width_px_, col * TILE_SIZE, row * TILE_SIZE); } }