Files
dl/project/dl_test/game_match.cpp
T
2026-09-16 14:07:40 +08:00

249 lines
6.0 KiB
C++

#include "game_match.h"
GameMatch::GameMatch()
{
GenerateBoard();
_txt = g_factory->CreateTextDefault();
_txt->SetFontSize(24);
_txt->SetPositionAlign(toPosition(400, 50), Align::CT);
_txt->SetString("Score: 0");
}
GameMatch::~GameMatch()
{
}
void GameMatch::Init()
{
}
void GameMatch::Update()
{
if (g_input->KeyDown(MouseCode::LEFT))
{
Point mousePos = g_input->GetCursorPosition();
int x = (mousePos.x - 100) / 60;
int y = (mousePos.y - 100) / 60;
if (x >= 0 && x < BOARD_SIZE && y >= 0 && y < BOARD_SIZE)
{
if (_selectedPos.x == -1)
{
_selectedPos = toPosition(static_cast<float>(x), static_cast<float>(y));
}
else
{
if ((abs(static_cast<int>(_selectedPos.x) - x) == 1 && static_cast<int>(_selectedPos.y) == y) ||
(abs(static_cast<int>(_selectedPos.y) - y) == 1 && static_cast<int>(_selectedPos.x) == x))
{
if (CanSwap(static_cast<int>(_selectedPos.x), static_cast<int>(_selectedPos.y), x, y))
{
SwapItems(static_cast<int>(_selectedPos.x), static_cast<int>(_selectedPos.y), x, y);
CheckMatches();
RemoveMatches();
DropItems();
RefillBoard();
CheckMatches();
RemoveMatches();
}
}
_selectedPos = toPosition(-1.0f, -1.0f);
}
}
}
}
void GameMatch::Render()
{
for (int y = 0; y < BOARD_SIZE; y++)
{
for (int x = 0; x < BOARD_SIZE; x++)
{
int type = _board[y][x].type;
if (type > 0)
{
g_gfx->SetCoor(nullptr);
g_gfx->SetColor(createColorHSV((type - 1) * 60.0f, 1.0f, 1.0f));
g_gfx->RectangleSolid2D(toPosition(100 + x * 60, 100 + y * 60), toPosition(100 + x * 60 + 50, 100 + y * 60 + 50));
}
}
}
if (_selectedPos.x != -1)
{
g_gfx->SetCoor(nullptr);
g_gfx->SetColor(ColorDef::WHITE);
g_gfx->Rectangle2D(toPosition(100 + _selectedPos.x * 60, 100 + _selectedPos.y * 60), toPosition(100 + _selectedPos.x * 60 + 50, 100 + _selectedPos.y * 60 + 50));
}
if(_txt)
_txt->Render();
}
void GameMatch::GenerateBoard()
{
for (int y = 0; y < BOARD_SIZE; y++)
{
for (int x = 0; x < BOARD_SIZE; x++)
{
_board[y][x].type = rand() % 5 + 1;
}
}
}
void GameMatch::CheckMatches()
{
for (int y = 0; y < BOARD_SIZE; y++)
{
for (int x = 0; x < BOARD_SIZE; x++)
{
_board[y][x].matched = false;
}
}
for (int y = 0; y < BOARD_SIZE; y++)
{
int count = 1;
int type = _board[y][0].type;
for (int x = 1; x < BOARD_SIZE; x++)
{
if (_board[y][x].type == type)
{
count++;
}
else
{
if (count >= 3)
{
for (int i = x - count; i < x; i++)
{
_board[y][i].matched = true;
}
}
count = 1;
type = _board[y][x].type;
}
}
if (count >= 3)
{
for (int i = BOARD_SIZE - count; i < BOARD_SIZE; i++)
{
_board[y][i].matched = true;
}
}
}
for (int x = 0; x < BOARD_SIZE; x++)
{
int count = 1;
int type = _board[0][x].type;
for (int y = 1; y < BOARD_SIZE; y++)
{
if (_board[y][x].type == type)
{
count++;
}
else
{
if (count >= 3)
{
for (int i = y - count; i < y; i++)
{
_board[i][x].matched = true;
}
}
count = 1;
type = _board[y][x].type;
}
}
if (count >= 3)
{
for (int i = BOARD_SIZE - count; i < BOARD_SIZE; i++)
{
_board[i][x].matched = true;
}
}
}
}
void GameMatch::RemoveMatches()
{
for (int y = 0; y < BOARD_SIZE; y++)
{
for (int x = 0; x < BOARD_SIZE; x++)
{
if (_board[y][x].matched)
{
_board[y][x].type = 0;
_score += 10;
}
}
}
_txt->SetString("Score: " + to_string(_score));
}
void GameMatch::DropItems()
{
for (int x = 0; x < BOARD_SIZE; x++)
{
int emptyCount = 0;
for (int y = BOARD_SIZE - 1; y >= 0; y--)
{
if (_board[y][x].type == 0)
{
emptyCount++;
}
else if (emptyCount > 0)
{
_board[y + emptyCount][x].type = _board[y][x].type;
_board[y][x].type = 0;
}
}
}
}
void GameMatch::RefillBoard()
{
for (int x = 0; x < BOARD_SIZE; x++)
{
for (int y = 0; y < BOARD_SIZE; y++)
{
if (_board[y][x].type == 0)
{
_board[y][x].type = rand() % 5 + 1;
}
}
}
}
bool GameMatch::CanSwap(int x1, int y1, int x2, int y2)
{
SwapItems(x1, y1, x2, y2);
CheckMatches();
bool hasMatch = false;
for (int y = 0; y < BOARD_SIZE; y++)
{
for (int x = 0; x < BOARD_SIZE; x++)
{
if (_board[y][x].matched)
{
hasMatch = true;
break;
}
}
if (hasMatch)
{
break;
}
}
SwapItems(x1, y1, x2, y2);
return hasMatch;
}
void GameMatch::SwapItems(int x1, int y1, int x2, int y2)
{
std::swap(_board[y1][x1].type, _board[y2][x2].type);
std::swap(_board[y1][x1].matched, _board[y2][x2].matched);
}