diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0ff0cb2..2eb96fe 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,10 +1,8 @@ name: CMake Build on: - push: - branches: [ develop ] pull_request: - branches: [ main, develop ] + branches: [ main ] permissions: contents: read diff --git a/README.md b/README.md index 0869c7c..aaad22d 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,14 @@ # Memory in SDL3 - ![Screenshot of the game](in_game.png) -This is a simple Memory game with creepy themes. +This is a simple Memory game with scary themes, developed with Simple DirectMedia Layer (SDL3). + +I am building this project to improve my system design and architecture skills. -It is developed with Simple DirectMedia Layer (SDL3). +And also for the fun of it, of course. +I deliberately avoided game engines for this project, allowing me implement everything that I want myself. +*** All used assets are made by me. ## Playing the game diff --git a/include/core/Game.h b/include/core/Game.h index bfa046a..efc24cd 100644 --- a/include/core/Game.h +++ b/include/core/Game.h @@ -7,7 +7,6 @@ #include class AssetManager; -class GridLayout; class SceneManager; class SoundSystem; @@ -33,7 +32,6 @@ class Game // Systems std::unique_ptr m_assetManager; - std::unique_ptr m_grid; std::unique_ptr m_soundSystem; std::unique_ptr m_sceneManager; diff --git a/include/core/GameContext.h b/include/core/GameContext.h index 4151d4d..096de28 100644 --- a/include/core/GameContext.h +++ b/include/core/GameContext.h @@ -1,6 +1,4 @@ -#ifndef MEMORYSDL_GAMECONTEXT_H -#define MEMORYSDL_GAMECONTEXT_H -#include "ui/GridLayout.h" +#pragma once #include "systems/AssetManager.h" #include "systems/SoundSystem.h" @@ -10,7 +8,6 @@ struct GameContext { SDL_Renderer *renderer; AssetManager *assetManager; - GridLayout *grid; SoundSystem *soundSystem; int windowWidth; @@ -18,12 +15,10 @@ struct GameContext int texWidth; int texHeight; - GameContext(SDL_Renderer* r, AssetManager *am, GridLayout *gl, SoundSystem *ss, + GameContext(SDL_Renderer* r, AssetManager *am, SoundSystem *ss, const int wWidth, const int wHeight, const int tw, const int th) - : renderer(r), assetManager(am), grid(gl), soundSystem(ss), windowWidth(wWidth), + : renderer(r), assetManager(am), soundSystem(ss), windowWidth(wWidth), windowHeight(wHeight), texWidth(tw), texHeight(th) {} -}; - -#endif //MEMORYSDL_GAMECONTEXT_H \ No newline at end of file +}; \ No newline at end of file diff --git a/include/game/Card.h b/include/game/Card.h new file mode 100644 index 0000000..34f7cff --- /dev/null +++ b/include/game/Card.h @@ -0,0 +1,38 @@ +#pragma once +#include "game/CardData.h" + +#include "SDL3/SDL_rect.h" +#include "SDL3/SDL_render.h" + +class Card +{ +public: + enum class CardState { FaceDown, FaceUp, Matched }; + + Card(const CardData& data, const SDL_FRect& rect, SDL_Texture* front, SDL_Texture* back) + : m_data(data), m_rect(rect), m_front(front), m_back(back) + {} + + void Render(SDL_Renderer* renderer) const; + void HandleEvent(const SDL_Event& event); + + bool TryFlip(); + void SetMatched(); + void FlipDown(); + + [[nodiscard]] bool IsFaceDown() const { return m_state == CardState::FaceDown; } + [[nodiscard]] bool IsFaceUp() const { return m_state == CardState::FaceUp; } + + //[[nodiscard]] const char *GetTexName() const { return m_data.frontKey.c_str(); } // NOTE: for testing + [[nodiscard]] int GetPairId() const { return m_data.pairId; } + [[nodiscard]] SDL_FRect GetRect() const { return m_rect; } + +private: + CardData m_data; + SDL_FRect m_rect; + + SDL_Texture* m_front; + SDL_Texture* m_back; + + CardState m_state = CardState::FaceDown; +}; \ No newline at end of file diff --git a/include/game/CardData.h b/include/game/CardData.h new file mode 100644 index 0000000..cf9c4b3 --- /dev/null +++ b/include/game/CardData.h @@ -0,0 +1,10 @@ +#pragma once +#include + +struct CardData +{ + int uniqueId = -1; + int pairId = -1; + std::string frontKey; + float rotation = 0.f; +}; \ No newline at end of file diff --git a/include/game/CardDeck.h b/include/game/CardDeck.h new file mode 100644 index 0000000..b4473e1 --- /dev/null +++ b/include/game/CardDeck.h @@ -0,0 +1,22 @@ +#pragma once +#include "game/Card.h" + +#include +#include +#include + +class CardDeck +{ +public: + CardDeck() : m_rng(std::random_device{}()) + {} + + void BuildDeck(const std::vector& frontKeys); + void ShuffleDeck(); + + [[nodiscard]] const std::vector& GetCards() const { return m_cards; } + +private: + std::vector m_cards; + std::mt19937 m_rng; +}; \ No newline at end of file diff --git a/include/scenes/EndScene.h b/include/scenes/EndScene.h index 4d28433..6b45050 100644 --- a/include/scenes/EndScene.h +++ b/include/scenes/EndScene.h @@ -1,39 +1,28 @@ -#ifndef MEMORYSDL_ENDSCENE_H -#define MEMORYSDL_ENDSCENE_H +#pragma once #include "scenes/Scene.h" + +#include "ui/UIElement.h" #include "scenes/SceneManager.h" +#include + class EndScene : public Scene { public: - explicit EndScene(SceneManager &manager, GameContext &context) - : Scene(context), m_sceneManager(manager) + explicit EndScene(SceneManager &manager, GameContext &context, const bool hasPlayerWon) + : Scene(context), m_sceneManager(manager), m_hasPlayerWon(hasPlayerWon) { - m_uiPlayButtonRect.x = static_cast(m_context.windowWidth) * 0.15f; - m_uiPlayButtonRect.y = static_cast(m_context.windowHeight) * 0.75f; - m_uiPlayButtonRect.w = static_cast(m_context.texWidth) * 0.5f; - m_uiPlayButtonRect.h = static_cast(m_context.texHeight) * 0.5f; - - m_uiQuitButtonRect.x = static_cast(m_context.windowWidth) * 0.75f; - m_uiQuitButtonRect.y = static_cast(m_context.windowHeight) * 0.75f; - m_uiQuitButtonRect.w = static_cast(m_context.texWidth) * 0.5f; - m_uiQuitButtonRect.h = static_cast(m_context.texHeight) * 0.5f; + InitUI(); } + void InitUI(); void HandleEvent(const SDL_Event &event) override; void Update(float dt) override; void Render(SDL_Renderer *renderer) override; private: SceneManager &m_sceneManager; - + bool m_hasPlayerWon; // UI - const char* m_uiPlayButtonText = "PLAY"; - const char* m_uiQuitButtonText = "QUIT"; - SDL_FRect m_uiPlayButtonRect{}; - SDL_FRect m_uiQuitButtonRect{}; - bool uiPlayPressed = false; - bool uiQuitPressed = false; -}; - -#endif //MEMORYSDL_ENDSCENE_H \ No newline at end of file + std::vector> m_ui; +}; \ No newline at end of file diff --git a/include/scenes/GameScene.h b/include/scenes/GameScene.h index a46751a..6a6b760 100644 --- a/include/scenes/GameScene.h +++ b/include/scenes/GameScene.h @@ -1,7 +1,13 @@ -#ifndef MEMORYSDL_GAMESCENE_H -#define MEMORYSDL_GAMESCENE_H +#pragma once +#include "game/CardDeck.h" #include "scenes/Scene.h" #include "scenes/SceneManager.h" +#include "ui/GridLayout.h" + +#include + +#include "ui/UIAttempts.h" +#include "ui/UIElement.h" constexpr auto MAX_ATTEMPTS = 5; @@ -9,24 +15,16 @@ class GameScene : public Scene { public: explicit GameScene(SceneManager &manager, GameContext &context) - : Scene(context), m_sceneManager(manager), m_gameState(GameState::Paused), m_numOfCardsMatched(0), + : Scene(context), m_sceneManager(manager), m_numOfCardsMatched(0), m_cardsSelected(CardSelected::NoCard), m_firstCardIdx(-1), - m_secondCardIdx(-1), m_resolveCardsAtMs(0), - m_attempts(MAX_ATTEMPTS) + m_secondCardIdx(-1), m_attempts(MAX_ATTEMPTS), + m_resolveCardsAtMs(0) { - constexpr auto size = static_cast(MAX_ATTEMPTS); - m_uiHeartRects.resize(size); - for (size_t i = 0; i < size; ++i) { - m_uiHeartRects[i].x = (static_cast(m_context.windowWidth) * 0.5f + static_cast( - m_context.texWidth * i) - static_cast(m_context.texWidth * m_attempts) / - 2); - m_uiHeartRects[i].y = static_cast(m_context.windowHeight) * 0.001f; - m_uiHeartRects[i].w = static_cast(m_context.texWidth); - m_uiHeartRects[i].h = static_cast(m_context.texHeight); - } + Init(); } + void Init(); void HandleEvent(const SDL_Event &event) override; void Update(float dt) override; void Render(SDL_Renderer *renderer) override; @@ -34,20 +32,21 @@ class GameScene : public Scene private: SceneManager &m_sceneManager; - enum class GameState { Running, Ended, Paused, Starting }; - GameState m_gameState; - + // State enum class CardSelected { NoCard, OneCard, TwoCards }; size_t m_numOfCardsMatched; CardSelected m_cardsSelected; int m_firstCardIdx; int m_secondCardIdx; + int m_attempts; Uint64 m_resolveCardsAtMs; static constexpr Uint64 m_revealDelayMs = 800; - std::vector m_uiHeartRects; - int m_attempts; -}; + std::unique_ptr m_deck; + std::vector m_cards; -#endif //MEMORYSDL_GAMESCENE_H \ No newline at end of file + // UI + std::unique_ptr m_grid; + std::unique_ptr m_uiAttempts; +}; \ No newline at end of file diff --git a/include/scenes/Scene.h b/include/scenes/Scene.h index 0ca2cb4..9086eab 100644 --- a/include/scenes/Scene.h +++ b/include/scenes/Scene.h @@ -1,5 +1,4 @@ -#ifndef MEMORYSDL_SCENE_H -#define MEMORYSDL_SCENE_H +#pragma once #include "core/GameContext.h" #include "SDL3/SDL_render.h" @@ -21,6 +20,4 @@ class Scene protected: GameContext& m_context; -}; - -#endif //MEMORYSDL_SCENE_H \ No newline at end of file +}; \ No newline at end of file diff --git a/include/scenes/SceneManager.h b/include/scenes/SceneManager.h index 6054ed0..79a1cf3 100644 --- a/include/scenes/SceneManager.h +++ b/include/scenes/SceneManager.h @@ -1,5 +1,4 @@ -#ifndef MEMORYSDL_SCENEMANAGER_H -#define MEMORYSDL_SCENEMANAGER_H +#pragma once #include "scenes/Scene.h" #include @@ -22,6 +21,4 @@ class SceneManager std::unique_ptr m_nextScene; bool m_quitRequested = false; -}; - -#endif //MEMORYSDL_SCENEMANAGER_H \ No newline at end of file +}; \ No newline at end of file diff --git a/include/scenes/StartScene.h b/include/scenes/StartScene.h index 3d216fe..2d20364 100644 --- a/include/scenes/StartScene.h +++ b/include/scenes/StartScene.h @@ -1,8 +1,11 @@ -#ifndef MEMORYSDL_STARTSCENE_H -#define MEMORYSDL_STARTSCENE_H +#pragma once #include "scenes/Scene.h" -class SceneManager; +#include "ui/Button.h" +#include "scenes/SceneManager.h" + +#include +#include class StartScene : public Scene { @@ -10,17 +13,11 @@ class StartScene : public Scene explicit StartScene(SceneManager &manager, GameContext& context) : Scene(context), m_sceneManager(manager) { - m_uiPlayButtonRect.x = static_cast(m_context.windowWidth) * 0.15f; - m_uiPlayButtonRect.y = static_cast(m_context.windowHeight) * 0.75f; - m_uiPlayButtonRect.w = static_cast(m_context.texWidth) * 0.5f; - m_uiPlayButtonRect.h = static_cast(m_context.texHeight) * 0.5f; - - m_uiQuitButtonRect.x = static_cast(m_context.windowWidth) * 0.75f; - m_uiQuitButtonRect.y = static_cast(m_context.windowHeight) * 0.75f; - m_uiQuitButtonRect.w = static_cast(m_context.texWidth) * 0.5f; - m_uiQuitButtonRect.h = static_cast(m_context.texHeight) * 0.5f; + InitUI(); } + void InitUI(); + void HandleEvent(const SDL_Event &event) override; void Update(float dt) override {}; void Render(SDL_Renderer *renderer) override; @@ -29,12 +26,5 @@ class StartScene : public Scene SceneManager &m_sceneManager; // UI - const char* m_uiPlayButtonText = "PLAY"; - const char* m_uiQuitButtonText = "QUIT"; - SDL_FRect m_uiPlayButtonRect{}; - SDL_FRect m_uiQuitButtonRect{}; - bool uiPlayPressed = false; - bool uiQuitPressed = false; -}; - -#endif //MEMORYSDL_STARTSCENE_H \ No newline at end of file + std::vector> m_ui; +}; \ No newline at end of file diff --git a/include/systems/AssetManager.h b/include/systems/AssetManager.h index 59f2d1d..f4ef0a7 100644 --- a/include/systems/AssetManager.h +++ b/include/systems/AssetManager.h @@ -7,20 +7,6 @@ class AssetManager { - //enum class TextureID - //{ - // UI_Heart, - // UI_PlayButton, - // UI_QuitButton, - // Card_Back, - // Card_Bat, - // Card_Candle, - // Card_Coffin, - // Card_Dagger, - // Card_Door, - // Card_Skull - //}; - public: explicit AssetManager(SDL_Renderer* renderer); ~AssetManager(); diff --git a/include/ui/Button.h b/include/ui/Button.h new file mode 100644 index 0000000..89f360d --- /dev/null +++ b/include/ui/Button.h @@ -0,0 +1,21 @@ +#pragma once +#include "UIElement.h" + +#include + +class Button : public UIElement +{ +public: + Button(const SDL_FRect rect, SDL_Texture* texture, + std::function onClick) + : m_rect(rect), m_texture(texture), m_onClick(onClick) + {} + + void HandleEvent(const SDL_Event& event) override; + void Render(SDL_Renderer* renderer) override; + +private: + SDL_FRect m_rect; + SDL_Texture* m_texture; + std::function m_onClick; +}; \ No newline at end of file diff --git a/include/ui/Card.h b/include/ui/Card.h deleted file mode 100644 index b338c8a..0000000 --- a/include/ui/Card.h +++ /dev/null @@ -1,14 +0,0 @@ -#pragma once - -#include - -enum class CardState { FaceDown, FaceUp, Matched }; - -struct Card -{ - int uniqueId = -1; - int pairId = -1; - CardState state = CardState::FaceDown; - std::string frontKey; - float rotation = 0.f; -}; \ No newline at end of file diff --git a/include/ui/GridLayout.h b/include/ui/GridLayout.h index fc8623d..95aab29 100644 --- a/include/ui/GridLayout.h +++ b/include/ui/GridLayout.h @@ -1,31 +1,24 @@ #pragma once -#include "ui/Card.h" - #include -#include -#include #include #include - class GridLayout { public: GridLayout(int rows, int columns); - ~GridLayout(); + ~GridLayout() = default; void InitGrid(int width, int height, int texWidth, int texHeight); + [[nodiscard]] size_t GetSize() const { return m_grid.size(); } - void BuildDeck(const std::vector& frontKeys); - void ShuffleDeck(); - void ResetCardStates(); + [[nodiscard]] const std::vector& GetRects() const { return m_grid; } - std::map m_grid; - std::vector m_cards; private: - std::mt19937 m_rng; + std::vector m_grid; + int m_rows = -1; int m_columns = -1; -}; \ No newline at end of file +}; diff --git a/include/ui/UIAttempts.h b/include/ui/UIAttempts.h new file mode 100644 index 0000000..bb7171c --- /dev/null +++ b/include/ui/UIAttempts.h @@ -0,0 +1,28 @@ +#pragma once +#include "ui/UIImage.h" +#include "core/GameContext.h" + +#include + + +class UIAttempts +{ +public: + UIAttempts(GameContext& context, SDL_Texture* texture, const int maxAttempts) + : m_context(context), m_texture(texture), m_maxAttempts(maxAttempts), m_attempts(maxAttempts) + { + Init(); + } + + void Init(); + void SetAttempts(const int attempts) { m_attempts = attempts; } + + void Render(SDL_Renderer* renderer); + +private: + GameContext& m_context; + SDL_Texture* m_texture; + std::vector m_images {}; + int m_maxAttempts; + int m_attempts; +}; \ No newline at end of file diff --git a/include/ui/UIElement.h b/include/ui/UIElement.h new file mode 100644 index 0000000..0b3f098 --- /dev/null +++ b/include/ui/UIElement.h @@ -0,0 +1,13 @@ +#pragma once +#include "SDL3/SDL_events.h" +#include "SDL3/SDL_render.h" + +class UIElement +{ +public: + virtual ~UIElement() = default; + + virtual void HandleEvent(const SDL_Event& event) {} + virtual void Update() {} + virtual void Render(SDL_Renderer* renderer) = 0; +}; \ No newline at end of file diff --git a/include/ui/UIImage.h b/include/ui/UIImage.h new file mode 100644 index 0000000..00c66de --- /dev/null +++ b/include/ui/UIImage.h @@ -0,0 +1,18 @@ +#pragma once +#include "UIElement.h" + +class UIImage : public UIElement +{ +public: + UIImage(SDL_Texture* texture, const SDL_FRect rect) + : m_texture(texture), m_rect(rect) + {} + + void SetScale(float scale); + + void Render(SDL_Renderer* renderer) override; + +private: + SDL_Texture* m_texture; + SDL_FRect m_rect{}; +}; \ No newline at end of file diff --git a/src/Game.cpp b/src/Game.cpp deleted file mode 100644 index e69de29..0000000 diff --git a/src/Game.h b/src/Game.h deleted file mode 100644 index e69de29..0000000 diff --git a/src/core/Game.cpp b/src/core/Game.cpp index 5e4a48b..d97545b 100644 --- a/src/core/Game.cpp +++ b/src/core/Game.cpp @@ -1,7 +1,6 @@ //#include "pch.h" #include "core/Game.h" -#include "ui/GridLayout.h" #include "scenes/SceneManager.h" #include "scenes/StartScene.h" #include "systems/AssetManager.h" @@ -21,7 +20,7 @@ constexpr auto TEX_HEIGHT = 32 * 3; Game::Game(SDL_Window* window, SDL_Renderer* renderer, const int width, const int height) : m_window(window), m_renderer(renderer), - m_windowWidth(width), m_windowHeight(height), m_gameContext(nullptr, nullptr, nullptr, nullptr, 0, 0, 0, 0) + m_windowWidth(width), m_windowHeight(height), m_gameContext(nullptr, nullptr, /*nullptr,*/ nullptr, 0, 0, 0, 0) { } @@ -32,18 +31,15 @@ Game::~Game() int Game::Init() { - const std::vector frontCards = { "Card_Skull", "Card_Coffin", "Card_Candle", "Card_Dagger", "Card_Bat", "Card_Door" }; - + const std::vector frontCards + { "Card_Skull", "Card_Coffin", "Card_Candle", "Card_Dagger", "Card_Bat", "Card_Door" }; + m_assetManager = std::make_unique(m_renderer); m_assetManager->LoadTexture("Card_Back"); - - // TESTING: - constexpr int numOfCards = 6; // set to number of cards that will be rendered - std::vector testingCards{}; - for (int i{}; i < numOfCards; ++i) + + for (const auto& tex : frontCards) { - m_assetManager->LoadTexture(frontCards[i]); - testingCards.push_back(frontCards[i]); + m_assetManager->LoadTexture(tex); } const std::vector uiTextures = { "UI_PlayButton", "UI_QuitButton", "UI_Heart"}; for (const auto& tex : uiTextures) @@ -51,17 +47,11 @@ int Game::Init() m_assetManager->LoadTexture(tex); } - m_grid = std::make_unique(numOfCards/2, 4); - m_grid->BuildDeck(testingCards); - m_grid->ShuffleDeck(); - m_grid->InitGrid(m_windowWidth, m_windowHeight, TEX_WIDTH, TEX_HEIGHT); - m_soundSystem = std::make_unique(); m_soundSystem->Init(); m_gameContext.renderer = m_renderer; m_gameContext.assetManager = m_assetManager.get(); - m_gameContext.grid = m_grid.get(); m_gameContext.soundSystem = m_soundSystem.get(); m_gameContext.windowWidth = m_windowWidth; m_gameContext.windowHeight = m_windowHeight; @@ -107,7 +97,7 @@ int Game::Update() const void Game::Resize() { SDL_GetWindowSizeInPixels(m_window, &m_windowWidth, &m_windowHeight); - m_grid->InitGrid(m_windowWidth, m_windowHeight, TEX_WIDTH, TEX_HEIGHT); + //m_grid->InitGrid(m_windowWidth, m_windowHeight, TEX_WIDTH, TEX_HEIGHT); } void Game::HandleEvent(const SDL_Event &event) const diff --git a/src/game/Card.cpp b/src/game/Card.cpp new file mode 100644 index 0000000..9715930 --- /dev/null +++ b/src/game/Card.cpp @@ -0,0 +1,32 @@ +#include "game/Card.h" + +void Card::Render(SDL_Renderer *renderer) const +{ + SDL_Texture* tex; + if (m_state == CardState::FaceUp || m_state == CardState::Matched) + tex = m_front; + else + tex = m_back; + + SDL_RenderTexture(renderer, tex, nullptr, &m_rect); +} + +bool Card::TryFlip() +{ + if (m_state != CardState::FaceDown) + return false; + + m_state = CardState::FaceUp; + return true; +} + +void Card::SetMatched() +{ + m_state = CardState::Matched; +} + +void Card::FlipDown() +{ + if (m_state == CardState::FaceUp) + m_state = CardState::FaceDown; +} diff --git a/src/game/CardDeck.cpp b/src/game/CardDeck.cpp new file mode 100644 index 0000000..aa45c88 --- /dev/null +++ b/src/game/CardDeck.cpp @@ -0,0 +1,24 @@ +#include "game/CardDeck.h" + +#include + +// Creates a List of shuffled cards +void CardDeck::BuildDeck(const std::vector &frontKeys) +{ + m_cards.clear(); + m_cards.reserve(frontKeys.size() * 2); + + int pairId = 0; + int uniqueId = 0; + for (const auto& key : frontKeys) + { + m_cards.push_back({uniqueId++, pairId, key, 0.0f}); + m_cards.push_back({uniqueId++, pairId, key, 0.0f}); + ++pairId; + } +} + +void CardDeck::ShuffleDeck() +{ + std::ranges::shuffle(m_cards.begin(), m_cards.end(), m_rng); +} diff --git a/src/main.cpp b/src/main.cpp index c27a576..5e27121 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -16,19 +16,19 @@ #include // Use this renderer to draw into this window every frame. -static SDL_Window* g_window = NULL; -static SDL_Renderer* g_renderer = NULL; +static SDL_Window* g_window = nullptr; +static SDL_Renderer* g_renderer = nullptr; constexpr auto WINDOW_WIDTH = 640; constexpr auto WINDOW_HEIGHT = 480; -constexpr auto GAME_VERSION = "0.3"; +constexpr auto GAME_VERSION = "0.4"; std::unique_ptr g_game = nullptr; // This function runs once at startup. SDL_AppResult SDL_AppInit(void** appstate, int argc, char* argv[]) { - SDL_SetAppMetadata("Spooky Memory", GAME_VERSION, "com.example.spookymemory"); + SDL_SetAppMetadata("MemorySDL", GAME_VERSION, "com.example.MemorySDL"); if (!SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO)) diff --git a/src/scenes/EndScene.cpp b/src/scenes/EndScene.cpp index 432db9f..c5ee0fa 100644 --- a/src/scenes/EndScene.cpp +++ b/src/scenes/EndScene.cpp @@ -1,22 +1,54 @@ #include "scenes/EndScene.h" +#include "ui/Button.h" #include "scenes/GameScene.h" +#include "memory" + +void EndScene::InitUI() +{ + SDL_FRect tmpButton + { + static_cast(m_context.windowWidth) * 0.15f, + static_cast(m_context.windowHeight) * 0.75f, + static_cast(m_context.texWidth) * 0.5f, + static_cast(m_context.texHeight) * 0.5f + }; + SDL_Texture* play = m_context.assetManager->GetTexture("UI_PlayButton"); + m_ui.push_back(std::make_unique