diff --git a/src/game/GameSession.cpp b/src/game/GameSession.cpp index cbffe80..b50b9c9 100644 --- a/src/game/GameSession.cpp +++ b/src/game/GameSession.cpp @@ -62,7 +62,7 @@ bool GameSession::executeAction(int toRow, int toCol) { if (m_currentActionType == ActionType::GROW) { if (Rule::canGrow(m_board.get(), fromRow, fromCol, toRow, toCol, m_currentPlayer)) { m_board->placePieceAt(toRow, toCol, m_currentPlayer); - m_gamePieceEventCallback(GamePieceEvent::PLACE_PIECE, toRow, toCol); + m_gamePieceEventCallback(GamePieceEvent::PLACE_PIECE, toRow, toCol, -1, -1); // 如果执行了操作就擦除 markComponentAsUsed(getOldComponentID(fromRow, fromCol)); return true; @@ -71,11 +71,12 @@ bool GameSession::executeAction(int toRow, int toCol) { if (m_currentActionType == ActionType::MOVE) { if (Rule::canMove(m_board.get(), fromRow, fromCol, toRow, toCol, m_currentPlayer)) { m_board->removePieceAt(fromRow, fromCol); - m_gamePieceEventCallback(GamePieceEvent::REMOVE_PIECE, fromRow, fromCol); + m_gamePieceEventCallback(GamePieceEvent::REMOVE_PIECE, fromRow, fromCol, -1, -1); m_board->removePieceAt(toRow, toCol); - m_gamePieceEventCallback(GamePieceEvent::REMOVE_PIECE, toRow, toCol); + m_gamePieceEventCallback(GamePieceEvent::REMOVE_PIECE, toRow, toCol, -1, -1); m_board->placePieceAt(toRow, toCol, m_currentPlayer); - + + m_gamePieceEventCallback(GamePieceEvent::MOVE_PIECE, fromRow, fromCol, toRow, toCol); markComponentAsUsed(getOldComponentID(fromRow, fromCol)); return true; } @@ -83,9 +84,9 @@ bool GameSession::executeAction(int toRow, int toCol) { if (m_currentActionType == ActionType::SPORE) { if (Rule::canSpore(m_board.get(), fromRow, fromCol, toRow, toCol, m_currentPlayer)) { m_board->removePieceAt(fromRow, fromCol); - m_gamePieceEventCallback(GamePieceEvent::REMOVE_PIECE, fromRow, fromCol); + m_gamePieceEventCallback(GamePieceEvent::REMOVE_PIECE, fromRow, fromCol, -1, -1); m_board->placePieceAt(toRow, toCol, m_currentPlayer); - m_gamePieceEventCallback(GamePieceEvent::PLACE_PIECE, toRow, toCol); + m_gamePieceEventCallback(GamePieceEvent::PLACE_PIECE, toRow, toCol, -1, -1); markComponentAsUsed(getOldComponentID(fromRow, fromCol)); return true; } diff --git a/src/game/GameSession.h b/src/game/GameSession.h index c11e9c0..4b0204c 100644 --- a/src/game/GameSession.h +++ b/src/game/GameSession.h @@ -12,7 +12,7 @@ class GameSession { private: - using GamePieceEventCallback = std::function; + using GamePieceEventCallback = std::function; std::unique_ptr m_board; PlayerID m_currentPlayer = PlayerID::P1; ActionType m_currentActionType = ActionType::GROW; diff --git a/src/game/GameTypes.h b/src/game/GameTypes.h index 7d22e10..8b35f35 100644 --- a/src/game/GameTypes.h +++ b/src/game/GameTypes.h @@ -30,5 +30,6 @@ enum class GameMode { enum class GamePieceEvent { REMOVE_PIECE, - PLACE_PIECE + PLACE_PIECE, + MOVE_PIECE }; \ No newline at end of file diff --git a/src/graphics/game/BoardRenderer.cpp b/src/graphics/game/BoardRenderer.cpp index 2555853..85e0515 100644 --- a/src/graphics/game/BoardRenderer.cpp +++ b/src/graphics/game/BoardRenderer.cpp @@ -149,9 +149,24 @@ void BoardRenderer::drawPiece(std::optional> selectedPiece) isRenderered = true; //return; } - if (!isRenderered) { + //if (!isRenderered) { + if (m_pieceMoveStatus.isAnimating && col == m_pieceMoveStatus.toCol && row == m_pieceMoveStatus.toRow) { + //SDL_Log("rendering..\n"); + m_pieceMoveStatus.currentTime += Time::deltaTime(); + if (m_pieceMoveStatus.currentTime > m_pieceMoveStatus.animationDuration) { + m_pieceMoveStatus.currentTime = m_pieceMoveStatus.animationDuration; + m_pieceMoveStatus.isAnimating = false; + } + float progess = m_pieceMoveStatus.currentTime / m_pieceMoveStatus.animationDuration; + auto renderRect = m_pieceMoveStatus.fromPieceRect; + renderRect.x += m_pieceMoveStatus.distanceCol * progess; + renderRect.y += m_pieceMoveStatus.distanceRow * progess; + SDL_RenderTexture(m_renderer, texture, nullptr, &renderRect); + } else { SDL_RenderTexture(m_renderer, texture, nullptr, &rect); - } + } + //} + } } @@ -284,38 +299,63 @@ void BoardRenderer::renderBlackOverlay() { SDL_SetRenderDrawBlendMode(m_renderer, SDL_BLENDMODE_NONE); } -void BoardRenderer::handleGamePieceEvent(GamePieceEvent event, int row, int col) { +void BoardRenderer::handleGamePieceEvent(GamePieceEvent event, int fromRow, int fromCol, int toRow, int toCol) { auto area = getBoardArea(); // 计算棋子中心位置 - float x = area.x + col * area.cellSize; - float y = area.y + row * area.cellSize; - + float fromX = area.x + fromCol * area.cellSize; + float fromY = area.y + fromRow * area.cellSize; + float toX = -1; + float toY = -1; + if (toRow != -1 && toCol != -1) { + toX = area.x + toCol * area.cellSize; + toY = area.y + toRow * area.cellSize; + } float pieceRadius = m_cellSize * m_pieceRadiusRatio / 2.0f; SDL_FRect rect{ - x + (area.cellSize - pieceRadius * 2) / 2.0f, - y + (area.cellSize - pieceRadius * 2) / 2.0f, + fromX + (area.cellSize - pieceRadius * 2) / 2.0f, + fromY + (area.cellSize - pieceRadius * 2) / 2.0f, pieceRadius * 2, pieceRadius * 2 }; - const Piece* piece = m_board->getPieceAt(row, col); - if (!piece) { + const Piece* piece = m_board->getPieceAt(fromRow, fromCol); + // 这里直接return导致的 + if (!piece && event != GamePieceEvent::MOVE_PIECE) { SDL_Log("BoardRenderer: piece is null\n"); return; } - SDL_Color color = (piece->getPieceOwner() == PlayerID::P1) ? - m_colors.P1 : m_colors.P2; + switch (event) { case (GamePieceEvent::REMOVE_PIECE): + { + SDL_Color color = (piece->getPieceOwner() == PlayerID::P1) ? + m_colors.P1 : m_colors.P2; //SDL_Log("BoardRenderer: try to destory texture\n"); m_textureManager->destoryTexture(rect, color); break; + } case (GamePieceEvent::PLACE_PIECE): + break; + case (GamePieceEvent::MOVE_PIECE): + //SDL_Log("MovePPPPPP\n"); + m_pieceMoveStatus = { + fromRow, fromCol, + toRow, toCol, + toY - fromY, + toX - fromX, + 0.0f, + true, + rect, + 1.0f + }; + break; default: break; } -} \ No newline at end of file +} + + diff --git a/src/graphics/game/BoardRenderer.h b/src/graphics/game/BoardRenderer.h index a4b0ebf..76007a6 100644 --- a/src/graphics/game/BoardRenderer.h +++ b/src/graphics/game/BoardRenderer.h @@ -13,6 +13,18 @@ struct PlayerColors { SDL_Color selected = {255, 255, 0, 255}; // 黄色(选中状态) }; +struct PieceMoveStatus { + int fromRow = -1; + int fromCol = -1; + int toRow = -1; + int toCol = -1; + float distanceRow; + float distanceCol; + float currentTime = 0.0f; // 当前已进行时间 + bool isAnimating = false; + SDL_FRect fromPieceRect; + float animationDuration = 1.0f; // 动画总时长(秒) +}; class Board; @@ -39,6 +51,8 @@ private: std::optional> m_lastSelected = std::nullopt; + PieceMoveStatus m_pieceMoveStatus; + public: BoardRenderer(int WIDTH, int HEIGHT, SDL_Renderer* renderer, TextureManager* textureManager); @@ -67,7 +81,7 @@ public: void renderBlackOverlay(); - void handleGamePieceEvent(GamePieceEvent event, int row, int col); + void handleGamePieceEvent(GamePieceEvent event, int fromRow, int fromCol, int toRow = -1, int toCol = -1); }; diff --git a/src/scenes/gameplay/GameScene.cpp b/src/scenes/gameplay/GameScene.cpp index ea88745..55ad045 100644 --- a/src/scenes/gameplay/GameScene.cpp +++ b/src/scenes/gameplay/GameScene.cpp @@ -72,9 +72,9 @@ void GameScene::onEnter(SDL_Renderer* renderer, int WIDTH, int HEIGHT, UIRendere m_boardRenderer->setBoard(m_gameSession->getBoard()); m_gameSession->setGamePieceEventCallback( - [this](GamePieceEvent evnet, int row, int col) { - std::cout << "GameScene: recevie the event piece at " << row << " " << col << "\n"; - m_boardRenderer->handleGamePieceEvent(evnet, row, col); + [this](GamePieceEvent evnet, int fromRow, int fromCol, int toRow, int toCol) { + std::cout << "GameScene: recevie the event piece at " << fromRow << " " << fromCol << "\n"; + m_boardRenderer->handleGamePieceEvent(evnet, fromRow, fromCol, toRow, toCol); } ); @@ -142,9 +142,9 @@ void GameScene::restartGame() { m_boardRenderer->setGameState(GameState::GAME_RUNING); m_gameSession->setGamePieceEventCallback( - [this](GamePieceEvent evnet, int row, int col) { - std::cout << "GameScene: recevie the event piece at " << row << " " << col << "\n"; - m_boardRenderer->handleGamePieceEvent(evnet, row, col); + [this](GamePieceEvent evnet, int fromRow, int fromCol, int toRow, int toCol) { + std::cout << "GameScene: recevie the event piece at " << fromRow << " " << fromCol << "\n"; + m_boardRenderer->handleGamePieceEvent(evnet, fromRow, fromCol, toRow, toCol); } );