mirror of
https://github.com/zhenyan121/SporeBG-Conid.git
synced 2026-04-10 06:14:08 +08:00
Added drawMovementRange function
This commit is contained in:
@@ -30,7 +30,7 @@ void BoardRenderer::drawBoard() {
|
|||||||
auto area = getBoardArea();
|
auto area = getBoardArea();
|
||||||
|
|
||||||
|
|
||||||
// 绘制棋盘格子(交替颜色)
|
// 绘制棋盘格子
|
||||||
for (int row = 0; row < area.rows; ++row) {
|
for (int row = 0; row < area.rows; ++row) {
|
||||||
for (int col = 0; col < area.cols; ++col) {
|
for (int col = 0; col < area.cols; ++col) {
|
||||||
// 使用 SDL_FRect(浮点数)
|
// 使用 SDL_FRect(浮点数)
|
||||||
@@ -68,8 +68,8 @@ void BoardRenderer::drawPiece(std::optional<std::pair<int, int>> selectedPiece)
|
|||||||
if (!piece) continue; // 没有棋子则跳过
|
if (!piece) continue; // 没有棋子则跳过
|
||||||
|
|
||||||
// 计算棋子中心位置
|
// 计算棋子中心位置
|
||||||
float centerX = area.x + col * area.cellSize + area.cellSize / 2.0f;
|
float x = area.x + col * area.cellSize;
|
||||||
float centerY = area.y + row * area.cellSize + area.cellSize / 2.0f;
|
float y = area.y + row * area.cellSize;
|
||||||
|
|
||||||
// 确定棋子颜色
|
// 确定棋子颜色
|
||||||
SDL_Color color;
|
SDL_Color color;
|
||||||
@@ -82,23 +82,112 @@ void BoardRenderer::drawPiece(std::optional<std::pair<int, int>> selectedPiece)
|
|||||||
m_colors.P1 : m_colors.P2;
|
m_colors.P1 : m_colors.P2;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 绘制棋子(圆形)
|
|
||||||
SDL_SetRenderDrawColor(m_renderer, color.r, color.g, color.b, color.a);
|
SDL_SetRenderDrawColor(m_renderer, color.r, color.g, color.b, color.a);
|
||||||
|
|
||||||
// 绘制实心圆(使用多个同心圆来近似)
|
SDL_FRect rect{
|
||||||
for (float r = pieceRadius; r > 0; r -= 1.0f) {
|
x + (area.cellSize - pieceRadius * 2) / 2.0f,
|
||||||
SDL_FRect rect = {
|
y + (area.cellSize - pieceRadius * 2) / 2.0f,
|
||||||
centerX - r,
|
pieceRadius * 2,
|
||||||
centerY - r,
|
pieceRadius * 2
|
||||||
r * 2.0f,
|
};
|
||||||
r * 2.0f
|
|
||||||
};
|
SDL_RenderFillRect(m_renderer, &rect);
|
||||||
SDL_RenderFillRect(m_renderer, &rect);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BoardRenderer::updateMovementRange(std::optional<std::pair<int, int>> selectedPiece, ActionType tpye) {
|
||||||
|
// 清空当前范围以便下次更新
|
||||||
|
m_currentDrawRange.clear();
|
||||||
|
if (!m_board || !m_renderer || !selectedPiece) return;
|
||||||
|
if (selectedPiece == std::nullopt) return;
|
||||||
|
auto selectedComponent = m_board->getComponentByPieceID(m_board->getPieceID(selectedPiece->first, selectedPiece->second));
|
||||||
|
|
||||||
|
auto currentPlayer = m_board->getPieceAt(selectedPiece->first, selectedPiece->second)->getPieceOwner();
|
||||||
|
switch (tpye) {
|
||||||
|
case ActionType::GROW:
|
||||||
|
// 绘制生长范围的逻辑
|
||||||
|
for (auto PieceID : selectedComponent) {
|
||||||
|
auto Neighbors = m_board->getOrthogonalNeighbors(PieceID);
|
||||||
|
for (auto neighborID : Neighbors) {
|
||||||
|
auto pieceCoord = m_board->getCoordFromID(neighborID);
|
||||||
|
const Piece* piece = m_board->getPieceAt(pieceCoord.first, pieceCoord.second);
|
||||||
|
if (piece == nullptr) {
|
||||||
|
m_currentDrawRange.insert(neighborID);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ActionType::MOVE:
|
||||||
|
// 绘制移动范围的逻辑
|
||||||
|
for (auto PieceID : selectedComponent) {
|
||||||
|
auto Neighbors = m_board->getOrthogonalNeighbors(PieceID);
|
||||||
|
for (auto neighborID : Neighbors) {
|
||||||
|
auto pieceCoord = m_board->getCoordFromID(neighborID);
|
||||||
|
const Piece* piece = m_board->getPieceAt(pieceCoord.first, pieceCoord.second);
|
||||||
|
if (piece == nullptr) {
|
||||||
|
m_currentDrawRange.insert(neighborID);
|
||||||
|
} else if (piece->getPieceOwner() != currentPlayer) {
|
||||||
|
m_currentDrawRange.insert(neighborID);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ActionType::SPORE: {
|
||||||
|
// 绘制孢子范围的逻辑
|
||||||
|
auto SporeRange = m_board->getSporeRange(m_board->getPieceID(selectedPiece->first, selectedPiece->second));
|
||||||
|
for (auto neighborID : SporeRange) {
|
||||||
|
auto pieceCoord = m_board->getCoordFromID(neighborID);
|
||||||
|
const Piece* piece = m_board->getPieceAt(pieceCoord.first, pieceCoord.second);
|
||||||
|
if (piece == nullptr) {
|
||||||
|
m_currentDrawRange.insert(neighborID);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void BoardRenderer::drawMovementRange() {
|
||||||
|
|
||||||
|
if (!m_board || !m_renderer) return;
|
||||||
|
|
||||||
|
// 开启混合模式(重要!)
|
||||||
|
SDL_SetRenderDrawBlendMode(m_renderer, SDL_BLENDMODE_BLEND);
|
||||||
|
|
||||||
|
auto area = getBoardArea();
|
||||||
|
float pieceRadius = m_cellSize * m_pieceRadiusRatio / 4.0f;
|
||||||
|
for (auto PieceID : m_currentDrawRange) {
|
||||||
|
auto [row, col] = m_board->getCoordFromID(PieceID);
|
||||||
|
|
||||||
|
// 计算棋子中心位置
|
||||||
|
float x = area.x + col * area.cellSize;
|
||||||
|
float y = area.y + row * area.cellSize;
|
||||||
|
|
||||||
|
SDL_FRect rect{
|
||||||
|
x + (area.cellSize - pieceRadius * 2) / 2.0f,
|
||||||
|
y + (area.cellSize - pieceRadius * 2) / 2.0f,
|
||||||
|
pieceRadius * 2,
|
||||||
|
pieceRadius * 2
|
||||||
|
};
|
||||||
|
|
||||||
|
SDL_SetRenderDrawColor(m_renderer,
|
||||||
|
0,
|
||||||
|
255,
|
||||||
|
0,
|
||||||
|
100); // 半透明绿色
|
||||||
|
|
||||||
|
SDL_RenderFillRect(m_renderer, &rect);
|
||||||
|
}
|
||||||
|
// 如果需要,绘制完可以恢复原来的混合模式
|
||||||
|
SDL_SetRenderDrawBlendMode(m_renderer, SDL_BLENDMODE_NONE);
|
||||||
|
}
|
||||||
|
|
||||||
BoardArea BoardRenderer::getBoardArea() const {
|
BoardArea BoardRenderer::getBoardArea() const {
|
||||||
return {
|
return {
|
||||||
(m_Width - m_cellSize * m_boardCOL) / 2,
|
(m_Width - m_cellSize * m_boardCOL) / 2,
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "utils/Config.h"
|
#include "utils/Config.h"
|
||||||
|
#include "game/GameTypes.h"
|
||||||
#include <SDL3/SDL.h>
|
#include <SDL3/SDL.h>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
#include <unordered_set>
|
||||||
|
|
||||||
struct PlayerColors {
|
struct PlayerColors {
|
||||||
SDL_Color P1 = {255, 0, 0, 255}; // 红色
|
SDL_Color P1 = {255, 0, 0, 255}; // 红色
|
||||||
@@ -29,6 +30,7 @@ private:
|
|||||||
// 棋子绘制相关
|
// 棋子绘制相关
|
||||||
float m_pieceRadiusRatio = 0.8f; // 棋子半径相对于格子大小的比例
|
float m_pieceRadiusRatio = 0.8f; // 棋子半径相对于格子大小的比例
|
||||||
PlayerColors m_colors;
|
PlayerColors m_colors;
|
||||||
|
std::unordered_set<int> m_currentDrawRange;
|
||||||
public:
|
public:
|
||||||
BoardRenderer(int WIDTH, int HEIGHT, SDL_Renderer* renderer);
|
BoardRenderer(int WIDTH, int HEIGHT, SDL_Renderer* renderer);
|
||||||
|
|
||||||
@@ -48,7 +50,9 @@ public:
|
|||||||
// 绘制棋子
|
// 绘制棋子
|
||||||
void drawPiece(std::optional<std::pair<int, int>> selectedPiece = std::nullopt);
|
void drawPiece(std::optional<std::pair<int, int>> selectedPiece = std::nullopt);
|
||||||
|
|
||||||
|
void updateMovementRange(std::optional<std::pair<int, int>> selectedPiece = std::nullopt, ActionType type = ActionType::GROW);
|
||||||
|
|
||||||
|
void drawMovementRange();
|
||||||
BoardArea getBoardArea() const;
|
BoardArea getBoardArea() const;
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ void GameScene::render() {
|
|||||||
m_boardRenderer->drawBoard();
|
m_boardRenderer->drawBoard();
|
||||||
|
|
||||||
m_boardRenderer->drawPiece(m_gameSession->getSelectedPiece());
|
m_boardRenderer->drawPiece(m_gameSession->getSelectedPiece());
|
||||||
|
m_boardRenderer->drawMovementRange();
|
||||||
m_uiRenderer->renderUI(m_gameUIManager->getUIRenderData());
|
m_uiRenderer->renderUI(m_gameUIManager->getUIRenderData());
|
||||||
endFrame();
|
endFrame();
|
||||||
}
|
}
|
||||||
@@ -46,6 +47,7 @@ void GameScene::handleClick(float screenX, float screenY) {
|
|||||||
m_gameSession->handleCoordinateInput(row, col);
|
m_gameSession->handleCoordinateInput(row, col);
|
||||||
m_gameSession->printBoard();
|
m_gameSession->printBoard();
|
||||||
m_gameUIManager->updateActionType( m_gameSession->getCurrentActionType());
|
m_gameUIManager->updateActionType( m_gameSession->getCurrentActionType());
|
||||||
|
m_boardRenderer->updateMovementRange(m_gameSession->getSelectedPiece(), m_gameSession->getCurrentActionType());
|
||||||
} else {
|
} else {
|
||||||
SDL_Log("invail cilck aera!");
|
SDL_Log("invail cilck aera!");
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user