#pragma once #include // Mapa d'una piràmide: sala rectangular amb marcador superior, muros pels // quatre costats i graella 4×4 de sarcòfags envoltada per un passadís a cada // cantó. Mesures portades de l'AEE original (mapa.cpp: sarcòfag 50×20, pitch // 65×35, passadís 15 px) i adaptades a 320×240 repartint els 40 px extra // sobretot al mur frontal, que fa de primer pla per a la falsa perspectiva. // // Z-order: el render es divideix en fons (marcador + muros + sòl) i files // de sarcòfags. El caller (GameScene) alternarà jugadors ordenats per la Y // dels peus amb cada fila per a aconseguir la perspectiva falsa (el sarcòfag // tapa el cos del jugador si aquest està "darrere"; el cap del jugador tapa // el sarcòfag de la fila superior si està "davant"). class Map { public: // Graella portada tal qual de l'AEE (4×4 sarcòfags, pitch 65×35). static constexpr int GRID_COLS = 4; static constexpr int GRID_ROWS = 5; static constexpr int SARC_W = 48; static constexpr int SARC_H = 16; static constexpr int PITCH_X = 64; static constexpr int PITCH_Y = 32; // El pas entre sarcòfags (15×15) és exactament el que ha de cabre el // jugador; el reutilitzem també com a passadís exterior (perímetre). static constexpr int CORRIDOR_W = PITCH_X - SARC_W; static constexpr int CORRIDOR_H = PITCH_Y - SARC_H; static constexpr int OUTER_CORRIDOR = CORRIDOR_W; // Dimensions del tauler complet (des del primer sarcòfag fins al cantó // inferior dret de l'últim). Derivades: no cal tocar-les a mà. static constexpr int BOARD_W = ((GRID_COLS - 1) * PITCH_X) + SARC_W; static constexpr int BOARD_H = ((GRID_ROWS - 1) * PITCH_Y) + SARC_H; // Cromat de la sala: marcador, mur posterior (dalt), murs laterals i mur // frontal (baix). El frontal és més gros per absorbir els 40 px extra del // pas de 320×200 → 320×240 i reforçar la falsa perspectiva. static constexpr int HUD_H = 24; static constexpr int BACK_WALL_H = 24; static constexpr int SIDE_WALL_W = 24; // Origen del tauler dins del canvas (cantó superior-esquerra del primer // sarcòfag). Derivat: mur + passadís en cada eix. static constexpr int ORIGIN_X = SIDE_WALL_W + OUTER_CORRIDOR; static constexpr int ORIGIN_Y = HUD_H + BACK_WALL_H + OUTER_CORRIDOR; // Límits de la zona jugable (on el jugador pot moure's lliurement, sense // comptar encara les colisions contra sarcòfags). Serviran per al pas // següent de colisions. static constexpr int PLAYFIELD_X = SIDE_WALL_W; static constexpr int PLAYFIELD_Y = HUD_H + BACK_WALL_H; static constexpr int PLAYFIELD_W = BOARD_W + (2 * OUTER_CORRIDOR); static constexpr int PLAYFIELD_H = BOARD_H + (2 * OUTER_CORRIDOR); // Índexs a la paleta UI (data/palettes/sega-cube.pal). Centralitzats ací // per a poder ajustar l'estètica sense buscar magic numbers pel codi. static constexpr Uint8 HUD_BG = 0; static constexpr Uint8 WALL = 80; static constexpr Uint8 FLOOR = 40; static constexpr Uint8 SARC = 160; Map(); // Fons estàtic: marcador, muros (back/side/front) i sòl interior. No // pinta cap sarcòfag; això queda per a renderSarcsRow() perquè el caller // puga interleaveing amb els jugadors. static void renderBackground(); // Pinta la fila `row` de sarcòfags (4 rectangles a pitch 65). El caller // decideix quan cridar-la respecte als jugadors segons la seua Y. static void renderSarcsRow(int row); // Y de la cara inferior dels sarcòfags de la fila `row` (la "baseline" // per a ordenar en Z): un jugador amb els peus per sobre d'aquest valor // queda darrere; per sota, queda davant. [[nodiscard]] static auto getSarcRowBottomY(int row) -> int; // Rectangle ocupat pel sarcòfag a la posició (col, row) de la graella. [[nodiscard]] static auto getSarcRect(int col, int row) -> SDL_FRect; // Mapa de colisions (separat del mapa de dibuix): retorna true si el // rectangle `base_box` (la base del jugador, per exemple) s'encavalca // amb cap sarcòfag. Així Player mai camine sobre un sarcòfag, // independentment de com els pinte renderSarcsRow. [[nodiscard]] static auto collides(const SDL_FRect& base_box) -> bool; };