0
0
mirror of https://github.com/Nimac0/SDL_Minigame synced 2026-01-12 13:43:41 +00:00

added loading of tmx files

This commit is contained in:
Benedikt Galbavy 2024-11-04 23:27:26 +01:00
parent 0179a27aaf
commit ba8dca8abc
7 changed files with 126 additions and 11 deletions

3
.gitmodules vendored
View File

@ -14,3 +14,6 @@
path = extern/SDL_ttf path = extern/SDL_ttf
url = https://github.com/libsdl-org/SDL_ttf.git url = https://github.com/libsdl-org/SDL_ttf.git
branch = release-2.22.x branch = release-2.22.x
[submodule "extern/tmxlite"]
path = extern/tmxlite
url = https://github.com/fallahn/tmxlite.git

View File

@ -17,10 +17,13 @@ set(SDL2TTF_VENDORED ON)
set(SDL2_SOURCE_DIR ${ENGINE_SOURCE_DIR}/extern/SDL”) set(SDL2_SOURCE_DIR ${ENGINE_SOURCE_DIR}/extern/SDL”)
set(TMXLITE_STATIC_LIB TRUE)
add_subdirectory(extern/SDL EXCLUDE_FROM_ALL) add_subdirectory(extern/SDL EXCLUDE_FROM_ALL)
add_subdirectory(extern/SDL_image EXCLUDE_FROM_ALL) add_subdirectory(extern/SDL_image EXCLUDE_FROM_ALL)
add_subdirectory(extern/SDL_mixer EXCLUDE_FROM_ALL) add_subdirectory(extern/SDL_mixer EXCLUDE_FROM_ALL)
add_subdirectory(extern/SDL_ttf EXCLUDE_FROM_ALL) add_subdirectory(extern/SDL_ttf EXCLUDE_FROM_ALL)
add_subdirectory(extern/tmxlite/tmxlite EXCLUDE_FROM_ALL)
file(GLOB_RECURSE SOURCES ${ENGINE_SOURCE_DIR}/src/*.cpp) file(GLOB_RECURSE SOURCES ${ENGINE_SOURCE_DIR}/src/*.cpp)
add_library(${PROJECT_NAME} ${SOURCES}) add_library(${PROJECT_NAME} ${SOURCES})
@ -33,6 +36,7 @@ target_link_libraries(${PROJECT_NAME} PUBLIC # should be private when all SDL fu
SDL2_image::SDL2_image-static SDL2_image::SDL2_image-static
SDL2_mixer::SDL2_mixer-static SDL2_mixer::SDL2_mixer-static
SDL2_ttf::SDL2_ttf-static SDL2_ttf::SDL2_ttf-static
tmxlite
) )
if(CMAKE_BUILD_TYPE MATCHES "Debug") if(CMAKE_BUILD_TYPE MATCHES "Debug")

1
extern/tmxlite vendored Submodule

@ -0,0 +1 @@
Subproject commit fcef1a28ade8406e290d5fd168a8950e6996844f

View File

@ -23,4 +23,6 @@ public:
*/ */
static void loadMap(const char* path, int sizeX, int sizeY, GameInternal* game, const std::map<int, std::pair<std::string, bool>>* textureDict /* backreference */); static void loadMap(const char* path, int sizeX, int sizeY, GameInternal* game, const std::map<int, std::pair<std::string, bool>>* textureDict /* backreference */);
static void addTile(unsigned long id, int x, int y, GameInternal* game, const std::map<int, std::pair<std::string, bool>>* textureDict); static void addTile(unsigned long id, int x, int y, GameInternal* game, const std::map<int, std::pair<std::string, bool>>* textureDict);
static void loadMapTmx(const char* path);
}; };

View File

