diff --git a/src/game/Board.h b/src/game/Board.h index 37cabaf..b2efc1e 100644 --- a/src/game/Board.h +++ b/src/game/Board.h @@ -59,4 +59,8 @@ public: bool changeATK(int row, int col, int num); bool setPieceInfo(int row, int col, PieceInfo pieceInfo); + + std::unordered_map> getAllComponents() const { + return m_component->getAllComponents(); + } }; \ No newline at end of file diff --git a/src/graphics/game/BoardRenderer.cpp b/src/graphics/game/BoardRenderer.cpp index c8f4381..cc844ce 100644 --- a/src/graphics/game/BoardRenderer.cpp +++ b/src/graphics/game/BoardRenderer.cpp @@ -35,6 +35,7 @@ bool BoardRenderer::initialize() { void BoardRenderer::setBoard(const Board* board) { m_board = board; + m_cachedComponment = m_board->getAllComponents(); } @@ -388,7 +389,7 @@ void BoardRenderer::drawMovementRange() { if (!m_board || !m_renderer) return; // 开启混合模式(重要!) - SDL_SetRenderDrawBlendMode(m_renderer, SDL_BLENDMODE_BLEND); + //SDL_SetRenderDrawBlendMode(m_renderer, SDL_BLENDMODE_BLEND); float pieceRadius = m_cellSize * m_pieceRadiusRatio / 4.0f; @@ -415,9 +416,44 @@ void BoardRenderer::drawMovementRange() { SDL_RenderFillRect(m_renderer, &rect); } // 如果需要,绘制完可以恢复原来的混合模式 - SDL_SetRenderDrawBlendMode(m_renderer, SDL_BLENDMODE_NONE); + //SDL_SetRenderDrawBlendMode(m_renderer, SDL_BLENDMODE_NONE); } +void BoardRenderer::drawComponentRange() { + for (const auto& it : m_cachedComponment) { + auto [key, component] = it; + std::hash hasher; + size_t h = hasher(key); + // 把哈希空间切成大块,每块颜色突变 + Uint8 r = static_cast((h * 7) % 256); // 乘质数打乱 + Uint8 g = static_cast((h * 17) % 256); + Uint8 b = static_cast((h * 37) % 256); + // 强化对比:如果太灰,强制拉伸 + int gray = (r + g + b) / 3; + if (std::abs(r - gray) < 30 && std::abs(g - gray) < 30 && std::abs(b - gray) < 30) { + // 太灰了,强制变成鲜艳色 + r = (r + 128) % 256; + g = (g + 64) % 256; + b = (b + 192) % 256; + } + SDL_SetRenderDrawColor(m_renderer, r, g, b, 100); + for (auto pieceID : component) { + auto [row, col] = m_board->getCoordFromID(pieceID); + SDL_FRect rect{ + static_cast(m_area.x + col * m_area.cellSize), + static_cast(m_area.y + row * m_area.cellSize), + static_cast(m_area.cellSize), + static_cast(m_area.cellSize) + }; + + + // SDL3: RenderFillRect 接受 const SDL_FRect* + SDL_RenderFillRect(m_renderer, &rect); + } + } +} + + BoardArea BoardRenderer::getBoardArea() const { return { (m_Width - m_cellSize * m_boardCOL) / 2, @@ -456,7 +492,7 @@ void BoardRenderer::renderBlackOverlay() { } void BoardRenderer::handleGamePieceEvent(GamePieceEvent event, int fromRow, int fromCol, int toRow, int toCol) { - + // 计算棋子中心位置 float fromX = m_area.x + fromCol * m_area.cellSize; float fromY = m_area.y + fromRow * m_area.cellSize; @@ -552,4 +588,10 @@ void BoardRenderer::handleGamePieceEvent(GamePieceEvent event, int fromRow, int } +void BoardRenderer::updateComponent() { + if (m_board == nullptr) { + return; + } + m_cachedComponment = m_board ->getAllComponents(); +} diff --git a/src/graphics/game/BoardRenderer.h b/src/graphics/game/BoardRenderer.h index 93ae3d6..b035ab6 100644 --- a/src/graphics/game/BoardRenderer.h +++ b/src/graphics/game/BoardRenderer.h @@ -114,6 +114,8 @@ private: PieceAnimation m_pieceAnimation; + std::unordered_map> m_cachedComponment; + public: BoardRenderer(int WIDTH, int HEIGHT, SDL_Renderer* renderer, TextureManager* textureManager); @@ -140,6 +142,8 @@ public: void drawMovementRange(); BoardArea getBoardArea() const; + void drawComponentRange(); + void setGameState(GameState state); void renderBlackOverlay(); @@ -153,7 +157,7 @@ public: void updateMoveAnimation(float deltaTime); void updateFightAnimation(float deltaTime); void updateSelectedAnimation(float deltaTime); - + void updateComponent(); }; diff --git a/src/scenes/gameplay/GameScene.cpp b/src/scenes/gameplay/GameScene.cpp index a47d0e1..1343937 100644 --- a/src/scenes/gameplay/GameScene.cpp +++ b/src/scenes/gameplay/GameScene.cpp @@ -45,6 +45,7 @@ void GameScene::postHandleClick() { m_gameUIManager->updateGameState(m_gameSession->getGameState()); m_boardRenderer->setGameState(m_gameSession->getGameState()); m_gameUIManager->updatePlayerTurn(m_gameSession->getCurrentPlayer()); + m_boardRenderer->updateComponent(); } @@ -91,9 +92,10 @@ void GameScene::renderWorld() { m_boardRenderer->drawBackground(); m_boardRenderer->drawBoard(); - + m_boardRenderer->drawComponentRange(); m_boardRenderer->drawPiece(m_gameSession->getSelectedPiece()); m_boardRenderer->drawMovementRange(); + m_boardRenderer->renderBlackOverlay(); @@ -144,7 +146,7 @@ void GameScene::restartGame() { m_gameUIManager->updateActionType(ActionType::GROW); m_gameUIManager->updateGameState(GameState::GAME_RUNING); m_boardRenderer->setGameState(GameState::GAME_RUNING); - + m_gameSession->setGamePieceEventCallback( [this](GamePieceEvent evnet, int fromRow, int fromCol, int toRow, int toCol) { std::cout << "GameScene: recevie the event piece at " << fromRow << " " << fromCol << "\n"; diff --git a/src/utils/Tools.h b/src/utils/Tools.h index 7a05481..80af790 100644 --- a/src/utils/Tools.h +++ b/src/utils/Tools.h @@ -50,4 +50,21 @@ namespace Tools { } + // 辅助函数:HSV -> RGB + inline void hsvToRgb(float h, float s, float v, Uint8& r, Uint8& g, Uint8& b) { + float c = v * s; + float x = c * (1 - std::abs(std::fmod(h / 60.0f, 2) - 1)); + float m = v - c; + float r_, g_, b_; + if (h < 60) { r_ = c; g_ = x; b_ = 0; } + else if (h < 120) { r_ = x; g_ = c; b_ = 0; } + else if (h < 180) { r_ = 0; g_ = c; b_ = x; } + else if (h < 240) { r_ = 0; g_ = x; b_ = c; } + else if (h < 300) { r_ = x; g_ = 0; b_ = c; } + else { r_ = c; g_ = 0; b_ = x; } + r = static_cast((r_ + m) * 255); + g = static_cast((g_ + m) * 255); + b = static_cast((b_ + m) * 255); + } + } \ No newline at end of file