mirror of
https://github.com/zhenyan121/SporeBG-Conid.git
synced 2026-04-10 06:14:08 +08:00
feat: add online functionality
This commit is contained in:
@@ -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<GameUIManager>(
|
||||
std::unique_ptr<GameUIManager> GameScene::createUIManager() {
|
||||
// 默认创建普通的GameUIManager
|
||||
return std::make_unique<GameUIManager>(
|
||||
[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<BoardRenderer>(WIDTH, HEIGHT, renderer);
|
||||
m_gameSession = std::make_unique<GameSession>();
|
||||
m_CoordinateConverter = std::make_unique<CoordinateConverter>(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!");
|
||||
}
|
||||
|
||||
@@ -22,11 +22,19 @@ public:
|
||||
|
||||
void restartGame();
|
||||
protected:
|
||||
|
||||
// 创建UIManager的工厂方法,子类可以重写
|
||||
virtual std::unique_ptr<GameUIManager> createUIManager();
|
||||
|
||||
// // 点击处理的钩子方法
|
||||
virtual bool preHandleClick(int logicalX, int logicalY);
|
||||
virtual void postHandleClick();
|
||||
|
||||
virtual void handleBoardClick(int row, int col);
|
||||
|
||||
// 公共成员,子类可以直接访问
|
||||
std::unique_ptr<BoardRenderer> m_boardRenderer;
|
||||
std::unique_ptr<CoordinateConverter> m_CoordinateConverter;
|
||||
std::unique_ptr<GameSession> m_gameSession;
|
||||
private:
|
||||
std::unique_ptr<GameUIManager> m_gameUIManager;
|
||||
|
||||
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
#include "OnlineGameScene.h"
|
||||
#include "core/GameApplication.h"
|
||||
#include <iostream>
|
||||
void OnlineGameScene::onEnter(SDL_Renderer* renderer, int WIDTH, int HEIGHT, UIRenderer* uiRenderer) {
|
||||
m_renderer = renderer;
|
||||
m_uiRenderer = uiRenderer;
|
||||
m_gameUIManager = std::make_unique<OnlineGameUIManager>(
|
||||
|
||||
std::unique_ptr<GameUIManager> OnlineGameScene::createUIManager() {
|
||||
auto onlineUIManager = std::make_unique<OnlineGameUIManager>(
|
||||
[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<NetworkManager>();
|
||||
|
||||
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<BoardRenderer>(WIDTH, HEIGHT, renderer);
|
||||
m_gameSession = std::make_unique<GameSession>();
|
||||
m_CoordinateConverter = std::make_unique<CoordinateConverter>(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<NetworkManager>();
|
||||
m_networkManager->setClickEventCallback(
|
||||
[this](int logicalX, int logicalY) {
|
||||
this->handleNetworkClick(logicalX, logicalY);
|
||||
}
|
||||
);
|
||||
m_networkManager->setStartGameCallback(
|
||||
[this]() {
|
||||
auto onlineUIManager = dynamic_cast<OnlineGameUIManager*>(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);
|
||||
}
|
||||
}
|
||||
@@ -14,9 +14,15 @@ public:
|
||||
void handleNetworkClick(int logicalX, int logicalY);
|
||||
|
||||
void renderUI() override;
|
||||
protected:
|
||||
std::unique_ptr<GameUIManager> 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<NetworkManager> m_networkManager;
|
||||
std::unique_ptr<OnlineGameUIManager> m_gameUIManager;
|
||||
GameState m_currentGameState = GameState::GAME_PREGAME;
|
||||
};
|
||||
Reference in New Issue
Block a user