@ -31,8 +31,12 @@ private:
uint8_t speed = 100; uint8_t speed = 100;
bool flipped = false; bool flipped = false;
int textureXOffset;
int textureYOffset;
public: public:
SpriteComponent(const char* path, int zIndex); SpriteComponent(const char* path, int zIndex);
SpriteComponent(const char* path, int xOffset, int yOffset, int zIndex);
SpriteComponent( SpriteComponent(
const char* path, const char* path,
bool isAnimated, bool isAnimated,

View File

@ -1,14 +1,28 @@
#include "Map.h" #include "Map.h"
#include <algorithm>
#include <cctype> #include <cctype>
#include <iostream> #include <iostream>
#include <fstream> #include <fstream>
#include <type_traits>
#include <utility> #include <utility>
#include <vector>
#include <SDL_error.h>
#include <SDL_render.h>
#include <tmxlite/Layer.hpp>
#include <tmxlite/Map.hpp>
#include <tmxlite/Tileset.hpp>
#include <tmxlite/Property.hpp>
#include <tmxlite/TileLayer.hpp>
#include "Constants.h" #include "Constants.h"
#include "GameInternal.h" #include "GameInternal.h"
#include "SDL_error.h" #include "SpriteComponent.h"
#include "TextureManager.h"
#include "TileComponent.h" #include "TileComponent.h"
#include "VEGO.h"
void Map::loadMap(const char* path, int sizeX, int sizeY, GameInternal* game, const std::map<int, std::pair<std::string, bool>>* textureDict /* backreference */) void Map::loadMap(const char* path, int sizeX, int sizeY, GameInternal* game, const std::map<int, std::pair<std::string, bool>>* textureDict /* backreference */)
{ {
@ -58,9 +72,96 @@ void Map::loadMap(const char* path, int sizeX, int sizeY, GameInternal* game, co
void Map::addTile(unsigned long id, int x, int y, GameInternal* game, const std::map<int, std::pair<std::string, bool>>* textureDict) // tile entity void Map::addTile(unsigned long id, int x, int y, GameInternal* game, const std::map<int, std::pair<std::string, bool>>* textureDict) // tile entity
{ {
printf("X: %d, Y: %d", x, y);
auto& tile(game->manager.addEntity()); auto& tile(game->manager.addEntity());
tile.addComponent<TileComponent>(x, y, TILE_SIZE, TILE_SIZE, id, textureDict); tile.addComponent<TileComponent>(x, y, TILE_SIZE, TILE_SIZE, id, textureDict);
if(tile.getComponent<TileComponent>().hasCollision()) tile.addComponent<ColliderComponent>(tile.getComponent<TileComponent>().getName().data()); if(tile.getComponent<TileComponent>().hasCollision()) tile.addComponent<ColliderComponent>(tile.getComponent<TileComponent>().getName().data());
tile.addGroup((size_t)Entity::GroupLabel::MAPTILES); tile.addGroup((size_t)Entity::GroupLabel::MAPTILES);
} }
void Map::loadMapTmx(const char* path)
{
tmx::Map map;
if (!map.load(path)) {
// TODO: log to console
}
const std::vector<tmx::Tileset>& tileSets = map.getTilesets();
const std::vector<tmx::Layer::Ptr>& mapLayers = map.getLayers();
const auto mapSize = map.getTileCount();
const auto mapTileSize = map.getTileSize();
std::vector<std::string> texturePaths = {};
for (auto tileSet : tileSets) {
texturePaths.emplace_back(tileSet.getImagePath());
}
for (auto& layer : mapLayers) {
if (layer->getType() == tmx::Layer::Type::Tile) {
auto& tileLayer = layer->getLayerAs<tmx::TileLayer>();
int zIndex = 0;
const std::vector<tmx::Property>& properties = layer->getProperties();
auto zIndexIterator = std::find_if(properties.begin(), properties.end(), [](const tmx::Property& property) {
return property.getName() == "zIndex";
});
if (zIndexIterator != properties.end() && std::is_same<decltype(zIndexIterator->getType()), int>::value) {
zIndex = zIndexIterator->getIntValue();
}
const auto& tiles = tileLayer.getTiles();
for (auto i = 0u; i < tileSets.size(); i++) {
auto tilesetTexture = VEGO_Game().textureManager->loadTexture(texturePaths.at(i).c_str());
int texX, texY;
SDL_QueryTexture(tilesetTexture, nullptr, nullptr, &texX, &texY);
const auto tileCountX = texX / mapTileSize.x;
const auto tileCountY = texY / mapTileSize.y;
for (auto y = 0u; y < mapSize.y; ++y) {
for (auto x = 0u; x < mapSize.x; ++x) {
const auto idx = y * mapSize.x + x;
if (idx < tiles.size() && tiles[idx].ID >= tileSets.at(i).getFirstGID()
&& tiles[idx].ID < (tileSets.at(i).getFirstGID() + tileSets.at(i).getTileCount())) {
auto idIndex = (tiles[idx].ID - tileSets.at(i).getFirstGID());
int u = idIndex % tileCountX;
int v = idIndex / tileCountY;
u *= mapTileSize.x; //TODO we should be using the tile set size, as this may be different from the map's grid size
v *= mapTileSize.y;
//normalise the UV
u /= texX;
v /= texY;
//vert pos
const float tilePosX = static_cast<float>(x) * mapTileSize.x;
const float tilePosY = (static_cast<float>(y) * mapTileSize.y);
auto& tile(VEGO_Game().manager.addEntity());
tile.addComponent<TransformComponent>(tilePosX, tilePosY, mapTileSize.x, mapTileSize.y, 1);
tile.addComponent<SpriteComponent>(texturePaths.at(i).c_str(), v, u, zIndex); // why does uv need to be reversed?
}
}
}
}
continue;
}
if (layer->getType() == tmx::Layer::Type::Object) {
// spawn objects
continue;
}
}
}

View File

@ -15,7 +15,12 @@
#include "Manager.h" #include "Manager.h"
#include "VEGO.h" #include "VEGO.h"
SpriteComponent::SpriteComponent(const char* path, int zIndex) : RenderObject(zIndex, VEGO_Game().renderManager) SpriteComponent::SpriteComponent(const char* path, int zIndex) : RenderObject(zIndex, VEGO_Game().renderManager), textureXOffset(0), textureYOffset(0)
{
this->texturePath = path;
}
SpriteComponent::SpriteComponent(const char* path, int xOffset, int yOffset, int zIndex) : RenderObject(zIndex, VEGO_Game().renderManager), textureXOffset(xOffset), textureYOffset(yOffset)
{ {
this->texturePath = path; this->texturePath = path;
} }
@ -25,7 +30,7 @@ SpriteComponent::SpriteComponent(
bool isAnimated, bool isAnimated,
std::map<std::string, std::unique_ptr<Animation>>* animationMap, std::map<std::string, std::unique_ptr<Animation>>* animationMap,
std::string defaultAnimation, std::string defaultAnimation,
int zIndex) : RenderObject(zIndex, VEGO_Game().renderManager) int zIndex) : RenderObject(zIndex, VEGO_Game().renderManager), textureXOffset(0), textureYOffset(0)
{ {
animated = isAnimated; animated = isAnimated;
@ -49,21 +54,16 @@ void SpriteComponent::init()
this->transform = &entity->getComponent<TransformComponent>(); this->transform = &entity->getComponent<TransformComponent>();
this->srcRect.x = this->srcRect.y = 0;
this->srcRect.w = transform->width; this->srcRect.w = transform->width;
this->srcRect.h = transform->height; this->srcRect.h = transform->height;
this->srcRect.x = this->textureXOffset * this->srcRect.w;
this->srcRect.y = this->textureYOffset * this->srcRect.h;;
this->update(); this->update();
} }
void SpriteComponent::update() void SpriteComponent::update()
{ {
if (animated) {
srcRect.x = srcRect.w * static_cast<int>((SDL_GetTicks() / speed) % frames);
}
srcRect.y = animationIndex * transform->height;
this->destRect.x = this->transform->position.x; this->destRect.x = this->transform->position.x;
this->destRect.y = this->transform->position.y; this->destRect.y = this->transform->position.y;
this->destRect.w = transform->width * transform->scale; this->destRect.w = transform->width * transform->scale;