From b59a10b7e6114bf839b47d59ad542aa81df0aec2 Mon Sep 17 00:00:00 2001 From: Vladislav Khorev Date: Sun, 22 Feb 2026 19:50:13 +0300 Subject: [PATCH] Major refactoring for game menu --- proj-windows/CMakeLists.txt | 2 +- resources/config/main_menu.json | 17 ++++- src/Game.cpp | 129 ++++++++++++++++++++++++-------- src/Game.h | 3 + src/MenuManager.cpp | 16 ++-- src/MenuManager.h | 12 ++- src/Space.cpp | 50 +++---------- src/Space.h | 16 +--- 8 files changed, 142 insertions(+), 103 deletions(-) diff --git a/proj-windows/CMakeLists.txt b/proj-windows/CMakeLists.txt index 6210c4b..90e0f67 100644 --- a/proj-windows/CMakeLists.txt +++ b/proj-windows/CMakeLists.txt @@ -88,7 +88,7 @@ target_compile_definitions(space-game001 PRIVATE WIN32_LEAN_AND_MEAN PNG_ENABLED SDL_MAIN_HANDLED - #NETWORK + NETWORK # SIMPLIFIED ) diff --git a/resources/config/main_menu.json b/resources/config/main_menu.json index 9677e48..1807e74 100644 --- a/resources/config/main_menu.json +++ b/resources/config/main_menu.json @@ -96,11 +96,24 @@ }, { "type": "Button", - "name": "exitButton", + "name": "multiplayerButton2", "x": 409, "y": 218, "width": 382, "height": 56, + "textures": { + "normal": "resources/main_menu/multi.png", + "hover": "resources/main_menu/multi.png", + "pressed": "resources/main_menu/multi.png" + } + }, + { + "type": "Button", + "name": "exitButton", + "x": 409, + "y": 147, + "width": 382, + "height": 56, "textures": { "normal": "resources/main_menu/exit.png", "hover": "resources/main_menu/exit.png", @@ -111,7 +124,7 @@ "type": "Button", "name": "versionLabel", "x": 559.5, - "y": 170, + "y": 99, "width": 81, "height": 9, "textures": { diff --git a/src/Game.cpp b/src/Game.cpp index 743dc93..ceac9ca 100644 --- a/src/Game.cpp +++ b/src/Game.cpp @@ -21,10 +21,11 @@ #else #include "network/WebSocketClient.h" #endif -#else -#include "network/LocalClient.h" #endif +#include "network/LocalClient.h" + + namespace ZL { #ifdef EMSCRIPTEN @@ -34,12 +35,6 @@ namespace ZL const char* CONST_ZIP_FILE = ""; #endif - bool g_exitBgAnimating = false; - - bool firePressed = false; - - float x = 0; - Game::Game() : window(nullptr) , glContext(nullptr) @@ -88,21 +83,30 @@ namespace ZL #endif menuManager.setupMenu(); - renderer.InitOpenGL(); - space.setup(); + menuManager.onSingleplayerPressed = [this]() { + networkClient = std::make_unique(); + networkClient->Connect("", 0); + spaceGameStarted = 1; + }; + + + menuManager.onMultiplayerPressed = [this]() { #ifdef NETWORK #ifdef EMSCRIPTEN - networkClient = std::make_unique(); - networkClient->Connect("192.168.131.143", 8081); + networkClient = std::make_unique(); + networkClient->Connect("192.168.131.143", 8081); #else - networkClient = std::make_unique(taskManager.getIOContext()); - networkClient->Connect("127.0.0.1", 8081); + networkClient = std::make_unique(taskManager.getIOContext()); + networkClient->Connect("127.0.0.1", 8081); #endif -#else - networkClient = std::make_unique(); - networkClient->Connect("", 0); #endif + lastTickCount = 0; + spaceGameStarted = 1; + }; + + renderer.InitOpenGL(); + space.setup(); } @@ -131,9 +135,21 @@ namespace ZL CheckGlError(); } - void Game::drawScene() { + void Game::drawUnderMainMenu() + { + glClearColor(0.0f, 0.0f, 0.0f, 1.0f); + glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); - space.drawScene(); + } + + void Game::drawScene() { + if (spaceGameStarted) { + space.drawScene(); + } + else + { + drawUnderMainMenu(); + } drawUI(); CheckGlError(); } @@ -142,7 +158,14 @@ namespace ZL int64_t localNow = std::chrono::duration_cast( std::chrono::system_clock::now().time_since_epoch()).count(); // Добавляем смещение, полученное от сервера - return localNow + networkClient->getTimeOffset(); // Нужно добавить геттер в интерфейс + if (networkClient) + { + return localNow + networkClient->getTimeOffset(); + } + else + { + return localNow; + } } void Game::processTickCount() { @@ -167,8 +190,9 @@ namespace ZL //throw std::runtime_error("Synchronization is lost"); } - space.processTickCount(newTickCount, delta); - + if (spaceGameStarted) { + space.processTickCount(newTickCount, delta); + } menuManager.uiManager.update(static_cast(delta)); lastTickCount = newTickCount; } @@ -268,14 +292,8 @@ namespace ZL } if (event.type == SDL_KEYUP) { - if (event.key.keysym.sym == SDLK_i) { - x = x + 1; - } - if (event.key.keysym.sym == SDLK_k) { - x = x - 1; - } if (event.key.keysym.sym == SDLK_a) { - Environment::shipState.position = { 9466.15820, 1046.00159, 18531.2090 }; + //Environment::shipState.position = { 9466.15820, 1046.00159, 18531.2090 }; } } #endif @@ -293,22 +311,67 @@ namespace ZL } mainThreadHandler.processMainThreadTasks(); - space.update(); + if (spaceGameStarted) { + space.update(); + } } void Game::handleDown(int mx, int my) { - space.handleDown(mx, my); + int uiX = mx; + int uiY = Environment::height - my; + + menuManager.uiManager.onMouseDown(uiX, uiY); + + bool uiHandled = false; + + for (const auto& button : menuManager.uiManager.findButton("") ? std::vector>{} : std::vector>{}) { + (void)button; + } + + auto pressedSlider = [&]() -> std::shared_ptr { + for (const auto& slider : menuManager.uiManager.findSlider("") ? std::vector>{} : std::vector>{}) { + (void)slider; + } + return nullptr; + }(); + + if (!menuManager.uiManager.isUiInteraction()) { + if (spaceGameStarted) { + space.handleDown(mx, my); + } + } + } void Game::handleUp(int mx, int my) { - space.handleUp(mx, my); + int uiX = mx; + int uiY = Environment::height - my; + + menuManager.uiManager.onMouseUp(uiX, uiY); + + if (!menuManager.uiManager.isUiInteraction()) { + if (spaceGameStarted) { + space.handleUp(mx, my); + } + } + } void Game::handleMotion(int mx, int my) { - space.handleMotion(mx, my); + int uiX = mx; + int uiY = Environment::height - my; + + menuManager.uiManager.onMouseMove(uiX, uiY); + + if (!menuManager.uiManager.isUiInteraction()) { + if (spaceGameStarted) { + space.handleMotion(mx, my); + } + } + } diff --git a/src/Game.h b/src/Game.h index 057eb17..a37ef82 100644 --- a/src/Game.h +++ b/src/Game.h @@ -41,6 +41,7 @@ namespace ZL { void processTickCount(); void drawScene(); void drawUI(); + void drawUnderMainMenu(); void handleDown(int mx, int my); void handleUp(int mx, int my); void handleMotion(int mx, int my); @@ -56,6 +57,8 @@ namespace ZL { MenuManager menuManager; Space space; + + int spaceGameStarted = 0; }; diff --git a/src/MenuManager.cpp b/src/MenuManager.cpp index af0bcfd..e14bd56 100644 --- a/src/MenuManager.cpp +++ b/src/MenuManager.cpp @@ -55,7 +55,7 @@ namespace ZL { } }); - uiManager.setAnimationCallback("exitButton", "bgScroll", []() { + uiManager.setAnimationCallback("exitButton", "bgScroll", [this]() { std::cerr << "Exit button bgScroll animation finished" << std::endl; g_exitBgAnimating = false; }); @@ -96,10 +96,10 @@ namespace ZL { }); uiManager.setButtonCallback("shootButton", [this](const std::string& name) { - firePressed = true; + onFirePressed(); }); uiManager.setButtonCallback("shootButton2", [this](const std::string& name) { - firePressed = true; + onFirePressed(); }); uiManager.setSliderCallback("velocitySlider", [this](const std::string& name, float value) { int newVel = roundf(value * 10); @@ -114,16 +114,18 @@ namespace ZL { }); }; - uiManager.setButtonCallback("singleButton", [loadGameplayUI](const std::string& name) { + uiManager.setButtonCallback("singleButton", [loadGameplayUI, this](const std::string& name) { std::cerr << "Single button pressed: " << name << " -> load gameplay UI\n"; loadGameplayUI(); + onSingleplayerPressed(); }); - /*uiManager.setButtonCallback("multiplayerButton", [loadGameplayUI](const std::string& name) { + uiManager.setButtonCallback("multiplayerButton", [loadGameplayUI, this](const std::string& name) { std::cerr << "Multiplayer button pressed: " << name << " -> load gameplay UI\n"; loadGameplayUI(); - });*/ + onMultiplayerPressed(); + }); - uiManager.setButtonCallback("multiplayerButton", [this](const std::string& name) { + uiManager.setButtonCallback("multiplayerButton2", [this](const std::string& name) { std::cerr << "Multiplayer button pressed → opening multiplayer menu\n"; uiManager.startAnimationOnNode("playButton", "buttonsExit"); diff --git a/src/MenuManager.h b/src/MenuManager.h index 9ec0296..7ad6d87 100644 --- a/src/MenuManager.h +++ b/src/MenuManager.h @@ -7,21 +7,21 @@ namespace ZL { extern const char* CONST_ZIP_FILE; - extern bool g_exitBgAnimating; - extern bool firePressed; + //extern bool g_exitBgAnimating; class MenuManager { protected: Renderer& renderer; - bool uiGameOverShown = false; - std::shared_ptr uiSavedRoot; std::shared_ptr gameOverSavedRoot; std::shared_ptr settingsSavedRoot; std::shared_ptr multiplayerSavedRoot; public: + bool uiGameOverShown = false; + bool g_exitBgAnimating = false; + UiManager uiManager; MenuManager(Renderer& iRenderer); @@ -32,6 +32,10 @@ namespace ZL { std::function onRestartPressed; std::function onVelocityChanged; + std::function onFirePressed; + + std::function onSingleplayerPressed; + std::function onMultiplayerPressed; }; }; diff --git a/src/Space.cpp b/src/Space.cpp index 073b1d5..f69e7d0 100644 --- a/src/Space.cpp +++ b/src/Space.cpp @@ -30,10 +30,6 @@ namespace ZL extern const char* CONST_ZIP_FILE; - extern bool g_exitBgAnimating; - - extern bool firePressed; - extern float x; Eigen::Quaternionf generateRandomQuaternion(std::mt19937& gen) @@ -145,7 +141,7 @@ namespace ZL return P; } - bool Space::worldToScreen(const Vector3f& world, float& outX, float& outY, float& outDepth) const + bool worldToScreen(const Vector3f& world, float& outX, float& outY, float& outDepth) { // Матрицы должны совпасть с drawBoxes/drawShip по смыслу float aspect = static_cast(Environment::width) / static_cast(Environment::height); @@ -176,7 +172,7 @@ namespace ZL return true; } - bool Space::projectToNDC(const Vector3f& world, float& ndcX, float& ndcY, float& ndcZ, float& clipW) const + bool projectToNDC(const Vector3f& world, float& ndcX, float& ndcY, float& ndcZ, float& clipW) { float aspect = static_cast(Environment::width) / static_cast(Environment::height); Eigen::Matrix4f V = makeViewMatrix_FromYourCamera(); @@ -278,6 +274,10 @@ namespace ZL newShipVelocity = newVelocity; }; + menuManager.onFirePressed = [this]() { + firePressed = true; + }; + bool cfgLoaded = sparkEmitter.loadFromJsonFile("resources/config/spark_config.json", renderer, CONST_ZIP_FILE); bool projCfgLoaded = projectileEmitter.loadFromJsonFile("resources/config/spark_projectile_config.json", renderer, CONST_ZIP_FILE); bool explosionCfgLoaded = explosionEmitter.loadFromJsonFile("resources/config/explosion_config.json", renderer, CONST_ZIP_FILE); @@ -566,7 +566,6 @@ namespace ZL drawBoxesLabels(); drawShip(); - //drawUI(); drawTargetHud(); CheckGlError(); } @@ -1394,25 +1393,6 @@ namespace ZL void Space::handleDown(int mx, int my) { - int uiX = mx; - int uiY = Environment::height - my; - - menuManager.uiManager.onMouseDown(uiX, uiY); - - bool uiHandled = false; - - for (const auto& button : menuManager.uiManager.findButton("") ? std::vector>{} : std::vector>{}) { - (void)button; - } - - auto pressedSlider = [&]() -> std::shared_ptr { - for (const auto& slider : menuManager.uiManager.findSlider("") ? std::vector>{} : std::vector>{}) { - (void)slider; - } - return nullptr; - }(); - - if (!menuManager.uiManager.isUiInteraction()) { Environment::tapDownHold = true; Environment::tapDownStartPos(0) = mx; @@ -1420,29 +1400,17 @@ namespace ZL Environment::tapDownCurrentPos(0) = mx; Environment::tapDownCurrentPos(1) = my; - } } void Space::handleUp(int mx, int my) { - int uiX = mx; - int uiY = Environment::height - my; - - menuManager.uiManager.onMouseUp(uiX, uiY); - - if (!menuManager.uiManager.isUiInteraction()) { - Environment::tapDownHold = false; - } + Environment::tapDownHold = false; + } void Space::handleMotion(int mx, int my) { - int uiX = mx; - int uiY = Environment::height - my; - - menuManager.uiManager.onMouseMove(uiX, uiY); - - if (Environment::tapDownHold && !menuManager.uiManager.isUiInteraction()) { + if (Environment::tapDownHold) { Environment::tapDownCurrentPos(0) = mx; Environment::tapDownCurrentPos(1) = my; } diff --git a/src/Space.h b/src/Space.h index 993d3e4..b1f8fed 100644 --- a/src/Space.h +++ b/src/Space.h @@ -36,8 +36,6 @@ namespace ZL { void setup(); void update(); - bool shouldExit() const { return Environment::exitGameLoop; } - Renderer& renderer; TaskManager& taskManager; MainThreadHandler& mainThreadHandler; @@ -52,24 +50,14 @@ namespace ZL { void drawShip(); void drawBoxes(); void drawBoxesLabels(); - //void drawUI(); void drawRemoteShips(); void drawRemoteShipsLabels(); void fireProjectiles(); - bool worldToScreen(const Vector3f& world, float& outX, float& outY, float& outDepth) const; - void handleDown(int mx, int my); void handleUp(int mx, int my); void handleMotion(int mx, int my); - //SDL_Window* window; - //SDL_GLContext glContext; - - - - //int64_t newTickCount; - //int64_t lastTickCount; std::vector boxCoordsArr; std::vector boxRenderArr; @@ -101,8 +89,6 @@ namespace ZL { SparkEmitter explosionEmitter; PlanetObject planetObject; - //MenuManager menuManager; - std::vector> projectiles; std::shared_ptr projectileTexture; float projectileCooldownMs = 500.0f; @@ -113,6 +99,7 @@ namespace ZL { bool shipAlive = true; bool gameOver = false; + bool firePressed = false; std::vector boxAlive; float shipCollisionRadius = 15.0f; float boxCollisionRadius = 2.0f; @@ -142,7 +129,6 @@ namespace ZL { VertexRenderStruct hudTempMesh; // helpers - bool projectToNDC(const Vector3f& world, float& ndcX, float& ndcY, float& ndcZ, float& clipW) const; void drawTargetHud(); // рисует рамку или стрелку int pickTargetId() const; // выбирает цель (пока: ближайший живой удаленный игрок)