mirror of
https://github.com/zhenyan121/SporeBG-Conid.git
synced 2026-04-09 22:06:09 +08:00
feat: add MOVE animation
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
class GameSession {
|
||||
|
||||
private:
|
||||
using GamePieceEventCallback = std::function<void(GamePieceEvent, int x, int y)>;
|
||||
using GamePieceEventCallback = std::function<void(GamePieceEvent, int fromRow, int fromCol, int toRow, int toCol)>;
|
||||
std::unique_ptr<Board> m_board;
|
||||
PlayerID m_currentPlayer = PlayerID::P1;
|
||||
ActionType m_currentActionType = ActionType::GROW;
|
||||
|
||||
@@ -30,5 +30,6 @@ enum class GameMode {
|
||||
|
||||
enum class GamePieceEvent {
|
||||
REMOVE_PIECE,
|
||||
PLACE_PIECE
|
||||
PLACE_PIECE,
|
||||
MOVE_PIECE
|
||||
};
|
||||
@@ -149,9 +149,24 @@ void BoardRenderer::drawPiece(std::optional<std::pair<int, int>> 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;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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<std::pair<int, int>> 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);
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user