aboutsummaryrefslogtreecommitdiff
path: root/mwe
diff options
context:
space:
mode:
Diffstat (limited to 'mwe')
-rw-r--r--mwe/events/CMakeLists.txt33
-rw-r--r--mwe/events/font/Arial.ttfbin0 -> 275572 bytes
-rw-r--r--mwe/events/include/event.h70
-rw-r--r--mwe/events/include/eventHandler.h4
-rw-r--r--mwe/events/include/gameObject.h20
-rw-r--r--mwe/events/include/iKeyListener.h21
-rw-r--r--mwe/events/include/iMouseListener.h23
-rw-r--r--mwe/events/include/inputSystem.h24
-rw-r--r--mwe/events/include/keyCodes.h11
-rw-r--r--mwe/events/include/keyListenerTest.h12
-rw-r--r--mwe/events/include/loopManager.h7
-rw-r--r--mwe/events/include/mouseListenerTest.h14
-rw-r--r--mwe/events/include/uiObject.h70
-rw-r--r--mwe/events/include/uiRenderer.h21
-rw-r--r--mwe/events/include/window.h28
-rw-r--r--mwe/events/src/event.cpp28
-rw-r--r--mwe/events/src/iKeyListener.cpp18
-rw-r--r--mwe/events/src/iMouseListener.cpp23
-rw-r--r--mwe/events/src/inputSystem.cpp99
-rw-r--r--mwe/events/src/keyListenerTest.cpp17
-rw-r--r--mwe/events/src/loopManager.cpp69
-rw-r--r--mwe/events/src/main.cpp14
-rw-r--r--mwe/events/src/mouseListenerTest.cpp25
-rw-r--r--mwe/events/src/uiObject.cpp28
-rw-r--r--mwe/events/src/uiRenderer.cpp103
-rw-r--r--mwe/events/src/window.cpp73
-rw-r--r--mwe/gameloop/include/loopManager.h4
-rw-r--r--mwe/gameloop/include/timer.h2
-rw-r--r--mwe/gameloop/src/loopManager.cpp21
29 files changed, 796 insertions, 86 deletions
diff --git a/mwe/events/CMakeLists.txt b/mwe/events/CMakeLists.txt
index 585d869..12e45a7 100644
--- a/mwe/events/CMakeLists.txt
+++ b/mwe/events/CMakeLists.txt
@@ -2,30 +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/eventHandler.cpp
- src/eventManager.cpp
- src/event.cpp
- src/loopManager.cpp
- src/timer.cpp
- src/keyCodes.cpp
- src/eventHandler.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
)
-# 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/font/Arial.ttf b/mwe/events/font/Arial.ttf
new file mode 100644
index 0000000..7ff88f2
--- /dev/null
+++ b/mwe/events/font/Arial.ttf
Binary files differ
diff --git a/mwe/events/include/event.h b/mwe/events/include/event.h
index 730ee4b..62d8974 100644
--- a/mwe/events/include/event.h
+++ b/mwe/events/include/event.h
@@ -6,7 +6,8 @@
#include <string>
#include <unordered_map>
#include <variant>
-
+#include "keyCodes.h"
+#include "customTypes.h"
class UUIDGenerator {
public:
static std::uint32_t getUniqueID() {
@@ -63,7 +64,19 @@ public:
Keycode key = 0;
int repeatCount = 0;
};
+class MouseClickEvent : public Event {
+public:
+ MouseClickEvent(int x, int y, MouseButton button);
+
+ REGISTER_EVENT_TYPE("KeyClickedEvent");
+ std::pair<int, int> getMousePosition() const;
+ MouseButton getButton() const { return button; }
+private:
+ int mouseX = 0;
+ int mouseY = 0;
+ MouseButton button;
+};
// KeyReleasedEvent class
class KeyReleasedEvent : public Event {
public:
@@ -89,6 +102,31 @@ public:
private:
int mouseX = 0;
int mouseY = 0;
+ MouseButton button;
+};
+class MouseReleasedEvent : public Event {
+public:
+ MouseReleasedEvent(int mouseX, int mouseY, MouseButton button);
+
+ REGISTER_EVENT_TYPE(MouseReleasedEvent)
+
+ std::pair<int, int> getMousePosition() const;
+ MouseButton getMouseButton() const;
+private:
+ int mouseX = 0;
+ int mouseY = 0;
+ MouseButton button;
+};
+class MouseMovedEvent : public Event {
+public:
+ MouseMovedEvent(int mouseX, int mouseY);
+
+ REGISTER_EVENT_TYPE(MouseMovedEvent)
+
+ std::pair<int, int> getMousePosition() const;
+private:
+ int mouseX = 0;
+ int mouseY = 0;
};
class CollisionEvent : public Event {
public:
@@ -101,3 +139,33 @@ public:
private:
Collision collisionData;
};
+class TextSubmitEvent : public Event {
+public:
+ TextSubmitEvent(std::string submittedText);
+
+ REGISTER_EVENT_TYPE(TextSubmitEvent)
+
+ std::string getText() const;
+
+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 <functional>
#include <iostream>
+
+
template <typename EventType>
using EventHandler = std::function<void(const EventType & e)>;
diff --git a/mwe/events/include/gameObject.h b/mwe/events/include/gameObject.h
new file mode 100644
index 0000000..de5f3fe
--- /dev/null
+++ b/mwe/events/include/gameObject.h
@@ -0,0 +1,20 @@
+#pragma once
+#include <cstdint>
+#include <string>
+class GameObject {
+public:
+ GameObject(){}
+
+ // template <typename... Args>
+ // void addSpriteComponent(Args &&... args);
+ // template <typename... Args>
+ // void addRigidbodyComponent(Args &&... args);
+ // template <typename... Args>
+ // void addColiderComponent(Args &&... args);
+
+ std::uint32_t mId;
+ std::string mName;
+ std::string mTag;
+ bool mActive;
+ int mLayer;
+};
diff --git a/mwe/events/include/iKeyListener.h b/mwe/events/include/iKeyListener.h
new file mode 100644
index 0000000..5f39ece
--- /dev/null
+++ b/mwe/events/include/iKeyListener.h
@@ -0,0 +1,21 @@
+#pragma once
+#include "event.h"
+#include "eventManager.h"
+#include "eventHandler.h"
+class IKeyListener {
+public:
+ virtual ~IKeyListener();
+ virtual void onKeyPressed(const KeyPressedEvent& event) = 0;
+ virtual void onKeyReleased(const KeyReleasedEvent& event) = 0;
+
+protected:
+ void subscribeEvents(int listenerId = 0);
+ void unsubscribeEvents(int listenerId = 0);
+ void activate(int listenerId = 0) { subscribeEvents(listenerId); }
+ void deactivate(int listenerId = 0) { unsubscribeEvents(listenerId); }
+
+private:
+ EventHandler<KeyPressedEvent> keyPressedHandler;
+ EventHandler<KeyReleasedEvent> keyReleasedHandler;
+};
+
diff --git a/mwe/events/include/iMouseListener.h b/mwe/events/include/iMouseListener.h
new file mode 100644
index 0000000..7d840c1
--- /dev/null
+++ b/mwe/events/include/iMouseListener.h
@@ -0,0 +1,23 @@
+#pragma once
+#include "event.h"
+#include "eventHandler.h"
+#include "eventManager.h"
+
+class IMouseListener {
+public:
+ virtual ~IMouseListener();
+
+ virtual void onMouseClicked(const MouseClickEvent& event) = 0;
+ virtual void onMousePressed(const MousePressedEvent& event) = 0;
+ virtual void onMouseReleased(const MouseReleasedEvent& event) = 0;
+ virtual void onMouseMoved(const MouseMovedEvent& event) = 0;
+protected:
+ void subscribeEvents(int listenerId = 0);
+ void unsubscribeEvents(int listenerId = 0);
+
+private:
+ EventHandler<MouseClickEvent> mouseClickHandler;
+ EventHandler<MousePressedEvent> mousePressHandler;
+ EventHandler<MouseReleasedEvent> mouseReleaseHandler;
+ EventHandler<MouseMovedEvent> mouseMoveHandler;
+};
diff --git a/mwe/events/include/inputSystem.h b/mwe/events/include/inputSystem.h
new file mode 100644
index 0000000..c20562d
--- /dev/null
+++ b/mwe/events/include/inputSystem.h
@@ -0,0 +1,24 @@
+#pragma once
+#include <vector>
+#include "uiObject.h"
+#include "event.h"
+#include "keyCodes.h"
+#include "eventManager.h"
+class InputSystem {
+public:
+ InputSystem();
+ void registerButton(Button* button);
+ void registerText(Text* label);
+ void registerTextInput(TextInput* input);
+ void processInput();
+
+private:
+ std::vector<Button*> buttons;
+ std::vector<TextInput*> textInputs;
+ std::vector<Text*> texts;
+ void processMouseClick(int mouseX, int mouseY);
+ void processInputField(int mouseX, int mouseY);
+ void processKeyPress(Keycode);
+ void processTextInput(const std::string& text);
+
+};
diff --git a/mwe/events/include/keyCodes.h b/mwe/events/include/keyCodes.h
index 0879efc..61deba2 100644
--- a/mwe/events/include/keyCodes.h
+++ b/mwe/events/include/keyCodes.h
@@ -3,6 +3,16 @@
#include <cstdint>
#include <unordered_map>
using Keycode = uint16_t;
+enum class MouseButton {
+ None = 0,
+ Left_Mouse = 1,
+ Right_Mouse = 2,
+ Middle_Mouse = 3,
+ X1_Mouse = 4,
+ X2_Mouse = 5,
+ Scroll_Up = 6,
+ Scroll_Down = 7,
+};
enum : Keycode {
// From glfw3.h
Space = 32,
@@ -136,6 +146,7 @@ enum : Keycode {
RightSuper = 347,
Menu = 348
};
+
// Define the mapping
extern const std::unordered_map<SDL_Keycode, Keycode> sdlToCustom;
diff --git a/mwe/events/include/keyListenerTest.h b/mwe/events/include/keyListenerTest.h
new file mode 100644
index 0000000..5990cd1
--- /dev/null
+++ b/mwe/events/include/keyListenerTest.h
@@ -0,0 +1,12 @@
+#pragma once
+#include "iKeyListener.h"
+#include <iostream>
+
+class KeyListenerTest : public IKeyListener {
+public:
+ KeyListenerTest(int listenerId);
+ ~KeyListenerTest();
+
+ void onKeyPressed(const KeyPressedEvent& event) override;
+ void onKeyReleased(const KeyReleasedEvent& event) override;
+};
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 <memory>
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> inputSystem;
+ EventHandler<ShutDownEvent> shutdownHandler;
};
diff --git a/mwe/events/include/mouseListenerTest.h b/mwe/events/include/mouseListenerTest.h
new file mode 100644
index 0000000..dae04f5
--- /dev/null
+++ b/mwe/events/include/mouseListenerTest.h
@@ -0,0 +1,14 @@
+#pragma once
+#include "iMouseListener.h"
+#include <iostream>
+
+class MouseListenerTest : public IMouseListener {
+public:
+ MouseListenerTest(int listenerId);
+ ~MouseListenerTest();
+
+ void onMouseClicked(const MouseClickEvent& event) override;
+ void onMousePressed(const MousePressedEvent& event) override;
+ void onMouseReleased(const MouseReleasedEvent& event) override;
+ void onMouseMoved(const MouseMovedEvent& event) override;
+};
diff --git a/mwe/events/include/uiObject.h b/mwe/events/include/uiObject.h
new file mode 100644
index 0000000..893232d
--- /dev/null
+++ b/mwe/events/include/uiObject.h
@@ -0,0 +1,70 @@
+#pragma once
+#include "gameObject.h"
+#include <SDL2/SDL.h>
+#include <SDL_ttf.h>
+#include "event.h"
+#include "eventHandler.h"
+#include <functional>
+struct Alignment {
+ enum class Horizontal { LEFT, CENTER, RIGHT };
+ enum class Vertical { TOP, MIDDLE, BOTTOM };
+ enum class PositioningMode { RELATIVE, STATIC,ABSOLUTE };
+
+ Horizontal horizontal = Horizontal::CENTER;
+ Vertical vertical = Vertical::MIDDLE;
+ PositioningMode mode = PositioningMode::RELATIVE;
+
+ int staticX = 0;
+ int staticY = 0;
+
+ int marginTop = 0;
+ int marginBottom = 0;
+ int marginLeft = 0;
+ int marginRight = 0;
+};
+struct RGBColor{
+ int red;
+ int green;
+ int blue;
+};
+class UIObject : public GameObject{
+ public:
+ UIObject(int width,int height);
+ virtual ~UIObject() {}
+ int width;
+ int height;
+ int x;
+ int y;
+};
+class Button : public UIObject{
+ public:
+ Button(int width,int height);
+ RGBColor color;
+ std::function<void()> onClick;
+
+};
+class Text : public UIObject{
+ public:
+ Text(int width,int height);
+ std::string text;
+ int size;
+ Alignment alignment;
+ //font resource
+ TTF_Font *font;
+ RGBColor color;
+};
+class TextInput : public UIObject {
+public:
+ TextInput(int width, int height);
+ std::string textBuffer;
+ std::string placeholder;
+ bool isActive = false;
+ RGBColor textColor;
+ RGBColor backgroundColor;
+ size_t maxLength = 100;
+ Alignment alignment;
+ TTF_Font* font = nullptr;
+ std::function<void()> onSubmit;
+ std::function<void()> onFocus;
+};
+
diff --git a/mwe/events/include/uiRenderer.h b/mwe/events/include/uiRenderer.h
new file mode 100644
index 0000000..32acecf
--- /dev/null
+++ b/mwe/events/include/uiRenderer.h
@@ -0,0 +1,21 @@
+#pragma once
+#include <SDL2/SDL.h>
+#include <SDL2/SDL_ttf.h>
+#include <string>
+#include "uiObject.h"
+
+class UIRenderer {
+public:
+ UIRenderer(SDL_Renderer* renderer);
+ ~UIRenderer();
+
+ void render(UIObject* uiObject);
+
+private:
+ SDL_Renderer* renderer;
+ TTF_Font* font;
+
+ 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 <SDL2/SDL.h>
-#include <iostream>
#include <vector>
+#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<UIObject*> uiObjects;
};
diff --git a/mwe/events/src/event.cpp b/mwe/events/src/event.cpp
index c9201d0..eae4d14 100644
--- a/mwe/events/src/event.cpp
+++ b/mwe/events/src/event.cpp
@@ -50,3 +50,31 @@ CollisionEvent::CollisionEvent(Collision collision)
Collision CollisionEvent::getCollisionData() const {
return this->collisionData;
}
+
+TextSubmitEvent::TextSubmitEvent(std::string text)
+ : text(text), Event("TextSubmitEvent") {
+
+ }
+
+std::string TextSubmitEvent::getText() const {
+ return this->text;
+}
+
+MouseReleasedEvent::MouseReleasedEvent(int x, int y, MouseButton button) : mouseX(x), mouseY(y), button(button),Event("MouseReleased"){
+
+}
+std::pair<int, int> MouseReleasedEvent::getMousePosition() const{
+ return {mouseX,mouseY};
+}
+MouseClickEvent::MouseClickEvent(int x,int y,MouseButton button) : mouseX(x), mouseY(y), button(button),Event("MouseClickEvent"){
+
+}
+MouseMovedEvent::MouseMovedEvent(int x, int y) : mouseX(x), mouseY(y),Event("MouseMovedEvent"){
+
+}
+std::pair<int, int> MouseClickEvent::getMousePosition() const {
+ return {mouseX, mouseY};
+}
+std::pair<int, int> MouseMovedEvent::getMousePosition() const {
+ return {mouseX, mouseY};
+}
diff --git a/mwe/events/src/iKeyListener.cpp b/mwe/events/src/iKeyListener.cpp
new file mode 100644
index 0000000..59cc89a
--- /dev/null
+++ b/mwe/events/src/iKeyListener.cpp
@@ -0,0 +1,18 @@
+#include "iKeyListener.h"
+
+IKeyListener::~IKeyListener() {
+ unsubscribeEvents();
+}
+
+void IKeyListener::subscribeEvents(int listenerId) {
+ keyPressedHandler = [this](const KeyPressedEvent& event) { this->onKeyPressed(event); };
+ keyReleasedHandler = [this](const KeyReleasedEvent& event) { this->onKeyReleased(event); };
+
+ subscribe<KeyPressedEvent>(keyPressedHandler, listenerId);
+ subscribe<KeyReleasedEvent>(keyReleasedHandler, listenerId);
+}
+
+void IKeyListener::unsubscribeEvents(int listenerId) {
+ unsubscribe<KeyPressedEvent>(keyPressedHandler, listenerId);
+ unsubscribe<KeyReleasedEvent>(keyReleasedHandler, listenerId);
+}
diff --git a/mwe/events/src/iMouseListener.cpp b/mwe/events/src/iMouseListener.cpp
new file mode 100644
index 0000000..3239304
--- /dev/null
+++ b/mwe/events/src/iMouseListener.cpp
@@ -0,0 +1,23 @@
+#include "iMouseListener.h"
+IMouseListener::~IMouseListener() {
+ unsubscribeEvents();
+}
+
+void IMouseListener::subscribeEvents(int listenerId) {
+ mouseClickHandler = [this](const MouseClickEvent& event) { this->onMouseClicked(event); };
+ mousePressHandler = [this](const MousePressedEvent& event) { this->onMousePressed(event); };
+ mouseReleaseHandler = [this](const MouseReleasedEvent& event) { this->onMouseReleased(event); };
+ mouseMoveHandler = [this](const MouseMovedEvent& event) { this->onMouseMoved(event); };
+
+ subscribe<MouseClickEvent>(mouseClickHandler, listenerId);
+ subscribe<MousePressedEvent>(mousePressHandler, listenerId);
+ subscribe<MouseReleasedEvent>(mouseReleaseHandler, listenerId);
+ subscribe<MouseMovedEvent>(mouseMoveHandler, listenerId);
+}
+
+void IMouseListener::unsubscribeEvents(int listenerId) {
+ unsubscribe<MouseClickEvent>(mouseClickHandler, listenerId);
+ unsubscribe<MousePressedEvent>(mousePressHandler, listenerId);
+ unsubscribe<MouseReleasedEvent>(mouseReleaseHandler, listenerId);
+ unsubscribe<MouseMovedEvent>(mouseMoveHandler, listenerId);
+}
diff --git a/mwe/events/src/inputSystem.cpp b/mwe/events/src/inputSystem.cpp
new file mode 100644
index 0000000..bb26e8b
--- /dev/null
+++ b/mwe/events/src/inputSystem.cpp
@@ -0,0 +1,99 @@
+#include "inputSystem.h"
+
+InputSystem::InputSystem() {}
+
+void InputSystem::registerButton(Button* button) {
+ buttons.push_back(button);
+}
+void InputSystem::registerTextInput(TextInput* input) {
+ textInputs.push_back(input);
+}
+void InputSystem::registerText(Text* label) {
+ texts.push_back(label);
+}
+
+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)));
+ processKeyPress(event.key.keysym.sym);
+ break;
+ case SDL_TEXTINPUT:
+ // Process typed characters
+ processTextInput(event.text.text);
+ 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();
+ }
+ }
+ for(auto* textInput : textInputs){
+ if (mouseX >= textInput->x && mouseX <= textInput->x + textInput->width &&
+ mouseY >= textInput->y && mouseY <= textInput->y + textInput->height) {
+ textInput->isActive = true;
+ } else {
+ textInput->isActive = false;
+ }
+ }
+}
+void InputSystem::processKeyPress(Keycode key) {
+ // for (auto* textInput : textInputs) {
+ // if (textInput->isActive) {
+ // if (key == SDLK_RETURN || key == SDLK_KP_ENTER) {
+ // // Submit the text
+ // if (textInput->onSubmit) {
+ // textInput->onSubmit();
+ // }
+ // }
+ // else if (key == SDLK_BACKSPACE) {
+ // // Handle backspace
+ // if (!textInput->textBuffer.empty() && textInput->caretPosition > 0) {
+ // textInput->textBuffer.erase(textInput->caretPosition - 1, 1);
+ // textInput->caretPosition--;
+ // }
+ // }
+ // else if (key == SDLK_LEFT) {
+ // // Move caret left
+ // if (textInput->caretPosition > 0) {
+ // textInput->caretPosition--;
+ // }
+ // }
+ // else if (key == SDLK_RIGHT) {
+ // // Move caret right
+ // if (textInput->caretPosition < textInput->textBuffer.size()) {
+ // textInput->caretPosition++;
+ // }
+ // }
+ // }
+ // }
+}
+
+void InputSystem::processTextInput(const std::string& text) {
+ // for (auto* textInput : textInputs) {
+ // if (textInput->isActive) {
+ // // Insert text at caret position
+ // textInput->textBuffer.insert(textInput->caretPosition, text);
+ // textInput->caretPosition += text.length();
+ // }
+ // }
+}
+
diff --git a/mwe/events/src/keyListenerTest.cpp b/mwe/events/src/keyListenerTest.cpp
new file mode 100644
index 0000000..90b92a5
--- /dev/null
+++ b/mwe/events/src/keyListenerTest.cpp
@@ -0,0 +1,17 @@
+#include "keyListenerTest.h"
+
+KeyListenerTest::KeyListenerTest(int listenerId) {
+ subscribeEvents(listenerId);
+}
+
+KeyListenerTest::~KeyListenerTest() {
+ unsubscribeEvents();
+}
+
+void KeyListenerTest::onKeyPressed(const KeyPressedEvent& event) {
+ std::cout << "Key pressed: " << event.getKeyCode() << std::endl;
+}
+
+void KeyListenerTest::onKeyReleased(const KeyReleasedEvent& event) {
+ std::cout << "Key released: " << event.getKeyCode() << std::endl;
+}
diff --git a/mwe/events/src/loopManager.cpp b/mwe/events/src/loopManager.cpp
index 8ecb932..f673d44 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<InputSystem>()){
+ 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,37 @@ void LoopManager::setup() {
}
};
subscribe<KeyPressedEvent>(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);
+
+
+ TextInput* testInput = new TextInput(200,200);
+ testInput->x = 100;
+ testInput->y = 100;
+ testInput->backgroundColor = {20,50,80};
+ inputSystem->registerTextInput(testInput);
+ window.addUIObject(testInput);
}
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/main.cpp b/mwe/events/src/main.cpp
index f7e0766..972fc70 100644
--- a/mwe/events/src/main.cpp
+++ b/mwe/events/src/main.cpp
@@ -4,6 +4,13 @@
#include <SDL2/SDL.h>
#include <iostream>
#include <memory>
+#include "loopManager.h"
+#include "event.h"
+#include "customTypes.h"
+#include "iKeyListener.h"
+#include "iMouseListener.h"
+#include "keyListenerTest.h"
+#include "mouseListenerTest.h"
class PlayerDamagedEvent : public Event {
public:
PlayerDamagedEvent(int damage, int playerID)
@@ -44,10 +51,9 @@ void testCollisionEvent() {
}
int main(int argc, char * args[]) {
LoopManager gameLoop;
- // Create an event handler for KeyPressedEvent
- // EventHandler<KeyPressedEvent> callback = [](const KeyPressedEvent& e) {
- // onKeyPressed(e);
- // };
+ int testListenerId = 0;
+ KeyListenerTest keyListener(testListenerId);
+ MouseListenerTest mouseListener(testListenerId);
// custom event class poc
subscribe<PlayerDamagedEvent>(onPlayerDamaged);
triggerEvent(PlayerDamagedEvent(50, 1));
diff --git a/mwe/events/src/mouseListenerTest.cpp b/mwe/events/src/mouseListenerTest.cpp
new file mode 100644
index 0000000..4b3aa3e
--- /dev/null
+++ b/mwe/events/src/mouseListenerTest.cpp
@@ -0,0 +1,25 @@
+#include "mouseListenerTest.h"
+
+MouseListenerTest::MouseListenerTest(int listenerId) {
+ subscribeEvents(listenerId);
+}
+
+MouseListenerTest::~MouseListenerTest() {
+ unsubscribeEvents();
+}
+
+void MouseListenerTest::onMouseClicked(const MouseClickEvent& event) {
+ std::cout << "Mouse clicked at: (" << event.getMousePosition().first << ", " << event.getMousePosition().second << ")" << std::endl;
+}
+
+void MouseListenerTest::onMousePressed(const MousePressedEvent& event) {
+ std::cout << "Mouse button pressed at: (" << event.getMousePosition().first << ", " << event.getMousePosition().second << ")" << std::endl;
+}
+
+void MouseListenerTest::onMouseReleased(const MouseReleasedEvent& event) {
+ std::cout << "Mouse button released at: (" << event.getMousePosition().first << ", " << event.getMousePosition().second << ")" << std::endl;
+}
+
+void MouseListenerTest::onMouseMoved(const MouseMovedEvent& event) {
+ std::cout << "Mouse moved to: (" << event.getMousePosition().first << ", " << event.getMousePosition().second << ")" << std::endl;
+}
diff --git a/mwe/events/src/uiObject.cpp b/mwe/events/src/uiObject.cpp
new file mode 100644
index 0000000..31ff486
--- /dev/null
+++ b/mwe/events/src/uiObject.cpp
@@ -0,0 +1,28 @@
+#include "uiObject.h"
+
+// Constructor for UIObject
+UIObject::UIObject(int width, int height)
+ : width(width), height(height){
+
+ }
+
+// Constructor for Button
+Button::Button(int width, int height)
+ : UIObject(width, height) {
+}
+
+Text::Text(int width, int height)
+ : UIObject(width, height), size(12), font(nullptr), color{255, 255, 255} { // Default size and color
+ alignment.horizontal = Alignment::Horizontal::CENTER;
+ alignment.vertical = Alignment::Vertical::MIDDLE;
+ alignment.mode = Alignment::PositioningMode::RELATIVE;
+}
+
+TextInput::TextInput(int width, int height)
+ : UIObject(width, height), textBuffer(""), placeholder(""),
+ isActive(false), textColor{255, 255, 255}, backgroundColor{0, 0, 0}, maxLength(100), font(nullptr) {
+ alignment.horizontal = Alignment::Horizontal::LEFT;
+ alignment.vertical = Alignment::Vertical::TOP;
+ alignment.mode = Alignment::PositioningMode::RELATIVE;
+}
+
diff --git a/mwe/events/src/uiRenderer.cpp b/mwe/events/src/uiRenderer.cpp
new file mode 100644
index 0000000..dbe8dfe
--- /dev/null
+++ b/mwe/events/src/uiRenderer.cpp
@@ -0,0 +1,103 @@
+#include "uiRenderer.h"
+
+// Constructor
+UIRenderer::UIRenderer(SDL_Renderer* renderer) : renderer(renderer) {}
+
+// Render function
+void UIRenderer::render(UIObject* uiObject) {
+ if (Button* button = dynamic_cast<Button*>(uiObject)) {
+ renderButton(button);
+ } else if (Text* text = dynamic_cast<Text*>(uiObject)) {
+ renderText(text);
+ } else if (TextInput* textInput = dynamic_cast<TextInput*>(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);
+ }
+}
+
+void UIRenderer::renderTextInput(TextInput* textInput) {
+ // // Check if textInput or renderer is null to avoid segmentation faults
+ // if (!textInput || !renderer) {
+ // std::cerr << "Error: Null pointer detected for textInput or renderer." << std::endl;
+ // return;
+ // }
+
+ // // Render the background rectangle for the text input
+ // 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);
+
+ // // Check if font is valid
+ // if (!textInput->font) {
+ // std::cerr << "Error: Font is not loaded for textInput." << std::endl;
+ // return;
+ // }
+
+ // SDL_Color sdlColor = {textInput->textColor.red, textInput->textColor.green, textInput->textColor.blue, 255};
+
+ // if (!textInput->textBuffer.empty()) {
+ // // Render the text in the input field
+ // SDL_Surface* textSurface = TTF_RenderText_Blended(textInput->font, textInput->textBuffer.c_str(), sdlColor);
+ // if (textSurface) {
+ // SDL_Texture* textTexture = SDL_CreateTextureFromSurface(renderer, textSurface);
+ // if (textTexture) {
+ // SDL_Rect textRect = {textInput->x + 5, textInput->y + 5, textSurface->w, textSurface->h};
+ // SDL_RenderCopy(renderer, textTexture, nullptr, &textRect);
+ // SDL_DestroyTexture(textTexture);
+ // } else {
+ // std::cerr << "Error: Unable to create texture from text surface." << std::endl;
+ // }
+ // SDL_FreeSurface(textSurface);
+ // } else {
+ // std::cerr << "Error: Unable to create text surface." << std::endl;
+ // }
+ // } else if (!textInput->placeholder.empty()) {
+ // // Render the placeholder text
+ // SDL_Color placeholderColor = {128, 128, 128, 255}; // Light gray for placeholder
+ // SDL_Surface* placeholderSurface = TTF_RenderText_Blended(textInput->font, textInput->placeholder.c_str(), placeholderColor);
+ // if (placeholderSurface) {
+ // SDL_Texture* placeholderTexture = SDL_CreateTextureFromSurface(renderer, placeholderSurface);
+ // if (placeholderTexture) {
+ // SDL_Rect placeholderRect = {textInput->x + 5, textInput->y + 5, placeholderSurface->w, placeholderSurface->h};
+ // SDL_RenderCopy(renderer, placeholderTexture, nullptr, &placeholderRect);
+ // SDL_DestroyTexture(placeholderTexture);
+ // } else {
+ // std::cerr << "Error: Unable to create texture from placeholder surface." << std::endl;
+ // }
+ // SDL_FreeSurface(placeholderSurface);
+ // } else {
+ // std::cerr << "Error: Unable to create placeholder surface." << std::endl;
+ // }
+ // }
+}
+
diff --git a/mwe/events/src/window.cpp b/mwe/events/src/window.cpp
index 41eb85f..7192e6b 100644
--- a/mwe/events/src/window.cpp
+++ b/mwe/events/src/window.cpp
@@ -1,29 +1,56 @@
#include "window.h"
-WindowManager::WindowManager() {}
-WindowManager::~WindowManager() { destroyWindow(); }
-SDL_Renderer * WindowManager::getRenderer() { return renderer; }
+#include <iostream>
+
+
+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();
+ 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);
}
diff --git a/mwe/gameloop/include/loopManager.h b/mwe/gameloop/include/loopManager.h
index 1befb69..e2c2e2c 100644
--- a/mwe/gameloop/include/loopManager.h
+++ b/mwe/gameloop/include/loopManager.h
@@ -1,11 +1,11 @@
#pragma once
-#include "event.h"
#include "gameObject.h"
#include "window.h"
#include <SDL2/SDL.h>
class LoopManager {
public:
LoopManager();
+ ~LoopManager();
void setup();
void loop();
@@ -17,7 +17,7 @@ private:
void fixedUpdate();
void render();
bool gameRunning = false;
- WindowManager window;
+ WindowManager* window;
int timeScale = 1;
float accumulator = 0.0;
double currentTime;
diff --git a/mwe/gameloop/include/timer.h b/mwe/gameloop/include/timer.h
index 8273746..3c38594 100644
--- a/mwe/gameloop/include/timer.h
+++ b/mwe/gameloop/include/timer.h
@@ -25,7 +25,7 @@ private:
double maximumDeltaTime = 0.25;
double deltaTime;
double frameTargetTime = FPS / 1000;
- double fixedDeltaTime = 0.01;
+ double fixedDeltaTime = 0.02;
double elapsedTime;
double elapsedFixedTime;
double time;
diff --git a/mwe/gameloop/src/loopManager.cpp b/mwe/gameloop/src/loopManager.cpp
index 0392853..b075bd8 100644
--- a/mwe/gameloop/src/loopManager.cpp
+++ b/mwe/gameloop/src/loopManager.cpp
@@ -1,6 +1,15 @@
#include "loopManager.h"
#include "timer.h"
-LoopManager::LoopManager() {}
+LoopManager::LoopManager() {
+ this->window = new WindowManager();
+
+}
+LoopManager::~LoopManager(){
+ for(GameObject* object : this->objectList){
+ delete object;
+ }
+ delete this->window;
+}
void LoopManager::processInput() {
SDL_Event event;
SDL_PollEvent(&event);
@@ -42,14 +51,14 @@ void LoopManager::loop() {
timer.enforceFrameRate();
}
- window.destroyWindow();
+ window->destroyWindow();
}
void LoopManager::setup() {
- gameRunning = window.initWindow();
- LoopTimer::getInstance().start();
- LoopTimer::getInstance().setFPS(500);
+ LoopTimer::getInstance().start();
+ LoopTimer::getInstance().setFPS(10);
+ this->gameRunning = true;
for (int i = 1; i < 3; i++) {
GameObject * square
= new GameObject("square2", i * 60, i * 60, 20, 20, 0, 0);
@@ -59,7 +68,7 @@ void LoopManager::setup() {
void LoopManager::render() {
fprintf(stderr, "**********render********** \n");
if (gameRunning) {
- window.render(objectList);
+ window->render(objectList);
}
}