diff --git a/.gitignore b/.gitignore index f50581f..b82b006 100644 --- a/.gitignore +++ b/.gitignore @@ -6,6 +6,8 @@ Makefile install_manifest.txt .cache/ build/ +cmake-build-debug/ +.idea/ # Compiled files *.suo diff --git a/.gitmodules b/.gitmodules index 84e7c1b..57f7b27 100644 --- a/.gitmodules +++ b/.gitmodules @@ -20,3 +20,6 @@ [submodule "docs/doxygen-awesome-css"] path = docs/doxygen-awesome-css url = https://github.com/jothepro/doxygen-awesome-css.git +[submodule "extern/magic_enum"] + path = extern/magic_enum + url = https://github.com/Neargye/magic_enum.git diff --git a/CMakeLists.txt b/CMakeLists.txt index 8934839..4f6988c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -24,6 +24,7 @@ add_subdirectory(extern/SDL_image EXCLUDE_FROM_ALL) add_subdirectory(extern/SDL_mixer EXCLUDE_FROM_ALL) add_subdirectory(extern/SDL_ttf EXCLUDE_FROM_ALL) add_subdirectory(extern/tmxlite/tmxlite EXCLUDE_FROM_ALL) +add_subdirectory(extern/magic_enum EXCLUDE_FROM_ALL) file(GLOB_RECURSE SOURCES ${ENGINE_SOURCE_DIR}/src/*.cpp) add_library(${PROJECT_NAME} ${SOURCES}) @@ -36,6 +37,7 @@ target_link_libraries(${PROJECT_NAME} PUBLIC # should be private when all SDL fu SDL2_image::SDL2_image-static SDL2_mixer::SDL2_mixer-static SDL2_ttf::SDL2_ttf-static + magic_enum::magic_enum tmxlite ) diff --git a/extern/magic_enum b/extern/magic_enum new file mode 160000 index 0000000..a72a053 --- /dev/null +++ b/extern/magic_enum @@ -0,0 +1 @@ +Subproject commit a72a0536c716fdef4f029fb43e1fd7e7b3d9ac9b diff --git a/include/AssetManager.h b/include/AssetManager.h index 1d3c97a..154b7ea 100644 --- a/include/AssetManager.h +++ b/include/AssetManager.h @@ -24,28 +24,24 @@ public: AssetManager(Manager* manager); ~AssetManager(); - void createProjectile(Vector2D pos, Vector2D velocity, int scale, int range, int speed, const char* texturePath, Entity* owner); - void createPowerup(Vector2D pos, std::function pickupFunc, std::string texturePath); + void createProjectile(Vector2D pos, Vector2D velocity, int scale, int range, int speed, Textures textureEnum, Entity* owner); + void createPowerup(Vector2D pos, std::function pickupFunc, Textures texture); Vector2D calculateSpawnPosition(); PowerupType calculateType(); - //texture management - void addTexture(std::string id, const char* path); // sound management void addSoundEffect(std::string id, const char* path); void addMusic(std::string id, const char* path); - SDL_Texture* getTexture(std::string id); Mix_Chunk* getSound(std::string id); Mix_Music* getMusic(std::string id); private: Manager* man; - std::map textures; std::map soundEffects; std::map music; }; diff --git a/include/Map.h b/include/Map.h index 244322e..5e96186 100644 --- a/include/Map.h +++ b/include/Map.h @@ -16,7 +16,7 @@ class Map public: /*! * \brief Loads a .tmx map - * \details Loads a `.tmx` file and extracts all relevant data. Any entities (including tiles) are only spawned once + * \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() */ diff --git a/include/SpriteComponent.h b/include/SpriteComponent.h index 0676549..444663d 100644 --- a/include/SpriteComponent.h +++ b/include/SpriteComponent.h @@ -5,6 +5,7 @@ #include #include +#include "TextureEnumBase.h" #include "AnimationHandler.h" #include "Component.h" #include "Direction.h" @@ -24,7 +25,7 @@ private: SDL_Texture* texture; SDL_Rect srcRect, destRect; - const char* texturePath; + Textures textureEnum; bool animated = false; uint8_t frames = 0; @@ -34,18 +35,23 @@ private: int textureXOffset; int textureYOffset; + //should be changed in the future as this is only for the tiles + const char* path; + public: - SpriteComponent(const char* path, int zIndex); + SpriteComponent(Textures texture, int zIndex); + SpriteComponent(Textures texture, int xOffset, int yOffset, int zIndex); SpriteComponent(const char* path, int xOffset, int yOffset, int zIndex); SpriteComponent( - const char* path, + Textures texture, bool isAnimated, std::map>* animationList, std::string defaultAnimation, int zIndex); ~SpriteComponent(); - void setTexture(const char* path); + void setTexture(Textures texture); + void setMapTileTexture(const char* path); void init() override; void update() override; diff --git a/include/TextureEnumBase.h b/include/TextureEnumBase.h new file mode 100644 index 0000000..75c3573 --- /dev/null +++ b/include/TextureEnumBase.h @@ -0,0 +1,3 @@ +#pragma once + +enum class Textures; \ No newline at end of file diff --git a/include/TextureManager.h b/include/TextureManager.h index 3e4f1c4..5e5cd02 100644 --- a/include/TextureManager.h +++ b/include/TextureManager.h @@ -6,6 +6,7 @@ #include #include #include +#include "TextureEnumBase.h" class TextureManager { @@ -15,13 +16,21 @@ class TextureManager for (auto& it : this->texture_cache) { SDL_DestroyTexture(it.second); } + for (auto& it : this->mapTile_texture_cache) { + SDL_DestroyTexture(it.second); + } } - std::map texture_cache; - - SDL_Texture* loadTexture(const char* fileName); + void addSingleTexture(Textures texture, const char* filePath); + void addTextures(const std::map& textures); + SDL_Texture* loadTexture(Textures texture); static std::vector splitSpriteSheet(SDL_Texture* spriteSheet, int width, int height, int spritesOnSheet); static void draw(SDL_Renderer* renderer, SDL_Texture* texture, SDL_Rect src, SDL_Rect dest, bool flipped = false); + + SDL_Texture* loadMapTileTexture(const char* path); + private: Manager* manager; + std::map texture_cache; + std::map mapTile_texture_cache; }; \ No newline at end of file diff --git a/include/TileComponent.h b/include/TileComponent.h index 8844daa..627bb93 100644 --- a/include/TileComponent.h +++ b/include/TileComponent.h @@ -3,8 +3,10 @@ #include #include #include +#include #include "Component.h" +#include "TextureEnumBase.h" class SpriteComponent; class TransformComponent; @@ -17,17 +19,27 @@ public: SDL_Rect tileRect; int tileID; - const char* path; + Textures texture; TileComponent() = default; - TileComponent(int x, int y, int w, int h, int id, const std::map>* textureDict); + TileComponent(int x, int y, int w, int h, int id, const std::map>* textureDict); ~TileComponent() = default; void init() override; - bool hasCollision(){return this->collision;} - std::string getName(){return this->tileName;} + bool hasCollision() { + return this->collision; + } + + std::string getName() { +#ifdef TEXTURE_ENUM_DEFINED + return std::string(magic_enum::enum_name(this->texture)); +#else + return "Undefined Enum"; +#endif + } + + private: bool collision; - std::string tileName; }; \ No newline at end of file diff --git a/src/AssetManager.cpp b/src/AssetManager.cpp index 25ce8ad..9ac14c1 100644 --- a/src/AssetManager.cpp +++ b/src/AssetManager.cpp @@ -15,14 +15,12 @@ #include "PowerupComponent.h" #include +#include "TextureEnumBase.h" + AssetManager::AssetManager(Manager* manager) : man(manager) {} AssetManager::~AssetManager() {} -void AssetManager::addTexture(std::string id, const char* path) { - textures.emplace(id, this->man->getGame()->textureManager->loadTexture(path)); -} - void AssetManager::addSoundEffect(std::string id, const char* path) { soundEffects.emplace(id, this->man->getGame()->soundManager->loadSound(path)); @@ -33,9 +31,6 @@ void AssetManager::addMusic(std::string id, const char* path) music.emplace(id, this->man->getGame()->soundManager->loadMusic(path)); } -SDL_Texture* AssetManager::getTexture(std::string id) { - return textures.at(id); -} Mix_Chunk* AssetManager::getSound(std::string id) { return soundEffects.at(id); @@ -46,23 +41,23 @@ Mix_Music* AssetManager::getMusic(std::string id) return music.at(id); } -void AssetManager::createProjectile(Vector2D pos, Vector2D velocity, int scale, int range, int speed, const char* texturePath, Entity* owner) { +void AssetManager::createProjectile(Vector2D pos, Vector2D velocity, int scale, int range, int speed, Textures textureEnum, Entity* owner) { auto& projectile(man->addEntity()); projectile.addComponent(pos.x, pos.y, 32, 32, scale); //32x32 is standard size for objects - projectile.addComponent(texturePath, 4); + projectile.addComponent(textureEnum, 4); projectile.addComponent(range, speed, velocity, owner); projectile.addComponent("projectile", 0.6f); projectile.addGroup((size_t)Entity::GroupLabel::PROJECTILE); } -void AssetManager::createPowerup(Vector2D pos, std::function pickupFunc, std::string texturePath) { +void AssetManager::createPowerup(Vector2D pos, std::function pickupFunc, Textures texture) { auto& powerups(man->addEntity()); powerups.addComponent(pos.x, pos.y, 32, 32, 1); //32x32 is standard size for objects try { - powerups.addComponent(texturePath.c_str(), 3); + powerups.addComponent(texture, 3); } catch (std::runtime_error e) { std::cout << e.what() << std::endl; diff --git a/src/GameInternal.cpp b/src/GameInternal.cpp index 0ef8c69..a66e994 100644 --- a/src/GameInternal.cpp +++ b/src/GameInternal.cpp @@ -98,6 +98,8 @@ void GameInternal::init(const char* title, int xpos, int ypos, int width, int he // loading music // assets->addMusic("background_music", "assets/sound/background_music.mp3"); + + this->gameInstance = GameFactory::instance().create(this); this->gameInstance->init(); } diff --git a/src/Map.cpp b/src/Map.cpp index dab109b..9eb9212 100644 --- a/src/Map.cpp +++ b/src/Map.cpp @@ -39,7 +39,7 @@ template<> std::optional Map::getLayerProperty(const std::vector std::optional Map::getLayerProperty(const std::vector& properties, std::string propertyName) +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; @@ -104,7 +104,7 @@ void Map::loadTileLayer(const tmx::TileLayer& layer) tmx::Vector2i textureSize; SDL_QueryTexture( - VEGO_Game().textureManager->loadTexture(texturePath), + VEGO_Game().textureManager->loadMapTileTexture(texturePath), nullptr, nullptr, &(textureSize.x), @@ -170,6 +170,7 @@ void Map::addTile(float x, float y, const tmx::Vector2u& mapTileSize, int u, int tile.addComponent(x, y, mapTileSize.x, mapTileSize.y, 1); tile.addComponent(texturePath.c_str(), v, u, zIndex); // why does uv need to be reversed? + //TODO: also implement updated map stuff for this if (hasCollision) { // tag currently does not have a clear purposes, TODO: figure out appropriate tag name @@ -178,7 +179,7 @@ void Map::addTile(float x, float y, const tmx::Vector2u& mapTileSize, int u, int } } -void Map::generateTiles() +void Map::generateTiles() { std::ranges::for_each(this->tileConstructors, [](auto& function) { function(); diff --git a/src/SpriteComponent.cpp b/src/SpriteComponent.cpp index ae27ea7..99c7690 100644 --- a/src/SpriteComponent.cpp +++ b/src/SpriteComponent.cpp @@ -3,6 +3,7 @@ #include #include #include +#include #include "AnimationHandler.h" #include "Direction.h" @@ -15,18 +16,25 @@ #include "Manager.h" #include "VEGO.h" -SpriteComponent::SpriteComponent(const char* path, int zIndex) : RenderObject(zIndex, VEGO_Game().renderManager), textureXOffset(0), textureYOffset(0) +SpriteComponent::SpriteComponent(Textures texture, int zIndex) : RenderObject(zIndex, VEGO_Game().renderManager), textureXOffset(0), textureYOffset(0) { - this->texturePath = path; + this->textureEnum = texture; + this->path = ""; } -SpriteComponent::SpriteComponent(const char* path, int xOffset, int yOffset, int zIndex) : RenderObject(zIndex, VEGO_Game().renderManager), textureXOffset(xOffset), textureYOffset(yOffset) +SpriteComponent::SpriteComponent(Textures texture, int xOffset, int yOffset, int zIndex) : RenderObject(zIndex, VEGO_Game().renderManager), textureXOffset(xOffset), textureYOffset(yOffset) { - this->texturePath = path; + this->textureEnum = texture; + this->path = ""; +} + +SpriteComponent::SpriteComponent(const char* path, int xOffset, int yOffset, int zIndex) : RenderObject(zIndex, VEGO_Game().renderManager), textureXOffset(xOffset), textureYOffset(yOffset) { + + this->path = path; } SpriteComponent::SpriteComponent( - const char* path, + Textures texture, bool isAnimated, std::map>* animationMap, std::string defaultAnimation, @@ -38,19 +46,26 @@ SpriteComponent::SpriteComponent( playAnimation(defaultAnimation); - this->texturePath = path; + this->textureEnum = texture; + + this->path = ""; } SpriteComponent::~SpriteComponent() {} -void SpriteComponent::setTexture(const char* path) +void SpriteComponent::setTexture(Textures texture) { - this->texture = VEGO_Game().textureManager->loadTexture(path); + this->texture = VEGO_Game().textureManager->loadTexture(texture); } void SpriteComponent::init() { - setTexture(this->texturePath); + if (this->path == "") { + setTexture(this->textureEnum); + } + else { + setMapTileTexture(this->path); + } this->transform = &entity->getComponent(); @@ -92,4 +107,8 @@ void SpriteComponent::playAnimation(std::string type) void SpriteComponent::setDirection(Direction direction) { this->flipped = direction == Direction::RIGHT; -} \ No newline at end of file +} + +void SpriteComponent::setMapTileTexture(const char *path) { + this->texture = VEGO_Game().textureManager->loadMapTileTexture(path); +} diff --git a/src/TextureManager.cpp b/src/TextureManager.cpp index 3e46d46..ff8e2fd 100644 --- a/src/TextureManager.cpp +++ b/src/TextureManager.cpp @@ -3,24 +3,57 @@ #include #include #include +#include +#include #include "GameInternal.h" -SDL_Texture* TextureManager::loadTexture(const char* fileName) -{ - auto it = this->texture_cache.find(fileName); - if (it != this->texture_cache.end()) { - return it->second; + +void TextureManager::addSingleTexture(Textures texture, const char* filePath) { + auto sdlTexture = IMG_LoadTexture(VEGO_Game().renderer, filePath); + + if (sdlTexture == nullptr) + throw std::runtime_error(std::string("Couldn't load texture '") + filePath + "'"); + + this->texture_cache.emplace(texture, sdlTexture); + std::cout << "Loaded texture at " << filePath << std::endl; +} + +void TextureManager::addTextures(const std::map &textures) { + for (auto texture : textures) { + addSingleTexture(texture.first, texture.second); } - auto texture = IMG_LoadTexture(this->manager->getGame()->renderer, fileName); - if (texture == NULL) throw std::runtime_error(std::string("Couldn't load texture '") + fileName + "'"); - this->texture_cache.emplace(std::string(fileName), texture); - printf("Loaded texture at '%s'\n", fileName); - return texture; +} + + +SDL_Texture* TextureManager::loadTexture(Textures texture) { + auto it = this->texture_cache.find(texture); + + if (it != this->texture_cache.end()) + return it->second; + + std::cout << "ERROR: Couldn't load texture!" << std::endl; + return nullptr; } void TextureManager::draw(SDL_Renderer* renderer, SDL_Texture* texture, SDL_Rect src, SDL_Rect dest, bool flipped) { SDL_RendererFlip flip = flipped ? SDL_FLIP_HORIZONTAL : SDL_FLIP_NONE; SDL_RenderCopyEx(renderer, texture, &src, &dest, 0, NULL, flip); -} \ No newline at end of file +} + +SDL_Texture* TextureManager::loadMapTileTexture(const char *path) { + + //returns tile if it exists already + if(mapTile_texture_cache.contains(std::string(path))) + return mapTile_texture_cache.find(std::string(path))->second; + + auto newTexture = IMG_LoadTexture(VEGO_Game().renderer, path); + + if (newTexture == nullptr) + throw std::runtime_error(std::string("Couldn't load texture '") + path + "'"); + + this->mapTile_texture_cache.emplace(std::string(path), newTexture); + + return newTexture; +} diff --git a/src/TileComponent.cpp b/src/TileComponent.cpp index 4c33bf7..5f36e2f 100644 --- a/src/TileComponent.cpp +++ b/src/TileComponent.cpp @@ -7,7 +7,9 @@ #include "SpriteComponent.h" #include "TileComponent.h" -TileComponent::TileComponent(int x, int y, int w, int h, int id, const std::map>* textureDict) +#include "TextureEnumBase.h" + +TileComponent::TileComponent(int x, int y, int w, int h, int id, const std::map>* textureDict) { this->tileRect.x = x; this->tileRect.y = y; @@ -22,8 +24,7 @@ TileComponent::TileComponent(int x, int y, int w, int h, int id, const std::map< } this->collision = it->second.second; - this->tileName = it->second.first; - this->path = it->second.first.data(); + this->texture = it->second.first; } void TileComponent::init() @@ -31,7 +32,7 @@ void TileComponent::init() this->entity->addComponent(this->tileRect.x, this->tileRect.y, this->tileRect.w, this->tileRect.h, 1); this->transform = &entity->getComponent(); - this->entity->addComponent(this->path, 0); + this->entity->addComponent(this->texture, 0); this->sprite = &entity->getComponent(); }