Compare commits
10 Commits
multiplaye
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ba47255ee0 | ||
|
|
8690efe184 | ||
|
|
d6445092c2 | ||
|
|
452bf92e20 | ||
|
|
6c2f580134 | ||
|
|
d58b84d4a5 | ||
|
|
19a3e55e5f | ||
|
|
fe9ecb1ecc | ||
|
|
de7cbdc73c | ||
|
|
82b499e65c |
3
.gitmodules
vendored
Normal file
3
.gitmodules
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
[submodule "external/NetworkCore"]
|
||||
path = external/NetworkCore
|
||||
url = git@git.fawkes100.de:sebastian/JsonTCPServer.git
|
||||
@ -118,6 +118,8 @@ CPMAddPackage(
|
||||
|
||||
message(STATUS "dr_libs_SOURCE_DIR = ${dr_libs_SOURCE_DIR}")
|
||||
|
||||
add_subdirectory(external/NetworkCore)
|
||||
|
||||
# Engine als statische Lib
|
||||
add_library(Engine STATIC
|
||||
engine/src/core/Window.h
|
||||
@ -247,22 +249,29 @@ add_library(Engine STATIC
|
||||
engine/src/core/events/EventBus.h
|
||||
engine/src/core/audio/ecs/PlaySoundComponent.h
|
||||
engine/src/core/animation/events/AnimationMarkerEvent.h
|
||||
engine/src/core/animation/components/BlockingAnimationComponent.h
|
||||
engine/src/core/audio/ecs/AudioSystem.cpp
|
||||
engine/src/core/audio/ecs/AudioSystem.h
|
||||
engine/src/core/audio/ecs/BlockingSoundComponent.h
|
||||
engine/src/renderer/shader/GuiShader.cpp
|
||||
engine/src/renderer/shader/GuiShader.h
|
||||
engine/src/renderer/primitives/QuadFactory.cpp
|
||||
engine/src/renderer/primitives/QuadFactory.h
|
||||
engine/src/loader/models/SimpleTexturedMesh.cpp
|
||||
engine/src/loader/models/SimpleTexturedMesh.h
|
||||
engine/src/loader/models/Mesh.cpp
|
||||
engine/src/loader/models/Mesh.h
|
||||
engine/src/renderer/GuiRenderer.cpp
|
||||
engine/src/renderer/GuiRenderer.h
|
||||
engine/src/renderer/ui/GUITexture.cpp
|
||||
engine/src/renderer/ui/GUITexture.h
|
||||
engine/src/core/events/ApplicationEvents.h
|
||||
engine/src/core/events/EventChannels.cpp
|
||||
engine/src/core/events/EventChannels.h
|
||||
engine/src/core/events/ApplicationEvents.cpp
|
||||
)
|
||||
target_include_directories(Engine PUBLIC engine/src ${dr_libs_SOURCE_DIR})
|
||||
target_link_libraries(Engine PUBLIC OpenGL::GL glfw glad glm::glm imgui spdlog::spdlog tinyobjloader stb_image OpenAL::OpenAL)
|
||||
|
||||
CPMAddPackage(
|
||||
NAME asio
|
||||
GITHUB_REPOSITORY chriskohlhoff/asio
|
||||
GIT_TAG asio-1-30-2 # Eine stabile, aktuelle Version
|
||||
DOWNLOAD_ONLY YES # Da Asio Header-only ist und kein CMake-Projekt hat
|
||||
)
|
||||
|
||||
add_library(asio INTERFACE)
|
||||
target_include_directories(asio INTERFACE ${asio_SOURCE_DIR}/asio/include)
|
||||
# Definiere ASIO_STANDALONE, damit Asio weiß, dass es KEIN Boost benötigt
|
||||
target_compile_definitions(asio INTERFACE ASIO_STANDALONE)
|
||||
|
||||
target_link_libraries(Engine PUBLIC OpenGL::GL glfw glad glm::glm imgui spdlog::spdlog tinyobjloader stb_image OpenAL::OpenAL NetworkCore)
|
||||
|
||||
# --- GameLib: Spiel-Logik, unabhängig von main.cpp testbar ---
|
||||
add_library(GameLib STATIC
|
||||
@ -305,23 +314,26 @@ add_library(GameLib STATIC
|
||||
game/src/ludo/gameMode/PiecePathBuilder.cpp
|
||||
game/src/ludo/gameMode/PiecePathBuilder.h
|
||||
game/src/ludo/gameMode/PathNode.h
|
||||
game/src/mainMenu/MainMenuScene.cpp
|
||||
game/src/mainMenu/MainMenuScene.h
|
||||
)
|
||||
target_include_directories(GameLib PUBLIC game/src)
|
||||
target_link_libraries(GameLib PUBLIC Engine)
|
||||
|
||||
add_subdirectory(server)
|
||||
|
||||
# --- Executable ---
|
||||
add_executable(ColorRace
|
||||
game/src/main.cpp
|
||||
engine/src/core/animation/components/BlockingAnimationComponent.h
|
||||
engine/src/core/audio/ecs/AudioSystem.cpp
|
||||
engine/src/core/audio/ecs/AudioSystem.h
|
||||
engine/src/core/audio/ecs/BlockingSoundComponent.h
|
||||
game/src/ludo/multiplayer/IGameSession.cpp
|
||||
game/src/ludo/multiplayer/IGameSession.h
|
||||
game/src/ludo/multiplayer/LocalGameSession.cpp
|
||||
game/src/ludo/multiplayer/LocalGameSession.h
|
||||
game/src/ludo/multiplayer/RemoteGameSession.cpp
|
||||
game/src/ludo/multiplayer/RemoteGameSession.h
|
||||
game/src/mainMenu/layer/MainMenuUiLayer.cpp
|
||||
game/src/mainMenu/layer/MainMenuUiLayer.h
|
||||
game/src/multiplayer/LudoGameClient.cpp
|
||||
game/src/multiplayer/LudoGameClient.h
|
||||
game/src/multiplayer/LudoNetworkEvents.h
|
||||
game/src/multiplayer/lobby/LobbyScene.cpp
|
||||
game/src/multiplayer/lobby/LobbyScene.h
|
||||
game/src/multiplayer/lobby/LobbyUiLayer.cpp
|
||||
game/src/multiplayer/lobby/LobbyUiLayer.h
|
||||
)
|
||||
|
||||
target_link_libraries(ColorRace PRIVATE
|
||||
@ -342,15 +354,5 @@ target_link_libraries(ColorRaceTests PRIVATE
|
||||
GTest::gtest_main
|
||||
)
|
||||
|
||||
if(WIN32)
|
||||
# Windows benötigt zwingend die WinSock-Libraries und Win-Header-Anpassungen
|
||||
target_link_libraries(ColorRace PRIVATE ws2_32 mswsock)
|
||||
target_compile_definitions(ColorRace PRIVATE _WIN32_WINNT=0x0601) # Mindestens Windows 7 Target
|
||||
else()
|
||||
# Linux/macOS benötigt die Thread-Library für die Hintergrund-Worker
|
||||
find_package(Threads REQUIRED)
|
||||
target_link_libraries(ColorRace PRIVATE Threads::Threads)
|
||||
endif()
|
||||
|
||||
include(GoogleTest)
|
||||
gtest_discover_tests(ColorRaceTests)
|
||||
11
assets/shaders/gui.frag
Normal file
11
assets/shaders/gui.frag
Normal file
@ -0,0 +1,11 @@
|
||||
#version 460 core
|
||||
|
||||
in vec2 textureCoords;
|
||||
|
||||
out vec4 color;
|
||||
|
||||
uniform sampler2D guiTexture;
|
||||
|
||||
void main() {
|
||||
color = texture(guiTexture, textureCoords);
|
||||
}
|
||||
12
assets/shaders/gui.vert
Normal file
12
assets/shaders/gui.vert
Normal file
@ -0,0 +1,12 @@
|
||||
#version 460 core
|
||||
|
||||
layout(location = 0) in vec2 position;
|
||||
|
||||
out vec2 textureCoords;
|
||||
|
||||
uniform mat4 transformationMatrix;
|
||||
|
||||
void main() {
|
||||
gl_Position = transformationMatrix * vec4(position, 0.0, 1.0);
|
||||
textureCoords = vec2((position.x + 1.0) / 2.0, (position.y + 1.0) / 2.0);
|
||||
}
|
||||
BIN
assets/textures/main_menu_background.png
Normal file
BIN
assets/textures/main_menu_background.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.8 MiB |
BIN
assets/textures/multiplayer_lobby.png
Normal file
BIN
assets/textures/multiplayer_lobby.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.8 MiB |
BIN
assets/textures/multiplayer_lobby_background.png
Normal file
BIN
assets/textures/multiplayer_lobby_background.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.8 MiB |
BIN
assets/textures/splash_screen.png
Normal file
BIN
assets/textures/splash_screen.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.7 MiB |
@ -15,7 +15,18 @@ namespace engine {
|
||||
m_inputContextStack(),
|
||||
m_keyboard(*m_window),
|
||||
m_mouse(*m_window),
|
||||
m_sceneManager(m_inputContextStack) {
|
||||
m_sceneManager(m_inputContextStack),
|
||||
m_applicationEventBus(std::make_shared<EventBus<ApplicationEvents>>()) {
|
||||
m_applicationEventBus->subscribe([this](ApplicationEvents& event) {
|
||||
std::visit([this](auto&& e) {
|
||||
using T = std::decay_t<decltype(e)>;
|
||||
if constexpr (std::is_same_v<T, QuitRequested>) {
|
||||
m_window->requestWindowClose();
|
||||
} else if constexpr (std::is_same_v<T, SceneSwitchRequested>) {
|
||||
m_sceneManager.switchTo(std::move(e.nextScene), std::move(e.onSceneLoaded));
|
||||
}
|
||||
}, event);
|
||||
});
|
||||
}
|
||||
|
||||
Application::~Application() = default;
|
||||
|
||||
@ -11,6 +11,7 @@
|
||||
|
||||
#include "Window.h"
|
||||
#include "audio/AudioDevice.h"
|
||||
#include "events/ApplicationEvents.h"
|
||||
#include "inputsOutputs/context/InputContextStack.h"
|
||||
#include "inputsOutputs/inputs/Keyboard.h"
|
||||
#include "inputsOutputs/inputs/Mouse.h"
|
||||
@ -25,6 +26,7 @@ namespace engine {
|
||||
virtual ~Application();
|
||||
|
||||
void run();
|
||||
void requestClose();
|
||||
|
||||
protected:
|
||||
virtual void onUpdate(float deltaTime) {}
|
||||
@ -34,6 +36,7 @@ namespace engine {
|
||||
Keyboard& getKeyboard() { return m_keyboard; }
|
||||
Mouse& getMouse() { return m_mouse; }
|
||||
|
||||
std::shared_ptr<EventBus<ApplicationEvents>> m_applicationEventBus;
|
||||
private:
|
||||
EngineConfig m_config;
|
||||
std::unique_ptr<Window> m_window;
|
||||
|
||||
@ -84,4 +84,8 @@ namespace engine {
|
||||
glfwGetFramebufferSize(m_handle, &width, &height);
|
||||
return height;
|
||||
}
|
||||
|
||||
void Window::requestWindowClose() {
|
||||
glfwSetWindowShouldClose(m_handle, true);
|
||||
}
|
||||
}
|
||||
|
||||
@ -36,6 +36,8 @@ namespace engine {
|
||||
|
||||
void setMouse(Mouse* mouse) { m_callbackTarget.mouse = mouse; }
|
||||
void setKeyboard(Keyboard* keyboard) { m_callbackTarget.keyboard = keyboard; }
|
||||
|
||||
void requestWindowClose();
|
||||
private:
|
||||
GLFWwindow* m_handle;
|
||||
CallbackTarget m_callbackTarget;
|
||||
|
||||
14
engine/src/core/events/ApplicationEvents.cpp
Normal file
14
engine/src/core/events/ApplicationEvents.cpp
Normal file
@ -0,0 +1,14 @@
|
||||
//
|
||||
// Created by sebastian on 07.08.26.
|
||||
//
|
||||
#include "ApplicationEvents.h"
|
||||
#include "layer/Scene.h" // hier ist Scene vollständig bekannt
|
||||
|
||||
SceneSwitchRequested::SceneSwitchRequested() = default;
|
||||
|
||||
SceneSwitchRequested::SceneSwitchRequested(std::unique_ptr<engine::Scene> scene, std::function<void()> callback) : nextScene(std::move(scene)), onSceneLoaded(std::move(callback)){
|
||||
}
|
||||
|
||||
SceneSwitchRequested::~SceneSwitchRequested() = default;
|
||||
SceneSwitchRequested::SceneSwitchRequested(SceneSwitchRequested&&) noexcept = default;
|
||||
SceneSwitchRequested& SceneSwitchRequested::operator=(SceneSwitchRequested&&) noexcept = default;
|
||||
31
engine/src/core/events/ApplicationEvents.h
Normal file
31
engine/src/core/events/ApplicationEvents.h
Normal file
@ -0,0 +1,31 @@
|
||||
//
|
||||
// Created by sebastian on 06.08.26.
|
||||
//
|
||||
|
||||
#ifndef COLORRACE_APPLICATIONEVENTS_H
|
||||
#define COLORRACE_APPLICATIONEVENTS_H
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <variant>
|
||||
|
||||
|
||||
namespace engine {
|
||||
class Scene;
|
||||
}
|
||||
|
||||
struct QuitRequested {};
|
||||
|
||||
struct SceneSwitchRequested {
|
||||
std::unique_ptr<engine::Scene> nextScene;
|
||||
std::function<void()> onSceneLoaded;
|
||||
|
||||
SceneSwitchRequested();
|
||||
SceneSwitchRequested(std::unique_ptr<engine::Scene> scene, std::function<void()> callback);
|
||||
~SceneSwitchRequested();
|
||||
SceneSwitchRequested(SceneSwitchRequested&&) noexcept;
|
||||
SceneSwitchRequested& operator=(SceneSwitchRequested&&) noexcept;
|
||||
};
|
||||
|
||||
|
||||
using ApplicationEvents = std::variant<QuitRequested, SceneSwitchRequested>;
|
||||
#endif //COLORRACE_APPLICATIONEVENTS_H
|
||||
@ -5,23 +5,36 @@
|
||||
#ifndef COLORRACE_EVENTBUS_H
|
||||
#define COLORRACE_EVENTBUS_H
|
||||
#include <functional>
|
||||
#include <mutex>
|
||||
|
||||
namespace engine {
|
||||
class IEventBus {
|
||||
public:
|
||||
virtual ~IEventBus() = default;
|
||||
};
|
||||
|
||||
template<typename Event>
|
||||
class EventBus {
|
||||
public:
|
||||
using Handler = std::function<void(Event&)>;
|
||||
|
||||
void subscribe(Handler handler) {
|
||||
std::lock_guard<std::mutex> lock(m_mutex);
|
||||
m_handlers.push_back(handler);
|
||||
}
|
||||
|
||||
void publish(Event& event) const {
|
||||
for (const auto& handler : m_handlers) {
|
||||
std::vector<Handler> handlersCopy;
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_mutex);
|
||||
handlersCopy = m_handlers;
|
||||
}
|
||||
for (const auto& handler : handlersCopy) {
|
||||
handler(event);
|
||||
}
|
||||
}
|
||||
private:
|
||||
mutable std::mutex m_mutex;
|
||||
std::vector<Handler> m_handlers;
|
||||
};
|
||||
} // engine
|
||||
|
||||
5
engine/src/core/events/EventChannels.cpp
Normal file
5
engine/src/core/events/EventChannels.cpp
Normal file
@ -0,0 +1,5 @@
|
||||
//
|
||||
// Created by sebastian on 06.08.26.
|
||||
//
|
||||
|
||||
#include "EventChannels.h"
|
||||
43
engine/src/core/events/EventChannels.h
Normal file
43
engine/src/core/events/EventChannels.h
Normal file
@ -0,0 +1,43 @@
|
||||
//
|
||||
// Created by sebastian on 06.08.26.
|
||||
//
|
||||
|
||||
#ifndef COLORRACE_EVENTCHANNELS_H
|
||||
#define COLORRACE_EVENTCHANNELS_H
|
||||
#include <memory>
|
||||
#include <typeindex>
|
||||
|
||||
#include "EventBus.h"
|
||||
|
||||
|
||||
namespace engine {
|
||||
class EventChannels {
|
||||
public:
|
||||
template<typename Event>
|
||||
void subscribe(typename EventBus<Event>::Handler handler) {
|
||||
getBus<Event>().subscribe(std::move(handler));
|
||||
}
|
||||
|
||||
template<typename Event>
|
||||
void publish(Event& event) {
|
||||
getBus<Event>().publish(event);
|
||||
}
|
||||
|
||||
template<typename Event>
|
||||
EventBus<Event>& getBus() {
|
||||
auto key = std::type_index(typeid(Event));
|
||||
auto it = m_buses.find(key);
|
||||
if (it == m_buses.end()) {
|
||||
auto bus = std::make_unique<EventBus<Event>>();
|
||||
auto* ptr = bus.get();
|
||||
m_buses.emplace(key, std::move(bus));
|
||||
return *ptr;
|
||||
}
|
||||
return static_cast<EventBus<Event>&>(*it->second);
|
||||
}
|
||||
private:
|
||||
std::unordered_map<std::type_index, std::unique_ptr<IEventBus>> m_buses;
|
||||
};
|
||||
}
|
||||
|
||||
#endif //COLORRACE_EVENTCHANNELS_H
|
||||
@ -5,6 +5,7 @@
|
||||
#ifndef COLORRACE_LAYER_H
|
||||
#define COLORRACE_LAYER_H
|
||||
#include "core/animation/events/AnimationMarkerEvent.h"
|
||||
#include "core/events/ApplicationEvents.h"
|
||||
#include "core/events/EventBus.h"
|
||||
#include "core/inputsOutputs/context/InputContextStack.h"
|
||||
#include "core/inputsOutputs/inputs/Keyboard.h"
|
||||
@ -16,6 +17,7 @@ namespace engine {
|
||||
class Layer {
|
||||
public:
|
||||
Layer(Keyboard& keyboard, Mouse& mouse, EventBus<animation::AnimationMarkerEvent>& animationEventBus) : m_keyboard(keyboard), m_mouse(mouse), m_animationEventBus(animationEventBus){};
|
||||
Layer(Keyboard& keyboard, Mouse& mouse, EventBus<animation::AnimationMarkerEvent>& animationEventBus, std::shared_ptr<EventBus<ApplicationEvents>> applicationEventBus) : m_keyboard(keyboard), m_mouse(mouse), m_animationEventBus(animationEventBus), m_applicationEventBus(std::move(applicationEventBus)){};
|
||||
virtual ~Layer() = default;
|
||||
void onAttach(InputContextStack& inputStack);
|
||||
void onDetach(InputContextStack& inputStack);
|
||||
@ -29,6 +31,8 @@ namespace engine {
|
||||
Keyboard& getKeyboard() { return m_keyboard; }
|
||||
Mouse& getMouse() { return m_mouse; }
|
||||
EventBus<animation::AnimationMarkerEvent>& getAnimationEventBus() { return m_animationEventBus; }
|
||||
|
||||
std::shared_ptr<EventBus<ApplicationEvents>> m_applicationEventBus;
|
||||
private:
|
||||
std::shared_ptr<InputContext> m_context;
|
||||
InputContextStack* m_inputStack = nullptr;
|
||||
|
||||
@ -9,6 +9,7 @@
|
||||
|
||||
#include "Layer.h"
|
||||
#include "core/animation/events/AnimationMarkerEvent.h"
|
||||
#include "core/events/ApplicationEvents.h"
|
||||
#include "core/events/EventBus.h"
|
||||
#include "loader/assets/AssetManager.h"
|
||||
#include "loader/assets/AssetRequests.h"
|
||||
@ -23,8 +24,8 @@ namespace engine {
|
||||
|
||||
class Scene {
|
||||
public:
|
||||
explicit Scene(engine::InputContextStack& inputStack, engine::Keyboard& keyboard, engine::Mouse& mouse):
|
||||
assetManager(std::make_unique<AssetManager>()), m_inputStack(inputStack), m_keyboard(keyboard), m_mouse(mouse) {}
|
||||
explicit Scene(std::shared_ptr<engine::EventBus<ApplicationEvents>> applicationEventbus, engine::InputContextStack& inputStack, engine::Keyboard& keyboard, engine::Mouse& mouse):
|
||||
assetManager(std::make_unique<AssetManager>()), m_inputStack(inputStack), m_keyboard(keyboard), m_mouse(mouse), m_applicationEventBus(std::move(applicationEventbus)) {}
|
||||
virtual ~Scene() = default;
|
||||
virtual void onEnter() {}
|
||||
virtual void onExit() {
|
||||
@ -51,9 +52,10 @@ namespace engine {
|
||||
|
||||
engine::Keyboard& m_keyboard;
|
||||
engine::Mouse& m_mouse;
|
||||
|
||||
std::shared_ptr<engine::EventBus<ApplicationEvents>> m_applicationEventBus;
|
||||
private:
|
||||
EventBus<animation::AnimationMarkerEvent> m_animationMarkerEventBus;
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
5
engine/src/loader/models/Mesh.cpp
Normal file
5
engine/src/loader/models/Mesh.cpp
Normal file
@ -0,0 +1,5 @@
|
||||
//
|
||||
// Created by sebastian on 06.08.26.
|
||||
//
|
||||
|
||||
#include "Mesh.h"
|
||||
20
engine/src/loader/models/Mesh.h
Normal file
20
engine/src/loader/models/Mesh.h
Normal file
@ -0,0 +1,20 @@
|
||||
//
|
||||
// Created by sebastian on 06.08.26.
|
||||
//
|
||||
|
||||
#ifndef COLORRACE_MESH_H
|
||||
#define COLORRACE_MESH_H
|
||||
|
||||
|
||||
namespace engine {
|
||||
class Mesh {
|
||||
public:
|
||||
virtual ~Mesh() = default;
|
||||
virtual void bind() const = 0;
|
||||
virtual void unbind() const = 0;
|
||||
virtual void draw() const = 0;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif //COLORRACE_MESH_H
|
||||
17
engine/src/loader/models/SimpleTexturedMesh.cpp
Normal file
17
engine/src/loader/models/SimpleTexturedMesh.cpp
Normal file
@ -0,0 +1,17 @@
|
||||
//
|
||||
// Created by sebastian on 06.08.26.
|
||||
//
|
||||
|
||||
#include "SimpleTexturedMesh.h"
|
||||
|
||||
void engine::SimpleTexturedMesh::bind() const {
|
||||
m_vao->bind();
|
||||
}
|
||||
|
||||
void engine::SimpleTexturedMesh::unbind() const {
|
||||
m_vao->unbind();
|
||||
}
|
||||
|
||||
void engine::SimpleTexturedMesh::draw() const {
|
||||
glDrawArrays(GL_TRIANGLES, 0, 6);
|
||||
}
|
||||
25
engine/src/loader/models/SimpleTexturedMesh.h
Normal file
25
engine/src/loader/models/SimpleTexturedMesh.h
Normal file
@ -0,0 +1,25 @@
|
||||
//
|
||||
// Created by sebastian on 06.08.26.
|
||||
//
|
||||
|
||||
#ifndef COLORRACE_SIMPLETEXTUREDMESH_H
|
||||
#define COLORRACE_SIMPLETEXTUREDMESH_H
|
||||
#include "Mesh.h"
|
||||
#include "utils/openglWrapper/openglObjects/Vao.h"
|
||||
|
||||
namespace engine {
|
||||
class SimpleTexturedMesh : public engine::Mesh{
|
||||
public:
|
||||
SimpleTexturedMesh(std::unique_ptr<Vao> vao, int vertexCount) : m_vao(std::move(vao)), vertexCount(vertexCount) {}
|
||||
void bind() const override;
|
||||
void unbind() const override;
|
||||
void draw() const override;
|
||||
private:
|
||||
std::unique_ptr<Vao> m_vao;
|
||||
int vertexCount;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif //COLORRACE_SIMPLETEXTUREDMESH_H
|
||||
19
engine/src/renderer/GuiRenderer.cpp
Normal file
19
engine/src/renderer/GuiRenderer.cpp
Normal file
@ -0,0 +1,19 @@
|
||||
//
|
||||
// Created by sebastian on 06.08.26.
|
||||
//
|
||||
|
||||
#include "GuiRenderer.h"
|
||||
|
||||
void engine::renderer::GuiRenderer::render(const std::vector<GUITexture> &guiElements) const {
|
||||
m_shader->start();
|
||||
m_renderState.apply();
|
||||
|
||||
m_fullscreenQuad->bind();
|
||||
for (auto& guiElement : guiElements) {
|
||||
m_shader->loadTransformationMatrix(guiElement.getTransform());
|
||||
guiElement.getTexture()->bind();
|
||||
m_fullscreenQuad->draw();
|
||||
guiElement.getTexture()->unbind();
|
||||
}
|
||||
m_fullscreenQuad->unbind();
|
||||
}
|
||||
36
engine/src/renderer/GuiRenderer.h
Normal file
36
engine/src/renderer/GuiRenderer.h
Normal file
@ -0,0 +1,36 @@
|
||||
//
|
||||
// Created by sebastian on 06.08.26.
|
||||
//
|
||||
|
||||
#ifndef COLORRACE_GUIRENDERER_H
|
||||
#define COLORRACE_GUIRENDERER_H
|
||||
#include <memory>
|
||||
|
||||
#include "loader/models/SimpleTexturedMesh.h"
|
||||
#include "primitives/QuadFactory.h"
|
||||
#include "shader/GuiShader.h"
|
||||
#include "ui/GUITexture.h"
|
||||
#include "utils/openglWrapper/GLRenderState.h"
|
||||
|
||||
|
||||
namespace engine::renderer {
|
||||
class GuiRenderer {
|
||||
public:
|
||||
GuiRenderer() : m_shader(std::make_unique<shader::GuiShader>()) {
|
||||
m_renderState.depthTesting = false;
|
||||
m_renderState.depthWriting = false;
|
||||
m_renderState.alphaBlending = true;
|
||||
m_renderState.backfaceCulling = false;
|
||||
m_renderState.frontFaceCulling = false;
|
||||
|
||||
m_fullscreenQuad = engine::QuadFactory::createFullScreenQuad();
|
||||
}
|
||||
void render(const std::vector<GUITexture> &guiElements) const;
|
||||
private:
|
||||
std::shared_ptr<SimpleTexturedMesh> m_fullscreenQuad;
|
||||
std::unique_ptr<shader::GuiShader> m_shader;
|
||||
GLRenderState m_renderState;
|
||||
};
|
||||
}
|
||||
|
||||
#endif //COLORRACE_GUIRENDERER_H
|
||||
28
engine/src/renderer/primitives/QuadFactory.cpp
Normal file
28
engine/src/renderer/primitives/QuadFactory.cpp
Normal file
@ -0,0 +1,28 @@
|
||||
//
|
||||
// Created by sebastian on 06.08.26.
|
||||
//
|
||||
|
||||
#include "QuadFactory.h"
|
||||
|
||||
std::shared_ptr<engine::SimpleTexturedMesh> engine::QuadFactory::createFullScreenQuad() {
|
||||
// pos.xy in NDC, uv.xy
|
||||
std::vector<float> vertices = {
|
||||
-1,-1,
|
||||
1,-1,
|
||||
1, 1,
|
||||
|
||||
1, 1,
|
||||
-1, 1,
|
||||
-1,-1
|
||||
};
|
||||
std::vector<unsigned int> indices = { 0, 1, 2, 2, 3, 0 };
|
||||
|
||||
auto vao = Vao::create();
|
||||
std::vector<std::unique_ptr<Attribute>> attribs;
|
||||
attribs.push_back(std::make_unique<Vec2Attribute>(0)); // position
|
||||
vao->initDataFeed(vertices.data(), vertices.size() * sizeof(float), GL_STATIC_DRAW, std::move(attribs));
|
||||
vao->createIndexBuffer(indices.data(), indices.size());
|
||||
vao->unbind();
|
||||
|
||||
return std::make_shared<engine::SimpleTexturedMesh>(std::move(vao), 4);
|
||||
}
|
||||
17
engine/src/renderer/primitives/QuadFactory.h
Normal file
17
engine/src/renderer/primitives/QuadFactory.h
Normal file
@ -0,0 +1,17 @@
|
||||
//
|
||||
// Created by sebastian on 06.08.26.
|
||||
//
|
||||
|
||||
#ifndef COLORRACE_QUADFACTORY_H
|
||||
#define COLORRACE_QUADFACTORY_H
|
||||
#include <memory>
|
||||
|
||||
#include "loader/models/SimpleTexturedMesh.h"
|
||||
|
||||
|
||||
namespace engine::QuadFactory {
|
||||
std::shared_ptr<engine::SimpleTexturedMesh> createFullScreenQuad();
|
||||
}
|
||||
|
||||
|
||||
#endif //COLORRACE_QUADFACTORY_H
|
||||
5
engine/src/renderer/shader/GuiShader.cpp
Normal file
5
engine/src/renderer/shader/GuiShader.cpp
Normal file
@ -0,0 +1,5 @@
|
||||
//
|
||||
// Created by sebastian on 06.08.26.
|
||||
//
|
||||
|
||||
#include "GuiShader.h"
|
||||
30
engine/src/renderer/shader/GuiShader.h
Normal file
30
engine/src/renderer/shader/GuiShader.h
Normal file
@ -0,0 +1,30 @@
|
||||
//
|
||||
// Created by sebastian on 06.08.26.
|
||||
//
|
||||
|
||||
#ifndef COLORRACE_GUISHADER_H
|
||||
#define COLORRACE_GUISHADER_H
|
||||
#include <functional>
|
||||
|
||||
#include "glm/fwd.hpp"
|
||||
#include "utils/openglWrapper/shader/ShaderProgram.h"
|
||||
#include "utils/openglWrapper/shader/UniformValue.h"
|
||||
|
||||
namespace engine::shader {
|
||||
class GuiShader : public ShaderProgram {
|
||||
public:
|
||||
GuiShader() : ShaderProgram("assets/shaders/gui.vert", "assets/shaders/gui.frag") {
|
||||
storeAllUniformLocations({
|
||||
std::ref(transformationMatrix)
|
||||
});
|
||||
}
|
||||
void loadTransformationMatrix(const glm::mat4& matrix) {
|
||||
transformationMatrix.load(matrix);
|
||||
}
|
||||
private:
|
||||
UniformValue<glm::mat4> transformationMatrix{"transformationMatrix"};
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
#endif //COLORRACE_GUISHADER_H
|
||||
28
engine/src/renderer/ui/GUITexture.cpp
Normal file
28
engine/src/renderer/ui/GUITexture.cpp
Normal file
@ -0,0 +1,28 @@
|
||||
//
|
||||
// Created by sebastian on 06.08.26.
|
||||
//
|
||||
|
||||
#include "GUITexture.h"
|
||||
#include "glm/glm.hpp"
|
||||
#include "glm/ext/matrix_transform.hpp"
|
||||
|
||||
namespace engine {
|
||||
void GUITexture::bind() {
|
||||
texture->bind();
|
||||
}
|
||||
|
||||
void GUITexture::unbind() {
|
||||
texture->unbind();
|
||||
}
|
||||
|
||||
glm::mat4 GUITexture::getTransform() const {
|
||||
glm::vec2 translationNDC;
|
||||
translationNDC.x = position.x * 2.0f - 1.0f + size.x;
|
||||
translationNDC.y = 1.0f - position.y * 2.0f - size.y;
|
||||
|
||||
auto matrix = glm::identity<glm::mat4>();
|
||||
matrix = glm::translate(matrix, glm::vec3( translationNDC, 0.0f));
|
||||
matrix = glm::scale(matrix, glm::vec3(size.x, size.y, 1.0f));
|
||||
return matrix;
|
||||
}
|
||||
} // engine
|
||||
33
engine/src/renderer/ui/GUITexture.h
Normal file
33
engine/src/renderer/ui/GUITexture.h
Normal file
@ -0,0 +1,33 @@
|
||||
//
|
||||
// Created by sebastian on 06.08.26.
|
||||
//
|
||||
|
||||
#ifndef COLORRACE_GUITEXTURE_H
|
||||
#define COLORRACE_GUITEXTURE_H
|
||||
#include <memory>
|
||||
|
||||
#include "glm/fwd.hpp"
|
||||
#include "glm/vec2.hpp"
|
||||
#include "loader/textures/Texture2D.h"
|
||||
|
||||
namespace engine {
|
||||
class GUITexture {
|
||||
public:
|
||||
GUITexture(std::shared_ptr<Texture2D> texture, glm::vec2 position, glm::vec2 size) : position(position), size(size), texture(std::move(texture)) {}
|
||||
[[nodiscard]] const glm::vec2& getPosition() const { return position; }
|
||||
[[nodiscard]] const glm::vec2& getSize() const { return size; }
|
||||
[[nodiscard]] const std::shared_ptr<Texture2D>& getTexture() const { return texture; }
|
||||
|
||||
void bind();
|
||||
void unbind();
|
||||
|
||||
glm::mat4 getTransform() const;
|
||||
private:
|
||||
const glm::vec2 position;
|
||||
const glm::vec2 size;
|
||||
|
||||
std::shared_ptr<Texture2D> texture;
|
||||
};
|
||||
} // engine
|
||||
|
||||
#endif //COLORRACE_GUITEXTURE_H
|
||||
1
external/NetworkCore
vendored
Submodule
1
external/NetworkCore
vendored
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit 79214c855ac1c414fe85ffe76af4e2e57b8305ec
|
||||
@ -13,6 +13,7 @@
|
||||
|
||||
void ColorRaceApp::onUpdate(float deltaTime) {
|
||||
getSceneManager().update(deltaTime);
|
||||
|
||||
}
|
||||
|
||||
void ColorRaceApp::onRender() {
|
||||
|
||||
@ -6,11 +6,15 @@
|
||||
#define COLORRACE_COLORRACEAPP_H
|
||||
#include "gameLayer/GameLayer.h"
|
||||
#include "GameScene.h"
|
||||
#include "../../external/NetworkCore/src/client/GameClient.h"
|
||||
#include "core/Application.h"
|
||||
#include "ecs/EntityRegistry.h"
|
||||
#include "ecs/standardComponents/MeshComponent.h"
|
||||
#include "ecs/standardComponents/TransformComponent.h"
|
||||
#include "layer/SceneManager.h"
|
||||
#include "mainMenu/MainMenuScene.h"
|
||||
#include "multiplayer/LudoGameClient.h"
|
||||
#include "multiplayer/LudoNetworkEvents.h"
|
||||
#include "renderer/MeshRenderer.h"
|
||||
#include "renderer/entities/Camera.h"
|
||||
#include "renderer/shader/StaticShader.h"
|
||||
@ -32,12 +36,28 @@ public:
|
||||
config.debugContext = true;
|
||||
return config;
|
||||
}
|
||||
ColorRaceApp() : Application(makeConfig()) {
|
||||
getSceneManager().switchTo(std::make_unique<GameScene>(getInputContextStack(), getKeyboard(), getMouse()));
|
||||
ColorRaceApp() : Application(makeConfig()), m_networkEventBus(std::make_shared<engine::EventBus<NetworkEvents>>()) {
|
||||
getSceneManager().switchTo(std::make_unique<MainMenuScene>(m_applicationEventBus, m_networkEventBus, getInputContextStack(), getKeyboard(), getMouse()));
|
||||
m_networkEventBus->subscribe([this](NetworkEvents& event) {
|
||||
std::visit([this](auto&& e) {
|
||||
using T = std::decay_t<decltype(e)>;
|
||||
if constexpr (std::is_same_v<T, ConnectRequest>) {
|
||||
engine::net::ClientConfig client_config;
|
||||
client_config.host = e.host;
|
||||
client_config.port = e.port;
|
||||
m_ludoGameClient = std::make_unique<LudoGameClient>(client_config, m_networkEventBus);
|
||||
m_ludoGameClient->onStart();
|
||||
}
|
||||
}, event);
|
||||
});
|
||||
}
|
||||
protected:
|
||||
void onUpdate(float deltaTime) override;
|
||||
void onRender() override;
|
||||
std::shared_ptr<engine::EventBus<NetworkEvents>> m_networkEventBus;
|
||||
|
||||
private:
|
||||
std::unique_ptr<LudoGameClient> m_ludoGameClient;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@ -12,7 +12,7 @@
|
||||
#include "layer/DebugLayer.h"
|
||||
#include "renderer/primitives/SphereFactory.h"
|
||||
|
||||
GameScene::GameScene(engine::InputContextStack& inputStack, engine::Keyboard& keyboard, engine::Mouse& mouse) : Scene(inputStack, keyboard, mouse), m_camera(std::make_unique<engine::Camera>()) {
|
||||
GameScene::GameScene(std::shared_ptr<engine::EventBus<ApplicationEvents>> applicationEventbus, engine::InputContextStack& inputStack, engine::Keyboard& keyboard, engine::Mouse& mouse) : Scene(std::move(applicationEventbus), inputStack, keyboard, mouse), m_camera(std::make_unique<engine::Camera>()) {
|
||||
m_pointLight = std::make_shared<engine::PointLight>(glm::vec3(.0f, 10.f, -5.0f), glm::vec3(1.0f, 1.0f, 1.0f));
|
||||
const std::vector<unsigned int> players = {0,1,2,3};
|
||||
m_gameMode = std::make_shared<ludo::LudoGameMode>(m_eventBus, players);
|
||||
|
||||
@ -12,7 +12,7 @@
|
||||
|
||||
class GameScene : public engine::Scene {
|
||||
public:
|
||||
GameScene(engine::InputContextStack& inputContext, engine::Keyboard& keyboard, engine::Mouse& mouse);
|
||||
GameScene(std::shared_ptr<engine::EventBus<ApplicationEvents>> applicationEventbus, engine::InputContextStack& inputContext, engine::Keyboard& keyboard, engine::Mouse& mouse);
|
||||
void onEnter() override;
|
||||
void onExit() override;
|
||||
std::vector<engine::AssetRequest> getRequiredAssets() const override;
|
||||
|
||||
@ -1,5 +0,0 @@
|
||||
//
|
||||
// Created by sebastian on 05.08.26.
|
||||
//
|
||||
|
||||
#include "IGameSession.h"
|
||||
@ -1,23 +0,0 @@
|
||||
//
|
||||
// Created by sebastian on 05.08.26.
|
||||
//
|
||||
|
||||
#ifndef COLORRACE_IGAMESESSION_H
|
||||
#define COLORRACE_IGAMESESSION_H
|
||||
#include "ludo/LudoTypes.h"
|
||||
|
||||
|
||||
class IGameSession {
|
||||
public:
|
||||
virtual ~IGameSession() = default;
|
||||
|
||||
// Befehle von der UI an das Spiel senden
|
||||
virtual void sendCommand(const std::variant<ludo::MovePieceCommand, ludo::RollDiceCommand> &command) {
|
||||
}
|
||||
|
||||
// Events vom Spiel abholen, um die UI zu aktualisieren
|
||||
virtual std::vector<ludo::LudoEvent> pollEvents() = 0;
|
||||
};
|
||||
|
||||
|
||||
#endif //COLORRACE_IGAMESESSION_H
|
||||
@ -1,14 +0,0 @@
|
||||
//
|
||||
// Created by sebastian on 05.08.26.
|
||||
//
|
||||
|
||||
#include "LocalGameSession.h"
|
||||
|
||||
void LocalGameSession::sendCommand(const std::variant<ludo::MovePieceCommand, ludo::RollDiceCommand> &command) {
|
||||
IGameSession::sendCommand(command);
|
||||
m_gameMode.sendCommand(command);
|
||||
}
|
||||
|
||||
std::vector<ludo::LudoEvent> LocalGameSession::pollEvents() {
|
||||
return m_gameMode.pollEvents();
|
||||
}
|
||||
@ -1,20 +0,0 @@
|
||||
//
|
||||
// Created by sebastian on 05.08.26.
|
||||
//
|
||||
|
||||
#ifndef COLORRACE_LOCALGAMESESSION_H
|
||||
#define COLORRACE_LOCALGAMESESSION_H
|
||||
#include "IGameSession.h"
|
||||
#include "ludo/LudoGameMode.h"
|
||||
|
||||
|
||||
class LocalGameSession : public IGameSession{
|
||||
private:
|
||||
ludo::LudoGameMode m_gameMode;
|
||||
public:
|
||||
void sendCommand(const std::variant<ludo::MovePieceCommand, ludo::RollDiceCommand> &command) override;
|
||||
std::vector<ludo::LudoEvent> pollEvents() override;
|
||||
};
|
||||
|
||||
|
||||
#endif //COLORRACE_LOCALGAMESESSION_H
|
||||
@ -1,17 +0,0 @@
|
||||
//
|
||||
// Created by sebastian on 05.08.26.
|
||||
//
|
||||
|
||||
#include "RemoteGameSession.h"
|
||||
|
||||
void RemoteGameSession::sendCommand(const std::variant<ludo::MovePieceCommand, ludo::RollDiceCommand> &command) {
|
||||
// 1. In JSON / Bytes verpacken
|
||||
// 2. Über den Socket asynchron an den Server senden
|
||||
// m_socket.send(serializedCommand);
|
||||
}
|
||||
|
||||
std::vector<ludo::LudoEvent> RemoteGameSession::pollEvents() {
|
||||
// Holt die Events ab, die der Netzwerk-Thread im Hintergrund
|
||||
// vom Server empfangen und in die Queue gelegt hat.
|
||||
return std::vector<ludo::LudoEvent>();
|
||||
}
|
||||
@ -1,18 +0,0 @@
|
||||
//
|
||||
// Created by sebastian on 05.08.26.
|
||||
//
|
||||
|
||||
#ifndef COLORRACE_REMOTEGAMESESSION_H
|
||||
#define COLORRACE_REMOTEGAMESESSION_H
|
||||
#include "IGameSession.h"
|
||||
|
||||
|
||||
class RemoteGameSession : public IGameSession{
|
||||
private:
|
||||
public:
|
||||
void sendCommand(const std::variant<ludo::MovePieceCommand, ludo::RollDiceCommand> &command) override;
|
||||
std::vector<ludo::LudoEvent> pollEvents() override;
|
||||
};
|
||||
|
||||
|
||||
#endif //COLORRACE_REMOTEGAMESESSION_H
|
||||
18
game/src/mainMenu/MainMenuScene.cpp
Normal file
18
game/src/mainMenu/MainMenuScene.cpp
Normal file
@ -0,0 +1,18 @@
|
||||
//
|
||||
// Created by sebastian on 06.08.26.
|
||||
//
|
||||
|
||||
#include "MainMenuScene.h"
|
||||
|
||||
#include "layer/MainMenuUiLayer.h"
|
||||
|
||||
void MainMenuScene::onEnter() {
|
||||
Scene::onEnter();
|
||||
addLayer(std::make_unique<MainMenuUiLayer>(m_keyboard, m_mouse, getAnimationEventBus(), m_applicationEventBus, m_networkEventBus, *assetManager));
|
||||
}
|
||||
|
||||
std::vector<engine::AssetRequest> MainMenuScene::getRequiredAssets() const {
|
||||
std::vector<engine::AssetRequest> requests;
|
||||
requests.emplace_back(engine::TextureRequest("main_menu_background", "assets/textures/main_menu_background.png"));
|
||||
return requests;
|
||||
}
|
||||
23
game/src/mainMenu/MainMenuScene.h
Normal file
23
game/src/mainMenu/MainMenuScene.h
Normal file
@ -0,0 +1,23 @@
|
||||
//
|
||||
// Created by sebastian on 06.08.26.
|
||||
//
|
||||
|
||||
#ifndef COLORRACE_MAINMENUSCENE_H
|
||||
#define COLORRACE_MAINMENUSCENE_H
|
||||
#include <utility>
|
||||
|
||||
#include "layer/Scene.h"
|
||||
#include "multiplayer/LudoNetworkEvents.h"
|
||||
|
||||
|
||||
class MainMenuScene : public engine::Scene {
|
||||
public:
|
||||
MainMenuScene(std::shared_ptr<engine::EventBus<ApplicationEvents>> applicationEventbus, std::shared_ptr<engine::EventBus<NetworkEvents>> networkEventbus, engine::InputContextStack& inputContext, engine::Keyboard& keyboard, engine::Mouse& mouse) : Scene(std::move(applicationEventbus), inputContext, keyboard, mouse), m_networkEventBus(std::move(networkEventbus)) {}
|
||||
void onEnter() override;
|
||||
std::vector<engine::AssetRequest> getRequiredAssets() const override;
|
||||
private:
|
||||
std::shared_ptr<engine::EventBus<NetworkEvents>> m_networkEventBus;
|
||||
};
|
||||
|
||||
|
||||
#endif //COLORRACE_MAINMENUSCENE_H
|
||||
132
game/src/mainMenu/layer/MainMenuUiLayer.cpp
Normal file
132
game/src/mainMenu/layer/MainMenuUiLayer.cpp
Normal file
@ -0,0 +1,132 @@
|
||||
//
|
||||
// Created by sebastian on 06.08.26.
|
||||
//
|
||||
|
||||
#include "MainMenuUiLayer.h"
|
||||
|
||||
#include "imgui.h"
|
||||
#include "GLFW/glfw3.h"
|
||||
#include "multiplayer/lobby/LobbyScene.h"
|
||||
#include "spdlog/spdlog.h"
|
||||
|
||||
void MainMenuUiLayer::onRender() {
|
||||
Layer::onRender();
|
||||
|
||||
std::vector<engine::GUITexture> guiElements;
|
||||
guiElements.emplace_back(*backgroundImage);
|
||||
m_guiRenderer.render(guiElements);
|
||||
|
||||
// Imgui Main Menu
|
||||
ImGui::SetNextWindowPos(ImVec2(20, 20), ImGuiCond_FirstUseEver);
|
||||
ImGui::Begin("Ludo", nullptr, ImGuiWindowFlags_NoResize | ImGuiWindowFlags_AlwaysAutoResize);
|
||||
|
||||
//ImGui::PushFont(titleFont); // falls du einen größeren Font geladen hast, sonst weglassen
|
||||
ImGui::Text("Ludo");
|
||||
|
||||
ImGui::Separator();
|
||||
ImGui::Spacing();
|
||||
|
||||
const ImVec2 buttonSize(180, 40);
|
||||
|
||||
if (ImGui::Button("Neues Spiel", buttonSize)) {
|
||||
// z.B. State-Wechsel: game.setState(GameState::Playing);
|
||||
}
|
||||
|
||||
ImGui::Spacing();
|
||||
|
||||
ImGui::Spacing();
|
||||
|
||||
if (ImGui::Button("Multiplayer", buttonSize)) {
|
||||
spdlog::info("Open Multiplayer Modal");
|
||||
ImGui::OpenPopup("ConnectToServer");
|
||||
}
|
||||
|
||||
ImGui::Spacing();
|
||||
|
||||
ImGui::Spacing();
|
||||
|
||||
if (ImGui::Button("Quit", buttonSize)) {
|
||||
ApplicationEvents e = QuitRequested{};
|
||||
m_applicationEventBus->publish(e);
|
||||
}
|
||||
|
||||
renderConnectDialog();
|
||||
|
||||
ImGui::End();
|
||||
|
||||
|
||||
}
|
||||
|
||||
void MainMenuUiLayer::onAttachImpl() {
|
||||
Layer::onAttachImpl();
|
||||
|
||||
auto backgroundTexture = m_assetManager.getTexture("main_menu_background");
|
||||
|
||||
backgroundImage = std::make_unique<engine::GUITexture>(backgroundTexture, glm::vec2(0,0), glm::vec2(1,1));
|
||||
|
||||
m_networkEventBus->subscribe([this](NetworkEvents& event) {
|
||||
std::visit([this](auto&& e) {
|
||||
using T = std::decay_t<decltype(e)>;
|
||||
if constexpr (std::is_same_v<T, ConnectResult>) {
|
||||
if (e.success) {
|
||||
spdlog::info("Received positive Connection Result");
|
||||
m_connectionError = false;
|
||||
std::unique_ptr<engine::Scene> lobbyScene = std::make_unique<LobbyScene>(m_applicationEventBus, getInputStack(), getKeyboard(), getMouse());
|
||||
m_closeConnectPopup = true;
|
||||
ApplicationEvents switchToLobby = SceneSwitchRequested{std::move(lobbyScene), []() {
|
||||
spdlog::info("Lobby Scene loaded");
|
||||
}};
|
||||
m_applicationEventBus->publish(switchToLobby);
|
||||
} else {
|
||||
spdlog::info("Received negative Connection Result");
|
||||
m_connectionError = true;
|
||||
m_errorMessage = e.errorMessage;
|
||||
}
|
||||
}
|
||||
}, event);
|
||||
});
|
||||
}
|
||||
|
||||
void MainMenuUiLayer::onDetachImpl() {
|
||||
Layer::onDetachImpl();
|
||||
}
|
||||
|
||||
void MainMenuUiLayer::renderConnectDialog() {
|
||||
// Zentriert öffnen
|
||||
ImVec2 center = ImGui::GetMainViewport()->GetCenter();
|
||||
ImGui::SetNextWindowPos(center, ImGuiCond_Appearing, ImVec2(0.5f, 0.5f));
|
||||
|
||||
if (ImGui::BeginPopupModal("ConnectToServer", nullptr, ImGuiWindowFlags_AlwaysAutoResize)) {
|
||||
if (m_closeConnectPopup) {
|
||||
ImGui::CloseCurrentPopup();
|
||||
}
|
||||
ImGui::InputText("Host", m_hostBuffer, sizeof(m_hostBuffer));
|
||||
ImGui::InputInt("Port", &m_port);
|
||||
|
||||
if (m_connectionError) {
|
||||
ImGui::TextColored(ImVec4(1, 0.3f, 0.3f, 1), "%s", m_errorMessage.c_str());
|
||||
}
|
||||
|
||||
ImGui::Spacing();
|
||||
|
||||
if (ImGui::Button("Connect", ImVec2(120, 0))) {
|
||||
// ApplicationEvents::ConnectRequested e{ m_hostBuffer, static_cast<uint16_t>(m_port) };
|
||||
// m_appEvents.publish(e);
|
||||
// Popup offen lassen bis Ergebnis feststeht, siehe unten
|
||||
NetworkEvents connectRequest = ConnectRequest(m_hostBuffer, static_cast<uint16_t>(m_port));
|
||||
m_networkEventBus->publish(connectRequest);
|
||||
}
|
||||
|
||||
ImGui::SameLine();
|
||||
|
||||
if (ImGui::Button("Cancel", ImVec2(120, 0))) {
|
||||
ImGui::CloseCurrentPopup();
|
||||
}
|
||||
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
}
|
||||
|
||||
void MainMenuUiLayer::onUpdate(float deltaTime) {
|
||||
Layer::onUpdate(deltaTime);
|
||||
}
|
||||
50
game/src/mainMenu/layer/MainMenuUiLayer.h
Normal file
50
game/src/mainMenu/layer/MainMenuUiLayer.h
Normal file
@ -0,0 +1,50 @@
|
||||
//
|
||||
// Created by sebastian on 06.08.26.
|
||||
//
|
||||
|
||||
#ifndef COLORRACE_MAINMENUUILAYER_H
|
||||
#define COLORRACE_MAINMENUUILAYER_H
|
||||
#include <utility>
|
||||
|
||||
#include "layer/Layer.h"
|
||||
#include "loader/assets/AssetManager.h"
|
||||
#include "multiplayer/LudoNetworkEvents.h"
|
||||
#include "renderer/GuiRenderer.h"
|
||||
#include "renderer/ui/GUITexture.h"
|
||||
|
||||
|
||||
class MainMenuUiLayer : public engine::Layer {
|
||||
public:
|
||||
MainMenuUiLayer(engine::Keyboard &keyboard,
|
||||
engine::Mouse &mouse,
|
||||
engine::EventBus<engine::animation::AnimationMarkerEvent> &animationEventBus,
|
||||
std::shared_ptr<engine::EventBus<ApplicationEvents>> applicationEventbus,
|
||||
std::shared_ptr<engine::EventBus<NetworkEvents>> networkEventbus,
|
||||
engine::AssetManager& assetManager)
|
||||
: Layer(keyboard, mouse, animationEventBus, std::move(applicationEventbus)), m_assetManager(assetManager), m_networkEventBus(std::move(networkEventbus)) {
|
||||
}
|
||||
|
||||
void onRender() override;
|
||||
void onUpdate(float deltaTime) override;
|
||||
|
||||
protected:
|
||||
void onAttachImpl() override;
|
||||
void onDetachImpl() override;
|
||||
|
||||
private:
|
||||
std::shared_ptr<engine::EventBus<NetworkEvents>> m_networkEventBus;
|
||||
engine::AssetManager& m_assetManager;
|
||||
std::unique_ptr<engine::GUITexture> backgroundImage;
|
||||
engine::renderer::GuiRenderer m_guiRenderer;
|
||||
|
||||
char m_hostBuffer[64] = "127.0.0.1";
|
||||
int m_port = 7777;
|
||||
bool m_connectionError = false;
|
||||
bool m_closeConnectPopup = false;
|
||||
std::string m_errorMessage;
|
||||
|
||||
void renderConnectDialog();
|
||||
};
|
||||
|
||||
|
||||
#endif //COLORRACE_MAINMENUUILAYER_H
|
||||
5
game/src/multiplayer/LudoGameClient.cpp
Normal file
5
game/src/multiplayer/LudoGameClient.cpp
Normal file
@ -0,0 +1,5 @@
|
||||
//
|
||||
// Created by sebastian on 06.08.26.
|
||||
//
|
||||
|
||||
#include "LudoGameClient.h"
|
||||
49
game/src/multiplayer/LudoGameClient.h
Normal file
49
game/src/multiplayer/LudoGameClient.h
Normal file
@ -0,0 +1,49 @@
|
||||
//
|
||||
// Created by sebastian on 06.08.26.
|
||||
//
|
||||
|
||||
#ifndef COLORRACE_LUDOGAMECLIENT_H
|
||||
#define COLORRACE_LUDOGAMECLIENT_H
|
||||
#include <iostream>
|
||||
|
||||
#include "LudoNetworkEvents.h"
|
||||
#include "../../../external/NetworkCore/src/client/ApplicationClient.h"
|
||||
#include "core/events/EventBus.h"
|
||||
#include "spdlog/spdlog.h"
|
||||
|
||||
|
||||
class LudoGameClient : public engine::net::ApplicationClient{
|
||||
public:
|
||||
explicit LudoGameClient(const engine::net::ClientConfig &config, std::shared_ptr<engine::EventBus<NetworkEvents>> networkEventBus)
|
||||
: ApplicationClient(config), m_networkEventBus(std::move(networkEventBus)) {
|
||||
}
|
||||
|
||||
protected:
|
||||
void onConnected() override {
|
||||
spdlog::info("LudoGameClient successfully connected to server");
|
||||
send({
|
||||
{"type", "auth"},
|
||||
{"payload", {
|
||||
{"token", getConfig().token}
|
||||
}}
|
||||
});
|
||||
}
|
||||
|
||||
void onDisconnected() override {
|
||||
std::cout << "Verbindung verloren, versuche Reconnect...\n";
|
||||
}
|
||||
|
||||
void onMessage(nlohmann::json message) override {
|
||||
if (message.value("type", "") == "auth_ack") {
|
||||
NetworkEvents connectResult = ConnectResult(true, "");
|
||||
m_networkEventBus->publish(connectResult);
|
||||
}
|
||||
std::cout << "Empfangen: " << message.dump() << "\n";
|
||||
}
|
||||
|
||||
private:
|
||||
std::shared_ptr<engine::EventBus<NetworkEvents>> m_networkEventBus;
|
||||
};
|
||||
|
||||
|
||||
#endif //COLORRACE_LUDOGAMECLIENT_H
|
||||
24
game/src/multiplayer/LudoNetworkEvents.h
Normal file
24
game/src/multiplayer/LudoNetworkEvents.h
Normal file
@ -0,0 +1,24 @@
|
||||
//
|
||||
// Created by sebastian on 06.08.26.
|
||||
//
|
||||
|
||||
#ifndef COLORRACE_LUDONETWORKEVENTS_H
|
||||
#define COLORRACE_LUDONETWORKEVENTS_H
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
#include <variant>
|
||||
#include <nlohmann/json_fwd.hpp>
|
||||
|
||||
|
||||
struct ConnectRequest {
|
||||
std::string host;
|
||||
uint16_t port;
|
||||
};
|
||||
|
||||
struct ConnectResult {
|
||||
bool success;
|
||||
std::string errorMessage;
|
||||
};
|
||||
|
||||
using NetworkEvents = std::variant<ConnectRequest, ConnectResult>;
|
||||
#endif //COLORRACE_LUDONETWORKEVENTS_H
|
||||
23
game/src/multiplayer/lobby/LobbyScene.cpp
Normal file
23
game/src/multiplayer/lobby/LobbyScene.cpp
Normal file
@ -0,0 +1,23 @@
|
||||
//
|
||||
// Created by sebastian on 06.08.26.
|
||||
//
|
||||
|
||||
#include "LobbyScene.h"
|
||||
|
||||
#include "LobbyUiLayer.h"
|
||||
|
||||
std::vector<engine::AssetRequest> LobbyScene::getRequiredAssets() const {
|
||||
std::vector<engine::AssetRequest> requests;
|
||||
requests.emplace_back(engine::TextureRequest("lobby_background", "assets/textures/multiplayer_lobby_background.png"));
|
||||
return requests;
|
||||
}
|
||||
|
||||
void LobbyScene::onEnter() {
|
||||
Scene::onEnter();
|
||||
|
||||
addLayer(std::make_unique<LobbyUiLayer>(m_keyboard, m_mouse, getAnimationEventBus(), m_applicationEventBus, *assetManager));
|
||||
}
|
||||
|
||||
void LobbyScene::onExit() {
|
||||
Scene::onExit();
|
||||
}
|
||||
23
game/src/multiplayer/lobby/LobbyScene.h
Normal file
23
game/src/multiplayer/lobby/LobbyScene.h
Normal file
@ -0,0 +1,23 @@
|
||||
//
|
||||
// Created by sebastian on 06.08.26.
|
||||
//
|
||||
|
||||
#ifndef COLORRACE_LOBBYSCENE_H
|
||||
#define COLORRACE_LOBBYSCENE_H
|
||||
#include "layer/Scene.h"
|
||||
|
||||
|
||||
class LobbyScene : public engine::Scene {
|
||||
public:
|
||||
LobbyScene(const std::shared_ptr<engine::EventBus<ApplicationEvents>> &applicationEventbus,
|
||||
engine::InputContextStack &inputStack, engine::Keyboard &keyboard, engine::Mouse &mouse)
|
||||
: Scene(applicationEventbus, inputStack, keyboard, mouse) {
|
||||
}
|
||||
|
||||
std::vector<engine::AssetRequest> getRequiredAssets() const override;
|
||||
void onEnter() override;
|
||||
void onExit() override;
|
||||
};
|
||||
|
||||
|
||||
#endif //COLORRACE_LOBBYSCENE_H
|
||||
30
game/src/multiplayer/lobby/LobbyUiLayer.cpp
Normal file
30
game/src/multiplayer/lobby/LobbyUiLayer.cpp
Normal file
@ -0,0 +1,30 @@
|
||||
//
|
||||
// Created by sebastian on 06.08.26.
|
||||
//
|
||||
|
||||
#include "LobbyUiLayer.h"
|
||||
|
||||
#include "spdlog/spdlog.h"
|
||||
|
||||
void LobbyUiLayer::onAttachImpl() {
|
||||
Layer::onAttachImpl();
|
||||
|
||||
auto backgroundTexture = m_assetManager.getTexture("lobby_background");
|
||||
|
||||
backgroundImage = std::make_unique<engine::GUITexture>(backgroundTexture, glm::vec2(0,0), glm::vec2(1,1));
|
||||
}
|
||||
|
||||
void LobbyUiLayer::onDetachImpl() {
|
||||
Layer::onDetachImpl();
|
||||
}
|
||||
|
||||
void LobbyUiLayer::onRender() {
|
||||
std::vector<engine::GUITexture> guiElements;
|
||||
guiElements.emplace_back(*backgroundImage);
|
||||
m_guiRenderer.render(guiElements);
|
||||
}
|
||||
|
||||
void LobbyUiLayer::onUpdate(float deltaTime) {
|
||||
Layer::onUpdate(deltaTime);
|
||||
|
||||
}
|
||||
40
game/src/multiplayer/lobby/LobbyUiLayer.h
Normal file
40
game/src/multiplayer/lobby/LobbyUiLayer.h
Normal file
@ -0,0 +1,40 @@
|
||||
//
|
||||
// Created by sebastian on 06.08.26.
|
||||
//
|
||||
|
||||
#ifndef COLORRACE_LOBBYUILAYER_H
|
||||
#define COLORRACE_LOBBYUILAYER_H
|
||||
#include "layer/Layer.h"
|
||||
#include "loader/assets/AssetManager.h"
|
||||
#include "renderer/GuiRenderer.h"
|
||||
#include "renderer/ui/GUITexture.h"
|
||||
|
||||
|
||||
class LobbyUiLayer : public engine::Layer {
|
||||
public:
|
||||
LobbyUiLayer(engine::Keyboard &keyboard, engine::Mouse &mouse,
|
||||
engine::EventBus<engine::animation::AnimationMarkerEvent> &animationEventBus, engine::AssetManager& assetManager)
|
||||
: Layer(keyboard, mouse, animationEventBus), m_assetManager(assetManager) {
|
||||
}
|
||||
|
||||
LobbyUiLayer(engine::Keyboard &keyboard, engine::Mouse &mouse,
|
||||
engine::EventBus<engine::animation::AnimationMarkerEvent> &animationEventBus,
|
||||
const std::shared_ptr<engine::EventBus<ApplicationEvents>> &applicationEventBus, engine::AssetManager& assetManager)
|
||||
: Layer(keyboard, mouse, animationEventBus, applicationEventBus), m_assetManager(assetManager) {
|
||||
}
|
||||
|
||||
void onRender() override;
|
||||
void onUpdate(float deltaTime) override;
|
||||
|
||||
protected:
|
||||
void onAttachImpl() override;
|
||||
void onDetachImpl() override;
|
||||
|
||||
private:
|
||||
std::unique_ptr<engine::GUITexture> backgroundImage;
|
||||
engine::AssetManager& m_assetManager;
|
||||
engine::renderer::GuiRenderer m_guiRenderer;
|
||||
};
|
||||
|
||||
|
||||
#endif //COLORRACE_LOBBYUILAYER_H
|
||||
17
server/CMakeLists.txt
Normal file
17
server/CMakeLists.txt
Normal file
@ -0,0 +1,17 @@
|
||||
|
||||
|
||||
add_executable(ColorRaceServer
|
||||
src/main.cpp
|
||||
src/LudoGameServer.cpp
|
||||
src/LudoGameServer.h
|
||||
)
|
||||
|
||||
target_include_directories(ColorRaceServer PRIVATE
|
||||
src
|
||||
)
|
||||
|
||||
target_link_libraries(ColorRaceServer PRIVATE
|
||||
NetworkCore
|
||||
)
|
||||
|
||||
target_compile_features(ColorRaceServer PRIVATE cxx_std_20) # an deinen tatsächlichen Standard anpassen
|
||||
26
server/src/LudoGameServer.cpp
Normal file
26
server/src/LudoGameServer.cpp
Normal file
@ -0,0 +1,26 @@
|
||||
//
|
||||
// Created by sebastian on 06.08.26.
|
||||
//
|
||||
|
||||
#include "LudoGameServer.h"
|
||||
|
||||
#include "spdlog/spdlog.h"
|
||||
|
||||
void LudoGameServer::onStart() {
|
||||
ApplicationServer::onStart();
|
||||
m_gameServer.onClientConnected([](engine::net::ClientId clientId) {
|
||||
spdlog::info("Client connected: {}", clientId);
|
||||
});
|
||||
|
||||
m_gameServer.onMessageReceived([this](engine::net::ClientId clientId, const nlohmann::json& msg) {
|
||||
spdlog::info("Client {}: {}", clientId, msg.dump());
|
||||
if (msg.value("type", "") == "Ping") {
|
||||
m_gameServer.sendTo(clientId, { {"type", "Pong"}, {"payload", nlohmann::json::object()} });
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void LudoGameServer::onTick(float deltaTime) {
|
||||
ApplicationServer::onTick(deltaTime);
|
||||
m_gameServer.update();
|
||||
}
|
||||
22
server/src/LudoGameServer.h
Normal file
22
server/src/LudoGameServer.h
Normal file
@ -0,0 +1,22 @@
|
||||
//
|
||||
// Created by sebastian on 06.08.26.
|
||||
//
|
||||
|
||||
#ifndef COLORRACE_LUDOGAMESERVER_H
|
||||
#define COLORRACE_LUDOGAMESERVER_H
|
||||
#include "../../external/NetworkCore/src/server/ApplicationServer.h"
|
||||
#include "../../external/NetworkCore/src/server/GameServer.h"
|
||||
|
||||
|
||||
class LudoGameServer : public engine::net::ApplicationServer {
|
||||
public:
|
||||
explicit LudoGameServer(const uint16_t port, engine::net::ServerConfig& serverConfig) : m_gameServer(port, serverConfig) {};
|
||||
protected:
|
||||
void onStart() override;
|
||||
void onTick(float deltaTime) override;
|
||||
private:
|
||||
engine::net::GameServer m_gameServer;
|
||||
};
|
||||
|
||||
|
||||
#endif //COLORRACE_LUDOGAMESERVER_H
|
||||
13
server/src/main.cpp
Normal file
13
server/src/main.cpp
Normal file
@ -0,0 +1,13 @@
|
||||
#include <iostream>
|
||||
#include <ostream>
|
||||
|
||||
#include "LudoGameServer.h"
|
||||
//
|
||||
// Created by sebastian on 06.08.26.
|
||||
//
|
||||
int main() {
|
||||
engine::net::ServerConfig config = engine::net::ServerConfig();
|
||||
LudoGameServer server = LudoGameServer(4242, config);
|
||||
server.run();
|
||||
return 0;
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user