From 41f370f2ee348038f3bccd942509c3f0ab3fd85d Mon Sep 17 00:00:00 2001 From: Vladislav Khorev Date: Fri, 6 Mar 2026 22:34:03 +0300 Subject: [PATCH] Minor fixing --- src/Game.cpp | 17 ++++++++++++ src/Game.h | 2 ++ src/MenuManager.cpp | 64 ++++++++++++++++++++++++++++++++++++++------- src/MenuManager.h | 12 +++++++++ 4 files changed, 86 insertions(+), 9 deletions(-) diff --git a/src/Game.cpp b/src/Game.cpp index abf01e1..63ad172 100644 --- a/src/Game.cpp +++ b/src/Game.cpp @@ -195,6 +195,7 @@ namespace ZL space.boxAlive.clear(); space.serverBoxesApplied = false; + connectingStartTicks = SDL_GetTicks(); lastTickCount = 0; }; @@ -470,6 +471,22 @@ namespace ZL } //#endif networkClient->Poll(); + + if (menuManager.getState() == GameState::Connecting) { + if (networkClient->IsConnected()) { + menuManager.notifyConnected(); + // Enable/disable shoot buttons based on ship type + if (Environment::shipState.shipType == 1) { + if (auto b = menuManager.uiManager.findButton("shootButton")) b->state = ButtonState::Disabled; + if (auto b = menuManager.uiManager.findButton("shootButton2")) b->state = ButtonState::Disabled; + } else { + if (auto b = menuManager.uiManager.findButton("shootButton")) b->state = ButtonState::Normal; + if (auto b = menuManager.uiManager.findButton("shootButton2")) b->state = ButtonState::Normal; + } + } else if (SDL_GetTicks() - connectingStartTicks > CONNECTING_TIMEOUT_MS) { + menuManager.notifyConnectionFailed(); + } + } #ifdef NETWORK auto* wsBase = dynamic_cast(networkClient.get()); if (wsBase) { diff --git a/src/Game.h b/src/Game.h index 123e963..083f007 100644 --- a/src/Game.h +++ b/src/Game.h @@ -65,6 +65,8 @@ namespace ZL { int64_t newTickCount; int64_t lastTickCount; + uint32_t connectingStartTicks = 0; + static constexpr uint32_t CONNECTING_TIMEOUT_MS = 10000; static const size_t CONST_TIMER_INTERVAL = 10; static const size_t CONST_MAX_TIME_INTERVAL = 1000; diff --git a/src/MenuManager.cpp b/src/MenuManager.cpp index 8d16e17..d56ce79 100644 --- a/src/MenuManager.cpp +++ b/src/MenuManager.cpp @@ -10,11 +10,13 @@ namespace ZL { void MenuManager::setupMenu() { - mainMenuRoot = loadUiFromFile("resources/config/main_menu.json", renderer, CONST_ZIP_FILE); - shipSelectionRoot = loadUiFromFile("resources/config/ship_selection_menu.json", renderer, CONST_ZIP_FILE); - gameplayRoot = loadUiFromFile("resources/config/ui.json", renderer, CONST_ZIP_FILE); - gameOverRoot = loadUiFromFile("resources/config/game_over.json", renderer, CONST_ZIP_FILE); - connectionLostRoot = loadUiFromFile("resources/config/connection_lost.json", renderer, CONST_ZIP_FILE); + mainMenuRoot = loadUiFromFile("resources/config/main_menu.json", renderer, CONST_ZIP_FILE); + shipSelectionRoot = loadUiFromFile("resources/config/ship_selection_menu.json", renderer, CONST_ZIP_FILE); + connectingRoot = loadUiFromFile("resources/config/connecting.json", renderer, CONST_ZIP_FILE); + connectionFailedRoot= loadUiFromFile("resources/config/connection_failed.json", renderer, CONST_ZIP_FILE); + gameplayRoot = loadUiFromFile("resources/config/ui.json", renderer, CONST_ZIP_FILE); + gameOverRoot = loadUiFromFile("resources/config/game_over.json", renderer, CONST_ZIP_FILE); + connectionLostRoot = loadUiFromFile("resources/config/connection_lost.json", renderer, CONST_ZIP_FILE); enterMainMenu(); } @@ -78,14 +80,18 @@ namespace ZL { uiManager.setButtonCallback("spaceshipButton", [this](const std::string&) { std::string nick = uiManager.getTextFieldValue("nicknameInput"); if (nick.empty()) nick = "Player"; - enterGameplay(); + pendingMultiNick = nick; + pendingMultiShipType = 0; + enterConnecting(); if (onMultiplayerPressed) onMultiplayerPressed(nick, 0); }); uiManager.setButtonCallback("cargoshipButton", [this](const std::string&) { std::string nick = uiManager.getTextFieldValue("nicknameInput"); if (nick.empty()) nick = "Player"; - enterGameplay(); + pendingMultiNick = nick; + pendingMultiShipType = 1; + enterConnecting(); if (onMultiplayerPressed) onMultiplayerPressed(nick, 1); }); @@ -94,6 +100,32 @@ namespace ZL { }); } + // ── State: Connecting ──────────────────────────────────────────────────── + + void MenuManager::enterConnecting() + { + state = GameState::Connecting; + uiManager.replaceRoot(connectingRoot); + // No interactive elements — just a static "Connecting..." image + } + + // ── State: ConnectionFailed ─────────────────────────────────────────────── + + void MenuManager::enterConnectionFailed() + { + state = GameState::ConnectionFailed; + uiManager.replaceRoot(connectionFailedRoot); + + uiManager.setButtonCallback("connectionFailedReconnectButton", [this](const std::string&) { + enterConnecting(); + if (onMultiplayerPressed) onMultiplayerPressed(pendingMultiNick, pendingMultiShipType); + }); + + uiManager.setButtonCallback("connectionFailedGoBack", [this](const std::string&) { + enterMainMenu(); + }); + } + // ── State: Gameplay ────────────────────────────────────────────────────── void MenuManager::enterGameplay() @@ -148,7 +180,7 @@ namespace ZL { enterGameplay(); }); uiManager.setButtonCallback("gameOverExitButton", [this](const std::string&) { - Environment::exitGameLoop = true; + enterMainMenu(); }); } @@ -163,12 +195,26 @@ namespace ZL { // TODO: reconnect logic }); uiManager.setButtonCallback("exitServerButton", [this](const std::string&) { - Environment::exitGameLoop = true; + enterMainMenu(); }); } // ── Public event API ────────────────────────────────────────────────────── + void MenuManager::notifyConnected() + { + if (state == GameState::Connecting) { + enterGameplay(); + } + } + + void MenuManager::notifyConnectionFailed() + { + if (state == GameState::Connecting) { + enterConnectionFailed(); + } + } + void MenuManager::showGameOver(int score) { if (state == GameState::Gameplay) { diff --git a/src/MenuManager.h b/src/MenuManager.h index 877226d..f254118 100644 --- a/src/MenuManager.h +++ b/src/MenuManager.h @@ -12,6 +12,8 @@ namespace ZL { MainMenu, ShipSelectionSingle, ShipSelectionMulti, + Connecting, + ConnectionFailed, Gameplay, GameOver, ConnectionLost @@ -24,16 +26,24 @@ namespace ZL { // Pre-loaded UI roots (loaded once in setupMenu) std::shared_ptr mainMenuRoot; std::shared_ptr shipSelectionRoot; + std::shared_ptr connectingRoot; + std::shared_ptr connectionFailedRoot; std::shared_ptr gameplayRoot; std::shared_ptr gameOverRoot; std::shared_ptr connectionLostRoot; + // Stored for multiplayer retry + std::string pendingMultiNick; + int pendingMultiShipType = 0; + GameState state = GameState::MainMenu; // State transition methods void enterMainMenu(); void enterShipSelectionSingle(); void enterShipSelectionMulti(); + void enterConnecting(); + void enterConnectionFailed(); void enterGameplay(); void enterGameOver(int score); void enterConnectionLost(); @@ -52,6 +62,8 @@ namespace ZL { // Called by game events void showGameOver(int score); void showConnectionLost(); + void notifyConnected(); + void notifyConnectionFailed(); // Callbacks set by Game/Space std::function onRestartPressed;