From ea72294a3ef7e08e41df440c988471c9be514d10 Mon Sep 17 00:00:00 2001 From: n0ffie Date: Tue, 18 Mar 2025 23:00:42 +0100 Subject: [PATCH] Added Map Rendering --- CMakeLists.txt | 2 +- src/Game.cpp | 10 ++-- src/Game.hpp | 1 - src/Map/Map.cpp | 110 +++++++++++++++++++++++++++++++++--------- src/Map/Map.hpp | 18 ++++--- src/Map/TileAtlas.cpp | 38 --------------- src/Map/TileAtlas.hpp | 23 --------- utils/MapFile.hexpat | 9 ++++ 8 files changed, 114 insertions(+), 97 deletions(-) delete mode 100644 src/Map/TileAtlas.cpp delete mode 100644 src/Map/TileAtlas.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 62a6637..f55dd74 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -55,7 +55,7 @@ target_link_libraries(colysis target_compile_definitions(colysis PUBLIC "$<$:_DEBUG>") -target_include_directories(colysis PUBLIC include ) +target_include_directories(colysis PUBLIC include) # put the assets folder path as a C preprocessor define set(ASSETS_PATH "${CMAKE_CURRENT_SOURCE_DIR}/assets/") diff --git a/src/Game.cpp b/src/Game.cpp index 433b1c7..5dc5208 100644 --- a/src/Game.cpp +++ b/src/Game.cpp @@ -2,8 +2,6 @@ Game::Game(sf::RenderWindow& window) : window(window) { - enemies.emplace_back(sf::Vector2f{100, 100}); - enemies.emplace_back(sf::Vector2f{200, 200}); } #include @@ -22,12 +20,16 @@ void Game::run() std::cout << "Loading took: " << milliseconds << std::endl; #endif + map.setPosition(sf::Vector2f{20, 20}); + if (err.code != 0) { std::cout << err.message << std::endl; return; } +#ifdef _DEBUG map.debug(); +#endif while (window.isOpen()) { while (const auto event = window.pollEvent()) @@ -42,10 +44,6 @@ void Game::run() // Render game window.clear({0x20, 0x20, 0x20,0xff}); - for (auto& enemy : enemies) - { - window.draw(enemy); - } window.draw(map); window.display(); diff --git a/src/Game.hpp b/src/Game.hpp index 1ae6d20..8f79ccc 100644 --- a/src/Game.hpp +++ b/src/Game.hpp @@ -8,7 +8,6 @@ #include class Game { - std::vector enemies; Map map; public: explicit Game(sf::RenderWindow& window); diff --git a/src/Map/Map.cpp b/src/Map/Map.cpp index e9511c9..22d0e81 100644 --- a/src/Map/Map.cpp +++ b/src/Map/Map.cpp @@ -24,28 +24,85 @@ auto operator<=>(int lhs, TileType rhs) MapError Map::populate_vertex_array() { if (!tiles) return {"Map: [Loading] Tilemap is not loaded", 2}; - vertices.setPrimitiveType(sf::PrimitiveType::Triangles); - vertices.resize(map_size.x * map_size.y); + atlas.vertices.setPrimitiveType(sf::PrimitiveType::Triangles); + atlas.vertices.resize(map_size.x * map_size.y * 6); - for (uint32_t x = 0; x < map_size.x; x++) { - for (uint32_t y = 0; y < map_size.y; ++y) + const auto xw = static_cast(atlas.tile_size.x); + const auto yw = static_cast(atlas.tile_size.y); + const auto tex_w = static_cast(atlas.tile_size.x); + const auto tex_h = static_cast(atlas.tile_size.y); + for (uint32_t x = 0; x < map_size.y; x++) { + for (uint32_t y = 0; y < map_size.z; y++) { - uint32_t tile = tiles[x + y * map_size.y]; + const int32_t tile = tiles[x + y * map_size.y]; + if (tile < -atlas.wall_tiles || tile > atlas.other_tiles) return {"Map: [Loading] Invalid tile! Tile type does not have a texture; ID: " + std::to_string(tile), 3}; + // map tile type to atlas /* - * ----- - * --#++ - * +++++ + * Atlas: + * +++++ + * +++-- + * ---## * - * + = other - * - = wall - * # = special + * + = wall + * # = special + * - = other + * + * wall_tiles = 8 + * other_tiles = 5 + * special_tiles = 2 + * + * Tile: + * -1 <= wall + * 0 == special @ .type == tile_type + * 1 >= other */ + if (tile == 0) return {"Map: [Loading] [Not Implemented!] Tile is a special tile", 3}; + + // atlas tile index + const uint32_t atlas_tile = atlas.wall_tiles + (tile - 1); + if (atlas_tile >= atlas.wall_tiles + atlas.other_tiles) return {"Map: [Loading] Invalid tile! Tile type does not have a texture", 3}; + + // add the vertices + const auto xf = static_cast(x); + const auto yf = static_cast(y); + const uint32_t tile_x = atlas_tile % atlas.tile_count.x; + const uint32_t tile_y = atlas_tile / atlas.tile_count.x; + const auto tex_x = static_cast(tile_x * atlas.tile_size.x); + const auto tex_y = static_cast(tile_y * atlas.tile_size.y); + + sf::Vertex tl = {{xf, yf}, sf::Color::White, {tex_x, tex_y}}; + sf::Vertex tr = {{xf + xw, yf}, sf::Color::White, {tex_x + tex_w, tex_y}}; + sf::Vertex bl = {{xf, yf + yw}, sf::Color::White, {tex_x, tex_y + tex_h}}; + sf::Vertex br = {{xf + xw, yf + yw}, sf::Color::White, {tex_x + tex_w, tex_y + tex_h}}; + + atlas.vertices.append(tl); + atlas.vertices.append(tr); + atlas.vertices.append(bl); + + atlas.vertices.append(bl); + atlas.vertices.append(tr); + atlas.vertices.append(br); } } + + + return {"Map: [Loading] Success", 0}; } -Map::Map() {} +void Map::LoadDefaultTilemap() { + atlas.wall_tiles = 0; + atlas.other_tiles = 1; + atlas.special_tiles = 0; + atlas.tile_count = {1, 1}; + atlas.tile_size = {16, 16}; + if (!atlas.texture.loadFromFile(ASSETS_PATH "/default_tilemap.png")) { + throw std::runtime_error("Map: [Loading] Could not load default tilemap -> Fatal"); + } +} + +Map::Map(): atlas() { +} #include @@ -57,11 +114,16 @@ MapError Map::load(const std::filesystem::path& path) { // opening the file and checking the magic number std::ifstream file(path, std::ios::binary | std::ios::in); - uint32_t magic; - file.read(reinterpret_cast(&magic), 4); - if (std::memcmp(&magic, "CYMF", 4) != 0) { - return {"Map: [Loading] Invalid magic number: " + std::string(reinterpret_cast(&magic), 4) + " (expected CYMF)", 1}; + if (!file.is_open()) { + return {"Map: [Loading] Could not open file: " + path.string(), 1}; + } + + char magic[4]; + file.read(magic, 4); + + if (std::memcmp(magic, "CYMF", 4) != 0) { + return {"Map: [Loading] Invalid magic number: " + std::string(magic, 4) + " (expected CYMF)", 1}; } // reading the version @@ -85,9 +147,13 @@ MapError Map::load(const std::filesystem::path& path) char* filepath_buffer = new char[filepath_buffer_size]; file.read(filepath_buffer, filepath_buffer_size); + return {"Map: [Loading] [Not Implemented] Custom Tilemap is not implemented. Tilemap file: " + std::string(filepath_buffer, filepath_buffer_size), 1}; delete[] filepath_buffer; } + else { + LoadDefaultTilemap(); + } // load the map info @@ -96,8 +162,8 @@ MapError Map::load(const std::filesystem::path& path) map_size = sf::Vector3(static_cast(map_info[0])*map_info[1], map_info[0], map_info[1]); // load the tiles - tiles = new int[map_info[0] * map_info[1] + map_info[2] * (sizeof(MapSpecial)/4)]; - for (int i = 0; i < map_info[0] * map_info[1] + map_info[2] * (sizeof(MapSpecial)/4); i++) + tiles = new int[map_info[0] * map_info[1]]; + for (int i = 0; i < map_info[0] * map_info[1]; i++) { // read the special if needed file.read(reinterpret_cast(&tiles[i]), 4); @@ -153,7 +219,7 @@ MapError Map::load(const std::filesystem::path& path) } // Everything went well - return {"Map: [Loading] Success", 0}; + return populate_vertex_array(); } sf::Vector2u Map::getSize() const @@ -169,10 +235,10 @@ void Map::draw(sf::RenderTarget& target, sf::RenderStates states) const states.transform *= getTransform(); // apply the tileset texture - states.texture = &texture; + states.texture = &atlas.texture; // draw the vertex array - target.draw(vertices, states); + target.draw(atlas.vertices, states); } @@ -181,7 +247,7 @@ void Map::debug() { std::cout << "Map Debug" << std::endl; std::cout << "\tSize : " << map_size.x << ", " << map_size.y << ", " << map_size.z << std::endl; - std::cout << "\tTiles : 0x" << tiles << std::endl; + std::cout << "\tTiles : " << tiles << std::endl; for (auto& special : specials) { std::cout << "\t\tSpecial : " << special.first.x << ", " << special.first.y << std::endl; diff --git a/src/Map/Map.hpp b/src/Map/Map.hpp index c56c5ec..ac0d600 100644 --- a/src/Map/Map.hpp +++ b/src/Map/Map.hpp @@ -71,17 +71,21 @@ struct MapError }; -#include "TileAtlas.hpp" - class Map : public sf::Drawable, public sf::Transformable { static_assert(sizeof(MapSpecial)%4 == 0); - sf::Vector2u tile_size; - sf::Vector2u tile_count; - sf::Texture texture; - sf::VertexArray vertices; + struct { + sf::Vector2u tile_size; + sf::Vector2u tile_count; + uint32_t wall_tiles; + uint32_t other_tiles; + uint32_t special_tiles; + + sf::Texture texture; + sf::VertexArray vertices; + } atlas; sf::Vector3 map_size; // width * height, width, height int *tiles = nullptr; @@ -93,6 +97,8 @@ class Map : public sf::Drawable, public sf::Transformable MapError populate_vertex_array(); + void LoadDefaultTilemap(); + public: Map(); diff --git a/src/Map/TileAtlas.cpp b/src/Map/TileAtlas.cpp deleted file mode 100644 index b3277ed..0000000 --- a/src/Map/TileAtlas.cpp +++ /dev/null @@ -1,38 +0,0 @@ -#include "TileAtlas.hpp" - -TileAtlas TileAtlas::defaultAtlas() -{ - TileAtlas atlas(sf::Vector2u{16, 16}, sf::Vector2u{16, 16}, ASSETS_PATH "/default_tilemap.png"); - return atlas; -} - -void TileAtlas::set(uint32_t x, uint32_t y) -{ - if (x >= tile_count.x || y >= tile_count.y) return; -} - -TileAtlas::TileAtlas(const sf::Vector2u tile_size, const sf::Vector2u tile_count, const std::filesystem::path& path) : - tile_size(tile_size), tile_count(tile_count) { load(path); } - -TileAtlas::TileAtlas(sf::Vector2u tile_size, sf::Vector2u tile_count) : tile_size(tile_size), tile_count(tile_count) -{ -} - -void TileAtlas::load(const std::filesystem::path& path) { - if (!texture.loadFromFile(path)) - { - throw std::runtime_error("TileAtlas: [Loading] Could not load tilemap -> Fatal"); - } -} - -void TileAtlas::draw(sf::RenderTarget& target, sf::RenderStates states) const -{ - // apply the transform - states.transform *= getTransform(); - - // apply the tileset texture - states.texture = &texture; - - // draw the vertex array - target.draw(vertices, states); -} \ No newline at end of file diff --git a/src/Map/TileAtlas.hpp b/src/Map/TileAtlas.hpp deleted file mode 100644 index cbe08a4..0000000 --- a/src/Map/TileAtlas.hpp +++ /dev/null @@ -1,23 +0,0 @@ -#pragma once -#include - -class TileAtlas : public sf::Drawable, public sf::Transformable -{ - sf::Vector2u tile_size; - sf::Vector2u tile_count; - -public: - explicit TileAtlas(sf::Vector2u tile_size, sf::Vector2u tile_count, const std::filesystem::path& path); - TileAtlas(sf::Vector2u tile_size, sf::Vector2u tile_count); - - void load(const std::filesystem::path& path); - - static TileAtlas defaultAtlas(); - - void set(uint32_t, uint32_t); - - void draw(sf::RenderTarget& target, sf::RenderStates states) const override; - -private: - -}; \ No newline at end of file diff --git a/utils/MapFile.hexpat b/utils/MapFile.hexpat index 7711e85..ac8e35d 100644 --- a/utils/MapFile.hexpat +++ b/utils/MapFile.hexpat @@ -10,8 +10,17 @@ bitfield OptionFlags { bool CustomeTilemap : 1; }; +struct vec2 { + T x,y; +}[[single_color]]; struct TilemapInfo { + vec2 dimentions; + vec2 tile_size; + vec2 tile_count; + u32 wall_tiles; + u32 other_tiles; + u32 special_tiles; }; struct Options {