#pragma once #include #include #include // Tilemap basat en tiles 16×16 (o la mida que indique el yaml). El mapa es // prerenderitza una sola vegada a un buffer ARGB propi a la construcció; a // partir d'aquí, cada render és una simple còpia de píxels clipada sobre el // canvas del joc. Això evita recórrer la graella de tiles cada frame. // // Les cel·les sense tile (p.ex. les caselles dels sarcòfags, que es faran // actors independents) es deixen transparents (alpha=0) i el canvas // subjacent hi queda visible. class Tilemap { public: // Carrega el yaml (camí relatiu o absolut), el tileset referenciat i // prerenderitza la graella a memòria. explicit Tilemap(const std::string& yaml_path); // Dibuixa la textura prerenderitzada al canvas a l'origen del yaml. // Offsets negatius permeten overscan (textura més gran que el canvas). void render() const; [[nodiscard]] auto getWidth() const -> int { return width_px_; } [[nodiscard]] auto getHeight() const -> int { return height_px_; } [[nodiscard]] auto getOriginX() const -> int { return origin_x_; } [[nodiscard]] auto getOriginY() const -> int { return origin_y_; } // Metadades per a consumidors que necessiten conèixer la geometria // lògica del tilemap (p.ex. l'editor per a la conversió px→cel·la). // Sempre disponibles (en Debug i Release) perquè són barates i no // lliguen amb cap codi específic de l'editor. [[nodiscard]] auto getTileSize() const -> int { return tile_size_; } [[nodiscard]] auto getCols() const -> int { return cols_; } [[nodiscard]] auto getRows() const -> int { return rows_; } [[nodiscard]] auto getTilesetPath() const -> const std::string& { return tileset_path_; } [[nodiscard]] auto getTilesetCols() const -> int { return tileset_cols_; } #ifdef _DEBUG // API d'edició (només Debug). L'editor és absent en Release, així que // aquestes operacions no formen part de l'API pública del joc final. // // `setTileAt` valida els límits i reemplaça el tile de (col,row) per // `index`. Internament neteja el rectangle `tile_size×tile_size` del // buffer de píxels i re-blita el tile nou; el render al pròxim frame // ja reflectirà el canvi. // // `save` persisteix `data_` al YAML indicat via `TilemapWriter`, que // només toca el bloc `data:` i preserva la resta byte a byte. void setTileAt(int col, int row, int index); [[nodiscard]] auto save(const std::string& yaml_path) const -> bool; // Pinta un únic tile del tileset sobre el canvas del Screen a la // posició (canvas_x, canvas_y). Els píxels transparents del tileset // es respecten (deixen visible el que hi ha sota). Usat per l'editor // com a preview del brush sota el cursor, sense tocar `pixels_` ni // `data_` fins que l'usuari fa click. void renderTilePreview(int canvas_x, int canvas_y, int tile_index) const; #endif private: int width_px_{0}; int height_px_{0}; int origin_x_{0}; int origin_y_{0}; int tile_size_{0}; int cols_{0}; int rows_{0}; int tileset_cols_{0}; std::string tileset_path_; std::vector pixels_; #ifdef _DEBUG // Graella en memòria només necessària per a l'editor: guardar-la en // Release gastaria ~1 KB sense retorn, perquè el `pixels_` ja té tot // el que cal per renderitzar. En Debug la usem com a font de veritat // de l'edició i com a payload de `save()`. std::vector> data_; #endif };