feat: add GROW and SPORE animation

This commit is contained in:
2026-01-17 12:21:48 +08:00
parent df3699c791
commit 940f0b11a1
6 changed files with 49 additions and 4 deletions

View File

@@ -35,7 +35,8 @@ bool WindowManager::Initialize(Config& config) {
"创建渲染器失败: %s", SDL_GetError());
return false;
}
// 开启混合模式
SDL_SetRenderDrawBlendMode(m_renderer, SDL_BLENDMODE_BLEND);
if (config.window.vsync) {
SDL_SetRenderVSync(m_renderer, true);
} else {

View File

@@ -61,7 +61,9 @@ bool GameSession::executeAction(int toRow, int toCol) {
auto [fromRow, fromCol] = *m_seletedPiece;
if (m_currentActionType == ActionType::GROW) {
if (Rule::canGrow(m_board.get(), fromRow, fromCol, toRow, toCol, m_currentPlayer)) {
m_gamePieceEventCallback(GamePieceEvent::PLACE_PIECE, toRow, toCol, -1, -1);
m_gamePieceEventCallback(GamePieceEvent::GROW_PIECE, fromRow, fromCol, toRow, toCol);
m_board->placePieceAt(toRow, toCol, m_currentPlayer);
// 如果执行了操作就擦除
@@ -89,6 +91,7 @@ bool GameSession::executeAction(int toRow, int toCol) {
if (Rule::canSpore(m_board.get(), fromRow, fromCol, toRow, toCol, m_currentPlayer)) {
m_gamePieceEventCallback(GamePieceEvent::REMOVE_PIECE, fromRow, fromCol, -1, -1);
m_gamePieceEventCallback(GamePieceEvent::PLACE_PIECE, toRow, toCol, -1, -1);
m_gamePieceEventCallback(GamePieceEvent::MOVE_PIECE, fromRow, fromCol, toRow, toCol);
m_board->removePieceAt(fromRow, fromCol);
m_board->placePieceAt(toRow, toCol, m_currentPlayer);

View File

@@ -31,5 +31,7 @@ enum class GameMode {
enum class GamePieceEvent {
REMOVE_PIECE,
PLACE_PIECE,
MOVE_PIECE
MOVE_PIECE,
GROW_PIECE,
SPORE_PIECE
};

View File

@@ -104,6 +104,23 @@ void BoardRenderer::drawPiece(std::optional<std::pair<int, int>> selectedPiece)
auto texture = m_textureManager->createTextureFromRect(rect, color);
//SDL_FRect srect = {0, 0, rect.w, rect.h};
if (m_pieceGrowStatus.isAnimating && m_pieceGrowStatus.row == row && m_pieceGrowStatus.col == col) {
m_pieceGrowStatus.currentTime += Time::deltaTime();
if (m_pieceGrowStatus.currentTime > m_pieceGrowStatus.animationDuration) {
m_pieceGrowStatus.currentTime = m_pieceGrowStatus.animationDuration;
m_pieceGrowStatus.isAnimating = false;
}
float progess = m_pieceGrowStatus.currentTime / m_pieceGrowStatus.animationDuration;
m_textureManager->destoryTexture(rect, color);
auto renderColor = color;
renderColor.a = 255 * progess;
auto texture = m_textureManager->createTextureFromRect(rect, renderColor);
SDL_RenderTexture(m_renderer, texture, nullptr, &rect);
continue;
}
if (isSelected) {
// 如果被选择
static float animationDuration = 1.0f; // 动画总时长(秒)
@@ -280,7 +297,7 @@ void BoardRenderer::renderBlackOverlay() {
if (!m_renderer) return;
if (m_gameState == GameState::GAME_RUNING) return;
// 开启混合模式(重要!)
SDL_SetRenderDrawBlendMode(m_renderer, SDL_BLENDMODE_BLEND);
//SDL_SetRenderDrawBlendMode(m_renderer, SDL_BLENDMODE_BLEND);
// 设置黑色半透明颜色
SDL_SetRenderDrawColor(m_renderer, 0, 0, 0, 150); // 半透明黑色
@@ -296,7 +313,7 @@ void BoardRenderer::renderBlackOverlay() {
SDL_RenderFillRect(m_renderer, &rect);
// 恢复原来的混合模式
SDL_SetRenderDrawBlendMode(m_renderer, SDL_BLENDMODE_NONE);
//SDL_SetRenderDrawBlendMode(m_renderer, SDL_BLENDMODE_NONE);
}
void BoardRenderer::handleGamePieceEvent(GamePieceEvent event, int fromRow, int fromCol, int toRow, int toCol) {
@@ -351,6 +368,15 @@ void BoardRenderer::handleGamePieceEvent(GamePieceEvent event, int fromRow, int
1.0f
};
break;
case (GamePieceEvent::GROW_PIECE):
m_pieceGrowStatus = {
toRow,
toCol,
0.0f,
true,
1.0f
};
break;
default:
break;

View File

@@ -26,6 +26,15 @@ struct PieceMoveStatus {
float animationDuration = 1.0f; // 动画总时长(秒)
};
struct PieceGrowStatue {
int row = -1;
int col = -1;
float currentTime = 0.0f;
bool isAnimating = false;
float animationDuration = 1.0f;
};
class Board;
class BoardRenderer
@@ -53,6 +62,8 @@ private:
PieceMoveStatus m_pieceMoveStatus;
PieceGrowStatue m_pieceGrowStatus;
public:
BoardRenderer(int WIDTH, int HEIGHT, SDL_Renderer* renderer, TextureManager* textureManager);

View File

@@ -43,6 +43,8 @@ SDL_Texture* TextureManager::createTextureFromRect(SDL_FRect& rect, SDL_Color& c
rect.w,
rect.h
);
// 开启纹理混合
SDL_SetTextureBlendMode(newTexture, SDL_BLENDMODE_BLEND);
// 保存当前的渲染目标
auto currentTexture = SDL_GetRenderTarget(m_renderer);