From 70260c01bbaf70755ecffeb7c7f9b55190056367 Mon Sep 17 00:00:00 2001 From: Benedikt Galbavy Date: Sun, 17 Nov 2024 12:39:14 +0100 Subject: [PATCH] structural improvements & code comments --- include/Map.h | 72 ++++++++++++++++++++++++++++++++------------------- src/Map.cpp | 42 +++++++----------------------- 2 files changed, 55 insertions(+), 59 deletions(-) diff --git a/include/Map.h b/include/Map.h index ed9af33..3a6019a 100644 --- a/include/Map.h +++ b/include/Map.h @@ -1,50 +1,44 @@ #pragma once -#include "tmxlite/Map.hpp" -#include "tmxlite/TileLayer.hpp" #include -#include #include -#include -#include #include #include +#include +#include +#include +#include + class GameInternal; class Map { public: - Map(const char* path); - - //[[deprecated("ID based text files are not supported anymore, use .tmx maps instead")]] - //static void loadMap(const char* path, int sizeX, int sizeY, GameInternal* game, const std::map>* textureDict /* backreference */); - //[[deprecated]] - //static void addTile(unsigned long id, int x, int y, GameInternal* game, const std::map>* textureDict); - /*! * \brief Loads a .tmx map + * \details Loads a `.tmx` file and extracts all relevant data. Any entities (including tiles) are only spawned once * \param path Path to the `.tmx` map file - * + * \sa Map::generateTiles() */ - - void generateTiles(); + Map(const char* path); + void generateTiles(); //!< Generates the map based on the loaded definition private: - // required for initialisation + // struct required for initialisation struct MapData { - const std::vector* tileSets; - const std::vector* mapLayers; - const tmx::Vector2u* mapSize; - const tmx::Vector2u* mapTileSize; - const std::vector* texturePaths; + const std::vector* tileSets; + const std::vector* mapLayers; + const tmx::Vector2u* mapSize; + const tmx::Vector2u* mapTileSize; + const std::vector* texturePaths; }; struct TileSetData { - const char* texturePath{}; - tmx::Vector2i textureSize; - uint32_t tileCount{}; - tmx::Vector2u tileCount2D; - uint32_t firstGID{}; - }; + const char* texturePath{}; + tmx::Vector2i textureSize; + uint32_t tileCount{}; + tmx::Vector2u tileCount2D; + uint32_t firstGID{}; + }; tmx::Map map; Map::MapData mapData; @@ -55,4 +49,28 @@ private: template static std::optional getLayerProperty(const std::vector& properties, std::string propertyName) { return std::nullopt; }; + template<> std::optional getLayerProperty(const std::vector& properties, std::string propertyName) { + auto zIndexIterator = std::ranges::find_if(properties, [propertyName](const tmx::Property& property) { + return property.getName().compare(propertyName) == 0; + }); + + if (zIndexIterator != properties.end() && zIndexIterator->getType() == tmx::Property::Type::Boolean) { + return zIndexIterator->getBoolValue(); + } + + return std::nullopt; + } + + template<> std::optional getLayerProperty(const std::vector& properties, std::string propertyName) + { + auto zIndexIterator = std::ranges::find_if(properties, [propertyName](const tmx::Property& property) { + return property.getName().compare(propertyName) == 0; + }); + + if (zIndexIterator != properties.end() && zIndexIterator->getType() == tmx::Property::Type::Int) { + return zIndexIterator->getIntValue(); + } + + return std::nullopt; + } }; \ No newline at end of file diff --git a/src/Map.cpp b/src/Map.cpp index 975b83b..e75db70 100644 --- a/src/Map.cpp +++ b/src/Map.cpp @@ -5,13 +5,8 @@ #include #include #include -#include -#include #include #include -#include -#include -#include #include #include @@ -22,39 +17,14 @@ #include #include #include +#include #include "ColliderComponent.h" -#include "Constants.h" #include "GameInternal.h" #include "SpriteComponent.h" #include "TextureManager.h" #include "TileComponent.h" #include "VEGO.h" -#include "tmxlite/Types.hpp" - -template<> std::optional Map::getLayerProperty(const std::vector& properties, std::string propertyName) { -auto zIndexIterator = std::ranges::find_if(properties, [propertyName](const tmx::Property& property) { - return property.getName().compare(propertyName) == 0; -}); - -if (zIndexIterator != properties.end() && zIndexIterator->getType() == tmx::Property::Type::Boolean) { - return zIndexIterator->getBoolValue(); -} - -return std::nullopt; -} - -template<> std::optional Map::getLayerProperty(const std::vector& properties, std::string propertyName) { -auto zIndexIterator = std::ranges::find_if(properties, [propertyName](const tmx::Property& property) { - return property.getName().compare(propertyName) == 0; -}); - -if (zIndexIterator != properties.end() && zIndexIterator->getType() == tmx::Property::Type::Int) { - return zIndexIterator->getIntValue(); -} - -return std::nullopt; -} Map::Map(const char* path) { @@ -65,7 +35,7 @@ Map::Map(const char* path) std::vector texturePaths = {}; - for (auto tileSet : map.getTilesets()) { + for (const auto& tileSet : map.getTilesets()) { texturePaths.emplace_back(tileSet.getImagePath()); } @@ -99,8 +69,10 @@ void Map::loadTileLayer(const tmx::TileLayer& layer) const auto& tiles = layer.getTiles(); + // for each tile set auto tileConstructorRange = std::views::iota(0) | std::views::take(this->mapData.tileSets->size()) + // return the tile set metadata | std::views::transform([&](uint16_t i) { const char* texturePath = this->mapData.texturePaths->at(i).c_str(); @@ -121,14 +93,17 @@ void Map::loadTileLayer(const tmx::TileLayer& layer) return TileSetData { texturePath, textureSize, tileCount, tileCount2D, firstGID }; }) | std::views::transform([=, this](const TileSetData& data) { + // for each tile on the tile set return std::views::iota(0) | std::views::take(this->mapData.mapSize->x * this->mapData.mapSize->y) + // only take tiles that are on the ID range of the tile set | std::views::filter([=](uint16_t idx) { return idx < tiles.size() && tiles[idx].ID >= data.firstGID && tiles[idx].ID < (data.firstGID + data.tileCount); }) + // extract tile data | std::views::transform([=, this](uint16_t idx) { const auto x = idx % this->mapData.mapSize->x; const auto y = idx / this->mapData.mapSize->x; @@ -148,6 +123,7 @@ void Map::loadTileLayer(const tmx::TileLayer& layer) const float tilePosX = static_cast(x) * this->mapData.mapTileSize->x; const float tilePosY = (static_cast(y) * this->mapData.mapTileSize->y); + // return tile data as a function to spawn said tile return std::function( [tilePosX, tilePosY, capture0 = *this->mapData.mapTileSize, u, v, zIndex, capture1 = data.texturePath, collision] { Map::addTile(tilePosX, tilePosY, capture0, u, v, zIndex, capture1, collision); @@ -155,6 +131,7 @@ void Map::loadTileLayer(const tmx::TileLayer& layer) ); }); }) + // 2D view to 1D vector; might be better keep as view with scene management | std::views::join | std::ranges::to(); @@ -169,6 +146,7 @@ void Map::addTile(float x, float y, const tmx::Vector2u& mapTileSize, int u, int tile.addComponent("assets/grassy-river-tiles.png" /*texturePath*/, v, u, zIndex); // why does uv need to be reversed? if (hasCollision) { + // tag currently does not have a clear purposes, TODO: figure out appropriate tag name tile.addComponent("hello I am a collider of a tile!"); tile.addGroup((size_t)Entity::GroupLabel::MAPTILES); }