From 5e833bba513d97c39f4e0d26b45a9095c32812a6 Mon Sep 17 00:00:00 2001 From: WBoerenkamps Date: Mon, 28 Oct 2024 17:58:53 +0100 Subject: button working --- mwe/events/CMakeLists.txt | 37 +++++++++++-------- mwe/events/include/event.h | 20 +++++++++- mwe/events/include/eventHandler.h | 4 +- mwe/events/include/gameObject.h | 14 +++---- mwe/events/include/iMouseListener.h | 3 +- mwe/events/include/inputSystem.h | 16 ++++++++ mwe/events/include/loopManager.h | 7 ++++ mwe/events/include/uiObject.h | 17 +++++---- mwe/events/include/uiRenderer.h | 17 +++++++++ mwe/events/include/window.h | 28 +++++++++----- mwe/events/src/event.cpp | 4 +- mwe/events/src/inputSystem.cpp | 39 +++++++++++++++++++ mwe/events/src/loopManager.cpp | 61 +++++++++++++++++------------- mwe/events/src/uiObject.cpp | 2 +- mwe/events/src/uiRenderer.cpp | 72 ++++++++++++++++++++++++++++++++++++ mwe/events/src/window.cpp | 74 +++++++++++++++++++++++++------------ 16 files changed, 321 insertions(+), 94 deletions(-) create mode 100644 mwe/events/include/inputSystem.h create mode 100644 mwe/events/include/uiRenderer.h create mode 100644 mwe/events/src/inputSystem.cpp create mode 100644 mwe/events/src/uiRenderer.cpp (limited to 'mwe/events') diff --git a/mwe/events/CMakeLists.txt b/mwe/events/CMakeLists.txt index 096b8ad..12e45a7 100644 --- a/mwe/events/CMakeLists.txt +++ b/mwe/events/CMakeLists.txt @@ -2,34 +2,39 @@ cmake_minimum_required(VERSION 3.5) project(gameloop) # Set the C++ standard (optional, but good practice) -set(CMAKE_C_STANDARD 11) +set(CMAKE_C_STANDARD 17) set(CMAKE_CXX_STANDARD 20) set(CMAKE_EXPORT_COMPILE_COMMANDS 1) set(CMAKE_BUILD_TYPE Debug) # Find the SDL2 package find_package(SDL2 REQUIRED) +# Find the SDL2_ttf package +find_package(SDL2_ttf REQUIRED) add_executable(gameloop - src/window.cpp - src/main.cpp - src/eventManager.cpp - src/event.cpp - src/loopManager.cpp - src/timer.cpp - src/keyCodes.cpp - src/eventHandler.cpp - src/iMouseListener.cpp - src/iKeyListener.cpp - src/mouseListenerTest.cpp - src/keyListenerTest.cpp + src/window.cpp + src/main.cpp + src/eventManager.cpp + src/event.cpp + src/loopManager.cpp + src/timer.cpp + src/keyCodes.cpp + src/eventHandler.cpp + src/iMouseListener.cpp + src/iKeyListener.cpp + src/mouseListenerTest.cpp + src/keyListenerTest.cpp + src/inputSystem.cpp + src/uiRenderer.cpp + src/uiObject.cpp ) -add_subdirectory(../../lib/SDL_ttf SDL_ttf) -# Link the SDL2 library to your project -target_link_libraries(gameloop ${SDL2_LIBRARIES}) + +target_link_libraries(gameloop ${SDL2_LIBRARIES} SDL2_ttf::SDL2_ttf) # Include SDL2 header files and project headers target_include_directories(gameloop PRIVATE ${SDL2_INCLUDE_DIRS}) target_include_directories(gameloop PRIVATE ${CMAKE_SOURCE_DIR}/include) +# Copy font files to the build directory file(COPY ${PROJECT_SOURCE_DIR}/font DESTINATION ${CMAKE_BINARY_DIR}) diff --git a/mwe/events/include/event.h b/mwe/events/include/event.h index 65560a1..b1b6867 100644 --- a/mwe/events/include/event.h +++ b/mwe/events/include/event.h @@ -7,7 +7,6 @@ #include #include "keyCodes.h" #include "customTypes.h" - class UUIDGenerator { public: static std::uint32_t getUniqueID() { @@ -151,3 +150,22 @@ public: private: std::string text; }; +class ShutDownEvent : public Event { +public: + ShutDownEvent() : Event("ShutDownEvent"){}; + + REGISTER_EVENT_TYPE(ShutDownEvent) + +private: +}; +// class ButtonClickEvent : public Event { +// public: +// ButtonClickEvent(int x,int y,int width,int height); + +// REGISTER_EVENT_TYPE(TextSubmitEvent) + +// std::string getText() const; + +// private: +// std::string text; +// }; diff --git a/mwe/events/include/eventHandler.h b/mwe/events/include/eventHandler.h index 7414801..7d8f20a 100644 --- a/mwe/events/include/eventHandler.h +++ b/mwe/events/include/eventHandler.h @@ -1,9 +1,9 @@ #pragma once - #include "event.h" - #include #include + + template using EventHandler = std::function; diff --git a/mwe/events/include/gameObject.h b/mwe/events/include/gameObject.h index 70d4517..de5f3fe 100644 --- a/mwe/events/include/gameObject.h +++ b/mwe/events/include/gameObject.h @@ -3,14 +3,14 @@ #include class GameObject { public: - GameObject(std::uint32_t id, std::string name, std::string tag, int layer); + GameObject(){} - template - void addSpriteComponent(Args &&... args); - template - void addRigidbodyComponent(Args &&... args); - template - void addColiderComponent(Args &&... args); + // template + // void addSpriteComponent(Args &&... args); + // template + // void addRigidbodyComponent(Args &&... args); + // template + // void addColiderComponent(Args &&... args); std::uint32_t mId; std::string mName; diff --git a/mwe/events/include/iMouseListener.h b/mwe/events/include/iMouseListener.h index 03fd4c3..7d840c1 100644 --- a/mwe/events/include/iMouseListener.h +++ b/mwe/events/include/iMouseListener.h @@ -1,7 +1,8 @@ #pragma once #include "event.h" -#include "eventManager.h" #include "eventHandler.h" +#include "eventManager.h" + class IMouseListener { public: virtual ~IMouseListener(); diff --git a/mwe/events/include/inputSystem.h b/mwe/events/include/inputSystem.h new file mode 100644 index 0000000..06db74c --- /dev/null +++ b/mwe/events/include/inputSystem.h @@ -0,0 +1,16 @@ +#pragma once +#include +#include "uiObject.h" +#include "event.h" +#include "keyCodes.h" +#include "eventManager.h" +class InputSystem { +public: + InputSystem(); + void registerButton(Button* button); + void processInput(); + +private: + std::vector buttons; + void processMouseClick(int mouseX, int mouseY); +}; diff --git a/mwe/events/include/loopManager.h b/mwe/events/include/loopManager.h index baffb94..289ff0f 100644 --- a/mwe/events/include/loopManager.h +++ b/mwe/events/include/loopManager.h @@ -6,6 +6,10 @@ #include "eventHandler.h" #include "eventManager.h" #include "loopManager.h" +#include "uiRenderer.h" +#include "uiObject.h" +#include "inputSystem.h" +#include class LoopManager { public: LoopManager(); @@ -19,6 +23,7 @@ private: void lateUpdate(); void fixedUpdate(); void render(); + void onShutdown(const ShutDownEvent& e); bool gameRunning = false; WindowManager window; int timeScale = 1; @@ -26,4 +31,6 @@ private: double currentTime; double t = 0.0; double dt = 0.01; + std::unique_ptr inputSystem; + EventHandler shutdownHandler; }; diff --git a/mwe/events/include/uiObject.h b/mwe/events/include/uiObject.h index 46d32be..720d5c2 100644 --- a/mwe/events/include/uiObject.h +++ b/mwe/events/include/uiObject.h @@ -1,8 +1,10 @@ +#pragma once #include "gameObject.h" #include #include #include "event.h" #include "eventHandler.h" +#include struct Alignment { enum class Horizontal { LEFT, CENTER, RIGHT }; enum class Vertical { TOP, MIDDLE, BOTTOM }; @@ -21,28 +23,29 @@ struct Alignment { int marginRight = 0; }; struct RGBColor{ - int red, - int green, - int blue + int red; + int green; + int blue; }; class UIObject : public GameObject{ public: UIObject(int width,int height); - private: + virtual ~UIObject() {} int width; int height; + int x; + int y; }; class Button : public UIObject{ public: Button(int width,int height); - EventHandler onKeyPressed; - EventHandler onKeyReleased; + RGBColor color; + std::function onClick; }; class Text : public UIObject{ public: Text(int width,int height); - private: std::string text; int size; Alignment alignment; diff --git a/mwe/events/include/uiRenderer.h b/mwe/events/include/uiRenderer.h new file mode 100644 index 0000000..286ac1f --- /dev/null +++ b/mwe/events/include/uiRenderer.h @@ -0,0 +1,17 @@ +#pragma once +#include +#include +#include "uiObject.h" + +class UIRenderer { +public: + UIRenderer(SDL_Renderer* renderer); + void render(UIObject* uiObject); + +private: + SDL_Renderer* renderer; + + void renderButton(Button* button); + void renderText(Text* text); + void renderTextInput(TextInput* textInput); +}; diff --git a/mwe/events/include/window.h b/mwe/events/include/window.h index 9020b1a..3c34d4c 100644 --- a/mwe/events/include/window.h +++ b/mwe/events/include/window.h @@ -1,19 +1,27 @@ #pragma once #include -#include #include +#include "uiObject.h" +#include "uiRenderer.h" + class WindowManager { public: - WindowManager(); - virtual ~WindowManager(); - bool initWindow(); - void destroyWindow(); + WindowManager(); + virtual ~WindowManager(); + + bool initWindow(); + void destroyWindow(); + SDL_Renderer* getRenderer(); - SDL_Renderer * getRenderer(); + void addUIObject(UIObject* uiObject); + void renderUIObjects(); private: - const int SCREEN_WIDTH = 800; - const int SCREEN_HEIGHT = 600; - SDL_Window * window = NULL; - SDL_Renderer * renderer = NULL; + const int SCREEN_WIDTH = 800; + const int SCREEN_HEIGHT = 600; + SDL_Window* window = nullptr; + SDL_Renderer* renderer = nullptr; + + UIRenderer* uiRenderer; + std::vector uiObjects; }; diff --git a/mwe/events/src/event.cpp b/mwe/events/src/event.cpp index fc8eec9..0a7454d 100644 --- a/mwe/events/src/event.cpp +++ b/mwe/events/src/event.cpp @@ -54,7 +54,9 @@ Collision CollisionEvent::getCollisionData() const } TextSubmitEvent::TextSubmitEvent(std::string text) - : text(text), Event("TextSubmitEvent") {} + : text(text), Event("TextSubmitEvent") { + + } std::string TextSubmitEvent::getText() const { return this->text; diff --git a/mwe/events/src/inputSystem.cpp b/mwe/events/src/inputSystem.cpp new file mode 100644 index 0000000..ffab84b --- /dev/null +++ b/mwe/events/src/inputSystem.cpp @@ -0,0 +1,39 @@ +#include "inputSystem.h" + +InputSystem::InputSystem() {} + +void InputSystem::registerButton(Button* button) { + buttons.push_back(button); +} + +void InputSystem::processInput() { + + SDL_Event event; + while (SDL_PollEvent(&event)) { + switch (event.type) { + case SDL_QUIT: + triggerEvent(ShutDownEvent()); + break; + case SDL_KEYDOWN: + triggerEvent(KeyPressedEvent(getCustomKey(event.key.keysym.sym))); + break; + case SDL_MOUSEBUTTONDOWN: { + int mouseX, mouseY; + SDL_GetMouseState(&mouseX, &mouseY); + processMouseClick(mouseX, mouseY); + triggerEvent(MousePressedEvent(mouseX, mouseY)); + break; + } + } + } +} + +void InputSystem::processMouseClick(int mouseX, int mouseY) { + for (auto* button : buttons) { + if (mouseX >= button->x && mouseX <= (button->x + button->width) && + mouseY >= button->y && mouseY <= (button->y + button->height)) { + button->onClick(); + } + } +} + diff --git a/mwe/events/src/loopManager.cpp b/mwe/events/src/loopManager.cpp index 8ecb932..83ccfc3 100644 --- a/mwe/events/src/loopManager.cpp +++ b/mwe/events/src/loopManager.cpp @@ -1,22 +1,27 @@ #include "loopManager.h" -LoopManager::LoopManager() {} +LoopManager::LoopManager() + : inputSystem(std::make_unique()){ + shutdownHandler = [this](const ShutDownEvent& event) { this->onShutdown(event); }; + subscribe(shutdownHandler); +} void LoopManager::processInput() { - SDL_Event event; - SDL_PollEvent(&event); - switch (event.type) { - case SDL_QUIT: - gameRunning = false; - break; - case SDL_KEYDOWN: - triggerEvent(KeyPressedEvent(getCustomKey(event.key.keysym.sym))); - break; - case SDL_MOUSEBUTTONDOWN: - int x, y; - SDL_GetMouseState(&x, &y); - triggerEvent(MousePressedEvent(x, y)); - break; - } + inputSystem->processInput(); + // SDL_Event event; + // SDL_PollEvent(&event); + // switch (event.type) { + // case SDL_QUIT: + // gameRunning = false; + // break; + // case SDL_KEYDOWN: + // triggerEvent(KeyPressedEvent(getCustomKey(event.key.keysym.sym))); + // break; + // case SDL_MOUSEBUTTONDOWN: + // int x, y; + // SDL_GetMouseState(&x, &y); + // triggerEvent(MousePressedEvent(x, y)); + // break; + // } } void LoopManager::setRunning(bool running) { this->gameRunning = running; } void LoopManager::fixedUpdate() { @@ -28,9 +33,8 @@ void LoopManager::loop() { while (gameRunning) { timer.update(); - + processInput(); while (timer.getLag() >= timer.getFixedDeltaTime()) { - processInput(); fixedUpdate(); timer.advanceFixedUpdate(); } @@ -66,22 +70,29 @@ void LoopManager::setup() { } }; subscribe(closeWindowCallback, false); + Button* testButton = new Button(200,200); + testButton->color = {100,0,100}; + testButton->onClick = []() { + std::cout << "Button was clicked" << std::endl; + }; + testButton->x = 200; + testButton->y = 200; + inputSystem->registerButton(testButton); + + window.addUIObject(testButton); } void LoopManager::render() { //fprintf(stderr, "**********render********** \n"); if (gameRunning) { - //window.render(objectList); + window.renderUIObjects(); } } - +void LoopManager::onShutdown(const ShutDownEvent& e){ + this->gameRunning = false; +} void LoopManager::update() { //fprintf(stderr, "**********normal update********** \n"); LoopTimer & timer = LoopTimer::getInstance(); float delta = timer.getDeltaTime(); - - // for (int i = 0; i < objectList.size(); i++) { - // objectList[i]->setX(objectList[i]->getX() + 50 * delta); - // objectList[i]->setY(objectList[i]->getY() + 50 * delta); - // } } diff --git a/mwe/events/src/uiObject.cpp b/mwe/events/src/uiObject.cpp index b941858..ef4443f 100644 --- a/mwe/events/src/uiObject.cpp +++ b/mwe/events/src/uiObject.cpp @@ -2,7 +2,7 @@ // Constructor for UIObject UIObject::UIObject(int width, int height) - : width(width), height(height) { + : width(width), height(height){ } diff --git a/mwe/events/src/uiRenderer.cpp b/mwe/events/src/uiRenderer.cpp new file mode 100644 index 0000000..4a756f9 --- /dev/null +++ b/mwe/events/src/uiRenderer.cpp @@ -0,0 +1,72 @@ +#include "uiRenderer.h" + +// Constructor +UIRenderer::UIRenderer(SDL_Renderer* renderer) : renderer(renderer) {} + +// Render function +void UIRenderer::render(UIObject* uiObject) { + if (Button* button = dynamic_cast(uiObject)) { + renderButton(button); + } else if (Text* text = dynamic_cast(uiObject)) { + renderText(text); + } else if (TextInput* textInput = dynamic_cast(uiObject)) { + renderTextInput(textInput); + } +} + +// Private helper function to render a Button +void UIRenderer::renderButton(Button* button) { + SDL_Rect buttonRect = {button->x, button->y, button->width, button->height}; + SDL_SetRenderDrawColor(renderer, 100, 100, 255, 255); // Button color + SDL_RenderFillRect(renderer, &buttonRect); +} + +// Private helper function to render a Text +void UIRenderer::renderText(Text* text) { + if (text->font != nullptr) { + SDL_Color sdlColor = {text->color.red, text->color.green, text->color.blue, 255}; + SDL_Surface* textSurface = TTF_RenderText_Blended(text->font, text->text.c_str(), sdlColor); + if (!textSurface) { + std::cerr << "Error creating text surface: " << TTF_GetError() << std::endl; + return; + } + + SDL_Texture* textTexture = SDL_CreateTextureFromSurface(renderer, textSurface); + if (!textTexture) { + std::cerr << "Error creating texture from surface: " << SDL_GetError() << std::endl; + SDL_FreeSurface(textSurface); + return; + } + + SDL_Rect textRect = {text->x, text->y, textSurface->w, textSurface->h}; + SDL_RenderCopy(renderer, textTexture, nullptr, &textRect); + SDL_FreeSurface(textSurface); + SDL_DestroyTexture(textTexture); + } +} + +// Private helper function to render a TextInput +void UIRenderer::renderTextInput(TextInput* textInput) { + SDL_Rect inputRect = {textInput->x, textInput->y, textInput->width, textInput->height}; + SDL_SetRenderDrawColor(renderer, textInput->backgroundColor.red, textInput->backgroundColor.green, textInput->backgroundColor.blue, 255); + SDL_RenderFillRect(renderer, &inputRect); + + // Render text or placeholder + if (!textInput->textBuffer.empty()) { + SDL_Color sdlColor = {textInput->textColor.red, textInput->textColor.green, textInput->textColor.blue, 255}; + SDL_Surface* textSurface = TTF_RenderText_Blended(textInput->font, textInput->textBuffer.c_str(), sdlColor); + SDL_Texture* textTexture = SDL_CreateTextureFromSurface(renderer, textSurface); + SDL_Rect textRect = {textInput->x + 5, textInput->y + 5, textSurface->w, textSurface->h}; + SDL_RenderCopy(renderer, textTexture, nullptr, &textRect); + SDL_FreeSurface(textSurface); + SDL_DestroyTexture(textTexture); + } else if (!textInput->placeholder.empty()) { + SDL_Color sdlColor = {128, 128, 128, 255}; // Placeholder color + SDL_Surface* placeholderSurface = TTF_RenderText_Blended(textInput->font, textInput->placeholder.c_str(), sdlColor); + SDL_Texture* placeholderTexture = SDL_CreateTextureFromSurface(renderer, placeholderSurface); + SDL_Rect placeholderRect = {textInput->x + 5, textInput->y + 5, placeholderSurface->w, placeholderSurface->h}; + SDL_RenderCopy(renderer, placeholderTexture, nullptr, &placeholderRect); + SDL_FreeSurface(placeholderSurface); + SDL_DestroyTexture(placeholderTexture); + } +} diff --git a/mwe/events/src/window.cpp b/mwe/events/src/window.cpp index 41eb85f..a3bae40 100644 --- a/mwe/events/src/window.cpp +++ b/mwe/events/src/window.cpp @@ -1,29 +1,57 @@ #include "window.h" -WindowManager::WindowManager() {} -WindowManager::~WindowManager() { destroyWindow(); } -SDL_Renderer * WindowManager::getRenderer() { return renderer; } +#include + + +WindowManager::WindowManager() { + this->uiRenderer = nullptr; +} + + +WindowManager::~WindowManager() { + destroyWindow(); +} bool WindowManager::initWindow() { - if (SDL_Init(SDL_INIT_EVERYTHING) != 0) { - fprintf(stderr, "Error inititalising SDL.\n"); - return false; - } - window = SDL_CreateWindow("SDL Tutorial", SDL_WINDOWPOS_UNDEFINED, - SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, - SCREEN_HEIGHT, SDL_WINDOW_SHOWN); - if (!window) { - fprintf(stderr, "Error creating SDL Window. \n"); - return false; - } - renderer = SDL_CreateRenderer(window, -1, 0); - if (!renderer) { - fprintf(stderr, "Error creating SDL renderer. \n"); - return false; - } - return true; + if (SDL_Init(SDL_INIT_EVERYTHING) != 0) { + std::cerr << "Error initializing SDL.\n"; + return false; + } + + window = SDL_CreateWindow("SDL Tutorial", SDL_WINDOWPOS_UNDEFINED, + SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, + SCREEN_HEIGHT, SDL_WINDOW_SHOWN); + if (!window) { + std::cerr << "Error creating SDL Window.\n"; + return false; + } + + renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED); + if (!renderer) { + std::cerr << "Error creating SDL renderer.\n"; + return false; + } + + uiRenderer = new UIRenderer(renderer); + return true; } + void WindowManager::destroyWindow() { - SDL_DestroyRenderer(renderer); - SDL_DestroyWindow(window); - SDL_Quit(); + delete uiRenderer; + SDL_DestroyRenderer(renderer); + SDL_DestroyWindow(window); + SDL_Quit(); +} + +SDL_Renderer* WindowManager::getRenderer() { + return renderer; +} +void WindowManager::addUIObject(UIObject* uiObject) { + uiObjects.push_back(uiObject); +} + +void WindowManager::renderUIObjects() { + for (UIObject* obj : uiObjects) { + uiRenderer->render(obj); + } + SDL_RenderPresent(this->renderer); } -- cgit v1.2.3