diff --git a/src/game/GameTypes.h b/src/game/GameTypes.h index 6c39510..672676b 100644 --- a/src/game/GameTypes.h +++ b/src/game/GameTypes.h @@ -18,6 +18,7 @@ enum class GameState { GAME_RUNING, // 游戏进行中 GAME_LOSE, // 游戏失败 GAME_WIN, // 游戏胜利 + GAME_PREGAME // 游戏未开始 }; enum class GameMode { diff --git a/src/graphics/font/TextRenderer.cpp b/src/graphics/font/TextRenderer.cpp index cc63ebc..6c34b35 100644 --- a/src/graphics/font/TextRenderer.cpp +++ b/src/graphics/font/TextRenderer.cpp @@ -247,10 +247,10 @@ void TextRenderer::autoCleanCache(size_t keepKey) { // 计算需要删除的数量 size_t itemsToRemove = m_cache.size() - MIN_CACHE_SIZE; - + /* SDL_Log("缓存清理:删除 %zu / %zu 条目(当前缓存大小:%zu)\n", itemsToRemove, m_cache.size(), m_cache.size()); - + */ // 删除最旧的缓存项 for (size_t i = 0; i < itemsToRemove && i < cacheItems.size(); ++i) { @@ -262,5 +262,5 @@ void TextRenderer::autoCleanCache(size_t keepKey) { } } - SDL_Log("缓存清理完成,当前缓存大小:%zu\n", m_cache.size()); + //SDL_Log("缓存清理完成,当前缓存大小:%zu\n", m_cache.size()); } \ No newline at end of file diff --git a/src/network/NetData.h b/src/network/NetData.h index 5c5d570..e9663f5 100644 --- a/src/network/NetData.h +++ b/src/network/NetData.h @@ -1,19 +1,34 @@ #pragma once #include + +enum class NetDataType { + CLICK_POSITION, + GAME_START +}; + struct NetData { std::pair clickPosition = {0, 0}; + int firstPlayer = 1; + NetDataType type = NetDataType::CLICK_POSITION; // 序列化,转换成字节数组 void serialize(char* buffer) const { // 暴力转换 int* ptr = reinterpret_cast(buffer); - ptr[0] = clickPosition.first; - ptr[1] = clickPosition.second; + + ptr[0] = static_cast(type); + ptr[1] = clickPosition.first; + ptr[2] = clickPosition.second; + ptr[3] = firstPlayer; } // 反序列化,从字节数组恢复 static NetData deserialize(const char* buffer) { // 暴力转换 const int* ptr = reinterpret_cast(buffer); - return NetData{{ptr[0], ptr[1]}}; + NetData data; + data.type = static_cast(ptr[0]); + data.clickPosition = {ptr[1], ptr[2]}; + data.firstPlayer = ptr[3]; + return data; } // 大小(固定16字节:4个int) static constexpr size_t size() { return 4 * sizeof(int); } diff --git a/src/network/NetworkManager.cpp b/src/network/NetworkManager.cpp index 15adea3..664d043 100644 --- a/src/network/NetworkManager.cpp +++ b/src/network/NetworkManager.cpp @@ -29,6 +29,10 @@ void NetworkManager::init(NetType type) { std::cout << "client started\n"; } +void NetworkManager::setClickEventCallback(ClickEventCallback callback) { + m_clickEventCallback = callback; +} + /* void NetworkManager::init(NetType type) { // 先启动 io_context 线程 @@ -68,12 +72,23 @@ void NetworkManager::startServer() { void NetworkManager::startClient() { m_client->setCallbackes( - [](const NetData& click) { + [this](const NetData& click) { /* 处理对手棋步 */ + if (m_clickEventCallback) { + std::cout << "Received opponent move: (" + << click.clickPosition.first << ", " + << click.clickPosition.second << ")\n"; + m_clickEventCallback(click.clickPosition.first, click.clickPosition.second); + } }, []() { /* 提示用户走棋 */ - std::cout << "It's your turn now!\n"; + std::cout << "NetworkManager:It's your turn now!\n"; + }, + [this]() { + /* 游戏开始回调 */ + m_startGameCallback(); + std::cout << "Game has started!\n"; } ); if (m_netType == NetType::HOST) { @@ -100,4 +115,24 @@ void NetworkManager::startIOContextLoop() { }); std::cout << "IO context loop started on thread: " << m_ioThread.joinable() << std::endl; +} + +void NetworkManager::postClickPosition(int logicalX, int logicalY, bool isChangeTurn) { + if (m_client) { + NetData data; + data.clickPosition = {logicalX, logicalY}; + // 发送位置并告诉对手是否换回合 + m_client->sentClickPosition(data, isChangeTurn); + std::cout << "Posted click position: (" + << logicalX << ", " << logicalY << ")\n"; + } +} + +void NetworkManager::setIsMyTurn(bool isMyTurn) { + m_isMyTurn = isMyTurn; + if (m_client) { + // 如果不是我的回合,则客户端应该等待对手 + m_client->setShouldWait(!isMyTurn); + } + } \ No newline at end of file diff --git a/src/network/NetworkManager.h b/src/network/NetworkManager.h index a4ee18e..22d0827 100644 --- a/src/network/NetworkManager.h +++ b/src/network/NetworkManager.h @@ -5,6 +5,8 @@ class NetworkManager { public: + using ClickEventCallback = std::function; + using StartGameCallback = std::function; NetworkManager(); @@ -13,7 +15,15 @@ public: void init(NetType type); + void setClickEventCallback(ClickEventCallback callback); + void setStartGameCallback(StartGameCallback callback) { + m_startGameCallback = callback; + } + + void setIsMyTurn(bool isMyTurn); + bool isMyTurn() const { return m_isMyTurn; } + void postClickPosition(int logicalX, int logicalY, bool isChangeTurn = false); private: // 一定要在最前面 @@ -28,7 +38,10 @@ private: asio::io_context::executor_type> m_workguard; std::thread m_ioThread; - + ClickEventCallback m_clickEventCallback; + StartGameCallback m_startGameCallback; + + bool m_isMyTurn = false; // 新增:当前是否是我的回合 void startServer(); void startClient(); diff --git a/src/network/client/Client.cpp b/src/network/client/Client.cpp index d55cf77..c2313d6 100644 --- a/src/network/client/Client.cpp +++ b/src/network/client/Client.cpp @@ -7,14 +7,22 @@ Client::Client(asio::io_context& ioContext): // 构造函数实现 } -void Client::setCallbackes(MoveCallback onOpponentMove, TurnCallback onMyTurn) { +void Client::setCallbackes(MoveCallback onOpponentMove, TurnCallback onMyTurn, TurnCallback onGameStart) { m_onOpponentMove = onOpponentMove; m_onMyTurn = onMyTurn; + m_onGameStart = onGameStart; +} + +void Client::stopWaiting() { + m_shouldWait = false; + m_isWaiting = false; } void Client::connect(const std::string& host, int port, bool iAmFirst) { m_host = host; m_port = port; + m_isHost = iAmFirst; + m_shouldWait = true; // 连接后开始等待 //用shared_ptr保持对象存活 auto self = shared_from_this(); @@ -40,28 +48,41 @@ void Client::connect(const std::string& host, int port, bool iAmFirst) { void Client::onConnected(bool iAmFirst) { std::cout << "Connected to server " << m_host << ":" << m_port << std::endl; - - // 如果是先手,触发回调 - if (iAmFirst && m_onMyTurn) { - m_onMyTurn(); - } else { - // 等待对手动作 + // 重置等待状态 + m_shouldWait = true; + m_isWaiting = false; + // 开始等待对手消息 + if (m_shouldWait) { waitForOpponent(); } + } // 发送点击位置数据给对手 -void Client::sentClickPosition(const NetData& data) { +void Client::sentClickPosition(const NetData& data, bool isChangeTurn) { auto self = shared_from_this(); + + NetData sendData = data; + sendData.type = NetDataType::CLICK_POSITION; + + char buffer[NetData::size()]; - data.serialize(buffer); + sendData.serialize(buffer); asio::async_write(m_socket, asio::buffer(buffer, NetData::size()), - [this, self](const asio::error_code& ec, std::size_t /*bytesTransferred*/) { + [this, self, isChangeTurn](const asio::error_code& ec, std::size_t /*bytesTransferred*/) { if (!ec) { - // 发送成功,等待对手动作 - waitForOpponent(); + // 如果需要转换回合,则开始等待对手 + if (isChangeTurn) { + m_isMyTurn = false; + m_shouldWait = true; + if (!m_isWaiting) { + waitForOpponent(); + } + } else { + m_isMyTurn = true; + } } else { std::cerr << "send failed: " << ec.message() << std::endl; } @@ -69,6 +90,9 @@ void Client::sentClickPosition(const NetData& data) { } void Client::waitForOpponent() { + if (!m_shouldWait || m_isWaiting) { + return; + } auto self = shared_from_this(); m_socket.async_read_some( asio::buffer(m_readBuffer, NetData::size()), @@ -77,21 +101,69 @@ void Client::waitForOpponent() { if (bytesTransferred == NetData::size()) { NetData netData = NetData::deserialize(m_readBuffer); - // 触发对手移动回调 - if (m_onOpponentMove) { - m_onOpponentMove(netData); + + // 检查消息类型 + if (netData.type == NetDataType::GAME_START) { + std::cout << "Game started! First player is: " << netData.firstPlayer << std::endl; + + // 判断自己是否是先手 + bool iAmFirst = (netData.firstPlayer == 1 && m_isHost) || + (netData.firstPlayer == 2 && !m_isHost); + + m_isMyTurn = iAmFirst; + if (m_onGameStart) { + m_onGameStart(); + } + + if (m_isMyTurn && m_onMyTurn) { + std::cout << "It's your turn now! (You are first)\n"; + m_onMyTurn(); + } else if (!m_isMyTurn && m_onOpponentMove) { + // 如果不是先手,等待对手走棋 + std::cout << "Waiting for opponent to move...\n"; + // 可以在这里触发一个等待对手的回调,如果需要的话 + if (m_shouldWait) { + waitForOpponent(); + } + } } - // 轮到我了 - if (m_onMyTurn) { - m_onMyTurn(); + else if (netData.type == NetDataType::CLICK_POSITION) { + // 正常的对手移动 + if (m_onOpponentMove) { + std::cout << "Received opponent move: (" + << netData.clickPosition.first << ", " + << netData.clickPosition.second << ")\n"; + m_onOpponentMove(netData); + } + // 现在轮到我了 + //m_isMyTurn = true; + + + if (m_isMyTurn) { + m_shouldWait = false; + if (m_onMyTurn) { + m_onMyTurn(); + } + } else { + if (m_shouldWait) { + waitForOpponent(); + } + } } // 重置读取缓冲区以准备下一次读取 } else { std::cerr << "Incomplete data received from opponent." << std::endl; + if (m_shouldWait) { + waitForOpponent(); + } } } else { std::cerr << "read failed: " << ec.message() << std::endl; + // 发生错误时,可以选择重新等待对手 + if (m_shouldWait) { + waitForOpponent(); + } } } ); diff --git a/src/network/client/Client.h b/src/network/client/Client.h index 15d5da5..8c87749 100644 --- a/src/network/client/Client.h +++ b/src/network/client/Client.h @@ -15,12 +15,13 @@ public: Client(asio::io_context& ioContext); ~Client() = default; - - void setCallbackes(MoveCallback onOpponentMove, TurnCallback onMyTurn); + // 设置等待状态 + void setShouldWait(bool shouldWait) { m_shouldWait = shouldWait; } + void setCallbackes(MoveCallback onOpponentMove, TurnCallback onMyTurn, TurnCallback onGameStart); void connect(const std::string& host, int port, bool iAmFirst = true); - void sentClickPosition(const NetData& data); + void sentClickPosition(const NetData& data, bool isChangeTurn = false); @@ -30,13 +31,21 @@ private: asio::ip::tcp::socket m_socket; std::string m_host; int m_port; + bool m_isHost = false; MoveCallback m_onOpponentMove; TurnCallback m_onMyTurn; + TurnCallback m_onGameStart; char m_readBuffer[NetData::size()]; + // 新增状态控制 + bool m_shouldWait = false; // 是否应该等待对手 + bool m_isWaiting = false; // 当前是否正在等待 + bool m_isMyTurn = false; // 是否是我的回合 + void onConnected(bool iAmFirst); void waitForOpponent(); + void stopWaiting(); // 停止等待 }; \ No newline at end of file diff --git a/src/network/server/GameServer.cpp b/src/network/server/GameServer.cpp index 3005331..06b03cc 100644 --- a/src/network/server/GameServer.cpp +++ b/src/network/server/GameServer.cpp @@ -83,6 +83,37 @@ void GameServer::waitForPlayers(int playerNum) { void GameServer::startGame() { std::cout << "Gmae Start player1 is the first\n"; + NetData gameStartMsg; + gameStartMsg.type = NetDataType::GAME_START; + gameStartMsg.firstPlayer = 1; // 玩家1先手 + gameStartMsg.clickPosition = {-1, -1}; // 特殊值表示游戏开始 + + char buffer1[NetData::size()]; + char buffer2[NetData::size()]; + // player1 + gameStartMsg.serialize(buffer1); + //player2 + gameStartMsg.serialize(buffer2); + // 发送游戏开始消息给两个玩家 + asio::async_write(m_player1, asio::buffer(buffer1, NetData::size()), + [](const asio::error_code& ec, size_t) { + if (ec) { + std::cerr << "Failed to send start message to player1: " << ec.message() << std::endl; + } else { + std::cout << "Game start message sent to player1\n"; + } + }); + + asio::async_write(m_player2, asio::buffer(buffer2, NetData::size()), + [](const asio::error_code& ec, size_t) { + if (ec) { + std::cerr << "Failed to send start message to player2: " << ec.message() << std::endl; + } else { + std::cout << "Game start message sent to player2\n"; + } + }); + + forwardMoves(); } diff --git a/src/scenes/gameplay/GameScene.cpp b/src/scenes/gameplay/GameScene.cpp index e97271a..dbb83c8 100644 --- a/src/scenes/gameplay/GameScene.cpp +++ b/src/scenes/gameplay/GameScene.cpp @@ -8,10 +8,9 @@ GameScene::~GameScene() { } -void GameScene::onEnter(SDL_Renderer* renderer, int WIDTH, int HEIGHT, UIRenderer* uiRenderer){ - m_renderer = renderer; - m_uiRenderer = uiRenderer; - m_gameUIManager = std::make_unique( +std::unique_ptr GameScene::createUIManager() { + // 默认创建普通的GameUIManager + return std::make_unique( [this](const std::string& sceneName) { if (m_eventCallback) { SceneEvent event{SceneEventType::ChangeScene, sceneName}; @@ -19,10 +18,50 @@ void GameScene::onEnter(SDL_Renderer* renderer, int WIDTH, int HEIGHT, UIRendere } } ); +} + + +bool GameScene::preHandleClick(int logicalX, int logicalY) { + // 默认实现:先处理UI点击 + if (m_gameUIManager && m_gameUIManager->handleClick(logicalX, logicalY)) { + return true; // UI已处理点击 + } + + // 检查游戏状态 + if (m_gameSession->getGameState() != GameState::GAME_RUNING) { + SDL_Log("Game is not running, click ignored."); + return true; // 游戏未运行,不处理点击 + } + + return false; // 继续处理游戏点击 +} + +void GameScene::postHandleClick() { + + // 默认实现:更新UI和渲染器状态 + m_gameUIManager->updateActionType(m_gameSession->getCurrentActionType()); + m_boardRenderer->updateMovementRange(m_gameSession->getSelectedPiece(), m_gameSession->getCurrentActionType()); + m_gameUIManager->updateGameState(m_gameSession->getGameState()); + m_boardRenderer->setGameState(m_gameSession->getGameState()); +} + +void GameScene::handleBoardClick(int row, int col) { + // 处理棋盘点击逻辑 + m_gameSession->handleCoordinateInput(row, col); + m_gameSession->printBoard(); +} + +void GameScene::onEnter(SDL_Renderer* renderer, int WIDTH, int HEIGHT, UIRenderer* uiRenderer){ + m_renderer = renderer; + m_uiRenderer = uiRenderer; + + // 使用工厂方法创建UIManager + m_gameUIManager = createUIManager(); m_gameUIManager->init(); m_gameUIManager->setCallback([this]() { this->restartGame(); }); + m_boardRenderer = std::make_unique(WIDTH, HEIGHT, renderer); m_gameSession = std::make_unique(); m_CoordinateConverter = std::make_unique(renderer); @@ -56,7 +95,8 @@ void GameScene::renderUI() { } void GameScene::handleClick(int logicalX, int logicalY) { - if (m_gameUIManager && m_gameUIManager->handleClick(logicalX, logicalY)) { + // 1. 预处理(UI点击等) + if (preHandleClick(logicalX, logicalY)) { return; } @@ -67,16 +107,18 @@ void GameScene::handleClick(int logicalX, int logicalY) { auto click = m_CoordinateConverter->ScreenToBoard(logicalX, logicalY, m_boardRenderer->getBoardArea()); if (click) { auto [row, col] = click.value(); - m_gameSession->handleCoordinateInput(row, col); - m_gameSession->printBoard(); - SDL_Log("try to updateActionType\n"); + handleBoardClick(row, col); + + // 3. 后处理(更新UI状态等) + postHandleClick(); + /*SDL_Log("try to updateActionType\n"); m_gameUIManager->updateActionType( m_gameSession->getCurrentActionType()); SDL_Log("tyr to updateMovementRange\n"); m_boardRenderer->updateMovementRange(m_gameSession->getSelectedPiece(), m_gameSession->getCurrentActionType()); SDL_Log("tyr to updateGameState\n"); m_gameUIManager->updateGameState(m_gameSession->getGameState()); m_boardRenderer->setGameState(m_gameSession->getGameState()); - + */ } else { SDL_Log("invail cilck aera!"); } diff --git a/src/scenes/gameplay/GameScene.h b/src/scenes/gameplay/GameScene.h index 5cb9b9f..08abc14 100644 --- a/src/scenes/gameplay/GameScene.h +++ b/src/scenes/gameplay/GameScene.h @@ -22,11 +22,19 @@ public: void restartGame(); protected: - + // 创建UIManager的工厂方法,子类可以重写 + virtual std::unique_ptr createUIManager(); + + // // 点击处理的钩子方法 + virtual bool preHandleClick(int logicalX, int logicalY); + virtual void postHandleClick(); + + virtual void handleBoardClick(int row, int col); + + // 公共成员,子类可以直接访问 std::unique_ptr m_boardRenderer; std::unique_ptr m_CoordinateConverter; std::unique_ptr m_gameSession; -private: std::unique_ptr m_gameUIManager; diff --git a/src/scenes/gameplay/OnlineGameScene.cpp b/src/scenes/gameplay/OnlineGameScene.cpp index 42f5461..a0f7e1b 100644 --- a/src/scenes/gameplay/OnlineGameScene.cpp +++ b/src/scenes/gameplay/OnlineGameScene.cpp @@ -1,10 +1,9 @@ #include "OnlineGameScene.h" #include "core/GameApplication.h" #include -void OnlineGameScene::onEnter(SDL_Renderer* renderer, int WIDTH, int HEIGHT, UIRenderer* uiRenderer) { - m_renderer = renderer; - m_uiRenderer = uiRenderer; - m_gameUIManager = std::make_unique( + +std::unique_ptr OnlineGameScene::createUIManager() { + auto onlineUIManager = std::make_unique( [this](const std::string& sceneName) { if (m_eventCallback) { SceneEvent event{SceneEventType::ChangeScene, sceneName}; @@ -12,49 +11,122 @@ void OnlineGameScene::onEnter(SDL_Renderer* renderer, int WIDTH, int HEIGHT, UIR } } ); - m_networkManager = std::make_unique(); - - m_gameUIManager->init(); - m_gameUIManager->setCallback([this]() { - this->restartGame(); - }); - - m_gameUIManager->setOnlineTypeCallback( - [this](NetType type){ - //std::cout << "try to init networkmanager\n"; - if (!m_networkManager) { - std::cerr << "networkmanager is null\n"; - } - m_networkManager->init(type); - if (type == NetType::CLIENT) { - m_isMyTurn = false; - m_myPlayerID = PlayerID::P2; - } - if (type == NetType::HOST) { - m_isMyTurn = true; - m_myPlayerID = PlayerID::P1; + // 设置网络类型回调 + onlineUIManager->setOnlineTypeCallback( + [this](NetType type) { + if (m_networkManager) { + m_networkManager->init(type); + if (type == NetType::CLIENT) { + m_isMyTurn = false; + + m_myPlayerID = PlayerID::P2; + } else if (type == NetType::HOST) { + m_isMyTurn = true; + m_myPlayerID = PlayerID::P1; + } + m_networkManager->setIsMyTurn(m_isMyTurn); } } ); - m_boardRenderer = std::make_unique(WIDTH, HEIGHT, renderer); - m_gameSession = std::make_unique(); - m_CoordinateConverter = std::make_unique(renderer); - m_gameSession->initialize(); - - m_boardRenderer->setBoard(m_gameSession->getBoard()); - + return onlineUIManager; +} + +void OnlineGameScene::onEnter(SDL_Renderer* renderer, int WIDTH, int HEIGHT, UIRenderer* uiRenderer) { + // 先创建网络管理器 + m_networkManager = std::make_unique(); + m_networkManager->setClickEventCallback( + [this](int logicalX, int logicalY) { + this->handleNetworkClick(logicalX, logicalY); + } + ); + m_networkManager->setStartGameCallback( + [this]() { + auto onlineUIManager = dynamic_cast(m_gameUIManager.get()); + if (onlineUIManager) { + onlineUIManager->hideOnlineButtons(); + } + m_currentGameState = GameState::GAME_RUNING; + } + ); + // 调用父类的onEnter(会调用我们重写的createUIManager) + GameScene::onEnter(renderer, WIDTH, HEIGHT, uiRenderer); +} + +bool OnlineGameScene::preHandleClick(int logicalX, int logicalY) { + + // 1. 先调用父类的UI处理 + if (GameScene::preHandleClick(logicalX, logicalY)) { + return true; + } + // 2. 检查是否是自己的回合 + // 网络处理会使用这个函数来决定是否处理点击,但是因为不是自己的回合所以不会调用handleBoardClick,导致bug + /*if (!m_isMyTurn) { + std::cout << "It is not your turn\n"; + return true; // 不是自己的回合,阻止处理 + }*/ + + return false; // 继续处理点击 +} + +void OnlineGameScene::postHandleClick() { + // 调用父类的后处理 + GameScene::postHandleClick(); + + // 在线游戏特有的后处理 + if (m_gameSession->getCurrentPlayer() != m_myPlayerID) { + m_isMyTurn = false; + // 可以在这里发送网络消息给对手 + m_networkManager->setIsMyTurn(false); + } } +void OnlineGameScene::handleBoardClick(int row, int col) { + if (m_currentGameState != GameState::GAME_RUNING) { + std::cout << "Game is not running, board click ignored.\n"; + return; + } + // 调用父类的处理逻辑 + GameScene::handleBoardClick(row, col); +} + +void OnlineGameScene::handleClick(int logicalX, int logicalY) { + // 要阻止的是鼠标点击事件,但是网络事件可以处理 + if (m_currentGameState == GameState::GAME_RUNING && !m_isMyTurn) { + std::cout << "It is not your turn, click ignored.\n"; + return; // 不是自己的回合,忽略点击 + } + + // 重用父类的逻辑 + GameScene::handleClick(logicalX, logicalY); + if (m_currentGameState != GameState::GAME_RUNING) { + std::cout << "Game has not started yet, not sending click\n"; + return; // 游戏未开始不发送点击 + } + if (m_gameSession->getCurrentPlayer() != m_myPlayerID) { + m_isMyTurn = false; + m_networkManager->setIsMyTurn(false); + m_networkManager->postClickPosition(logicalX, logicalY, true); + } else { + m_networkManager->postClickPosition(logicalX, logicalY, false); + } + +} + void OnlineGameScene::renderWorld() { + if (m_currentGameState != GameState::GAME_RUNING) { + // 渲染遮罩或提示 + m_boardRenderer->renderBlackOverlay(); + return; + } GameScene::renderWorld(); } void OnlineGameScene::renderUI() { - m_uiRenderer->renderUI(m_gameUIManager->getUIRenderData()); + GameScene::renderUI(); } - +/* void OnlineGameScene::handleClick(int logicalX, int logicalY) { if (m_gameUIManager && m_gameUIManager->handleClick(logicalX, logicalY)) { return; @@ -70,13 +142,21 @@ void OnlineGameScene::handleClick(int logicalX, int logicalY) { m_isMyTurn = false; } } - +*/ void OnlineGameScene::handleNetworkClick(int logicalX, int logicalY) { + std::cout << "Handling network click at (" << logicalX << ", " << logicalY << ")\n"; + // 处理来自网络的点击 if (m_isMyTurn) { - return; + return; // 如果是自己的回合,忽略网络点击 } + // 调用父类的基础点击处理 GameScene::handleClick(logicalX, logicalY); + std::cout << "After handling network click, current player: " + << (m_gameSession->getCurrentPlayer() == PlayerID::P1 ? "P1" : "P2") << "\n"; + // 更新回合状态 if (m_gameSession->getCurrentPlayer() == m_myPlayerID) { + std::cout << "OnlineGameScene: It is now my turn.\n"; m_isMyTurn = true; + m_networkManager->setIsMyTurn(true); } } \ No newline at end of file diff --git a/src/scenes/gameplay/OnlineGameScene.h b/src/scenes/gameplay/OnlineGameScene.h index d900e43..2f0d6ab 100644 --- a/src/scenes/gameplay/OnlineGameScene.h +++ b/src/scenes/gameplay/OnlineGameScene.h @@ -14,9 +14,15 @@ public: void handleNetworkClick(int logicalX, int logicalY); void renderUI() override; +protected: + std::unique_ptr createUIManager() override; + bool preHandleClick(int logicalX, int logicalY) override; + void postHandleClick() override; + + void handleBoardClick(int row, int col) override; private: - PlayerID m_myPlayerID; - bool m_isMyTurn; + PlayerID m_myPlayerID = PlayerID::P1; + bool m_isMyTurn = true; std::unique_ptr m_networkManager; - std::unique_ptr m_gameUIManager; + GameState m_currentGameState = GameState::GAME_PREGAME; }; \ No newline at end of file diff --git a/src/ui/managers/OnlineGameUIManager.cpp b/src/ui/managers/OnlineGameUIManager.cpp index d1f611c..4300f04 100644 --- a/src/ui/managers/OnlineGameUIManager.cpp +++ b/src/ui/managers/OnlineGameUIManager.cpp @@ -49,3 +49,15 @@ void OnlineGameUIManager::setOnlineTypeCallback(OnlineTypeEvent onlineTypeEvent) m_onlineTypeEvent = onlineTypeEvent; } +void OnlineGameUIManager::hideOnlineButtons() { + auto hostIt = m_buttons.find(makeHash("OnlineHostButton")); + if (hostIt != m_buttons.end()) { + hostIt->second->setVisible(false); + hostIt->second->setEnabled(false); + } + auto joinIt = m_buttons.find(makeHash("OnlineJoinButton")); + if (joinIt != m_buttons.end()) { + joinIt->second->setVisible(false); + joinIt->second->setEnabled(false); + } +} diff --git a/src/ui/managers/OnlineGameUIManager.h b/src/ui/managers/OnlineGameUIManager.h index 0094f19..c101dc4 100644 --- a/src/ui/managers/OnlineGameUIManager.h +++ b/src/ui/managers/OnlineGameUIManager.h @@ -8,6 +8,9 @@ public: ~OnlineGameUIManager(); void init() override; void setOnlineTypeCallback(OnlineTypeEvent type); + + void hideOnlineButtons(); + private: OnlineTypeEvent m_onlineTypeEvent; }; \ No newline at end of file