Part6 完成
This commit is contained in:
@@ -50,4 +50,4 @@
|
||||
|
||||
简要说明:完成最终游戏界面绘制,并与前面的逻辑配合形成可运行的完整项目。
|
||||
|
||||
- [ ] `20. TDrawScreen` - `src/source/TetrisRender.cpp`
|
||||
- [x] `20. TDrawScreen` - `src/source/TetrisRender.cpp`
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 269 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 168 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 35 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 29 KiB |
+222
-3
@@ -1,9 +1,228 @@
|
||||
#include "stdafx.h"
|
||||
#include "Tetris.h"
|
||||
|
||||
/**
|
||||
* @brief 完整绘制当前游戏界面。
|
||||
*
|
||||
* 该函数负责绘制窗口背景、游戏工作区边框、网格、已经固定的方块、
|
||||
* 当前活动方块、预测落点、右侧信息面板以及游戏结束提示文字。
|
||||
* 绘制过程只负责根据当前全局游戏状态进行显示,不修改任何游戏逻辑数据。
|
||||
*
|
||||
* @param hdc 当前窗口绘图设备上下文。
|
||||
* @param hWnd 当前窗口句柄,用于获取客户区尺寸。
|
||||
*/
|
||||
void TDrawScreen(HDC hdc, HWND hWnd)
|
||||
{
|
||||
// TODO(作业20): 完整绘制游戏界面。
|
||||
UNREFERENCED_PARAMETER(hdc);
|
||||
UNREFERENCED_PARAMETER(hWnd);
|
||||
RECT clientRect;
|
||||
GetClientRect(hWnd, &clientRect);
|
||||
|
||||
HBRUSH backgroundBrush = CreateSolidBrush(RGB(245, 245, 245));
|
||||
FillRect(hdc, &clientRect, backgroundBrush);
|
||||
DeleteObject(backgroundBrush);
|
||||
|
||||
RECT gameRect =
|
||||
{
|
||||
GRID,
|
||||
GRID,
|
||||
GRID + nGameWidth * GRID,
|
||||
GRID + nGameHeight * GRID
|
||||
};
|
||||
|
||||
// 绘制游戏区背景
|
||||
HBRUSH gameBrush = CreateSolidBrush(RGB(30, 30, 30));
|
||||
FillRect(hdc, &gameRect, gameBrush);
|
||||
DeleteObject(gameBrush);
|
||||
|
||||
// 绘制游戏区边框
|
||||
HPEN borderPen = CreatePen(PS_SOLID, 2, RGB(80, 80, 80));
|
||||
HPEN oldPen = (HPEN)SelectObject(hdc, borderPen);
|
||||
HBRUSH oldBrush = (HBRUSH)SelectObject(hdc, GetStockObject(NULL_BRUSH));
|
||||
Rectangle(hdc, gameRect.left, gameRect.top, gameRect.right, gameRect.bottom);
|
||||
SelectObject(hdc, oldBrush);
|
||||
SelectObject(hdc, oldPen);
|
||||
DeleteObject(borderPen);
|
||||
|
||||
// 绘制网格线
|
||||
HPEN gridPen = CreatePen(PS_SOLID, 1, RGB(55, 55, 55));
|
||||
oldPen = (HPEN)SelectObject(hdc, gridPen);
|
||||
|
||||
for (int i = 1; i < nGameWidth; i++)
|
||||
{
|
||||
int x = gameRect.left + i * GRID;
|
||||
MoveToEx(hdc, x, gameRect.top, nullptr);
|
||||
LineTo(hdc, x, gameRect.bottom);
|
||||
}
|
||||
|
||||
for (int i = 1; i < nGameHeight; i++)
|
||||
{
|
||||
int y = gameRect.top + i * GRID;
|
||||
MoveToEx(hdc, gameRect.left, y, nullptr);
|
||||
LineTo(hdc, gameRect.right, y);
|
||||
}
|
||||
|
||||
SelectObject(hdc, oldPen);
|
||||
DeleteObject(gridPen);
|
||||
|
||||
// 绘制已经固定的方块
|
||||
for (int i = 0; i < nGameHeight; i++)
|
||||
{
|
||||
for (int j = 0; j < nGameWidth; j++)
|
||||
{
|
||||
if (workRegion[i][j] != 0)
|
||||
{
|
||||
int colorIndex = workRegion[i][j] - 1;
|
||||
RECT brickRect =
|
||||
{
|
||||
gameRect.left + j * GRID + 1,
|
||||
gameRect.top + i * GRID + 1,
|
||||
gameRect.left + (j + 1) * GRID - 1,
|
||||
gameRect.top + (i + 1) * GRID - 1
|
||||
};
|
||||
|
||||
HBRUSH brickBrush = CreateSolidBrush(BrickColor[colorIndex]);
|
||||
FillRect(hdc, &brickRect, brickBrush);
|
||||
DeleteObject(brickBrush);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 绘制预测落点
|
||||
if (targetFlag)
|
||||
{
|
||||
HPEN targetPen = CreatePen(PS_DOT, 1, RGB(220, 220, 220));
|
||||
oldPen = (HPEN)SelectObject(hdc, targetPen);
|
||||
oldBrush = (HBRUSH)SelectObject(hdc, GetStockObject(NULL_BRUSH));
|
||||
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
for (int j = 0; j < 4; j++)
|
||||
{
|
||||
if (bricks[type][state][i][j] != 0)
|
||||
{
|
||||
int drawY = target.y + i;
|
||||
int drawX = target.x + j;
|
||||
|
||||
if (drawY >= 0 && drawY < nGameHeight && drawX >= 0 && drawX < nGameWidth)
|
||||
{
|
||||
Rectangle(
|
||||
hdc,
|
||||
gameRect.left + drawX * GRID + 4,
|
||||
gameRect.top + drawY * GRID + 4,
|
||||
gameRect.left + (drawX + 1) * GRID - 4,
|
||||
gameRect.top + (drawY + 1) * GRID - 4);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SelectObject(hdc, oldBrush);
|
||||
SelectObject(hdc, oldPen);
|
||||
DeleteObject(targetPen);
|
||||
}
|
||||
|
||||
// 绘制当前活动方块
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
for (int j = 0; j < 4; j++)
|
||||
{
|
||||
if (bricks[type][state][i][j] != 0)
|
||||
{
|
||||
int drawY = point.y + i;
|
||||
int drawX = point.x + j;
|
||||
|
||||
if (drawY >= 0 && drawY < nGameHeight && drawX >= 0 && drawX < nGameWidth)
|
||||
{
|
||||
RECT brickRect =
|
||||
{
|
||||
gameRect.left + drawX * GRID + 1,
|
||||
gameRect.top + drawY * GRID + 1,
|
||||
gameRect.left + (drawX + 1) * GRID - 1,
|
||||
gameRect.top + (drawY + 1) * GRID - 1
|
||||
};
|
||||
|
||||
HBRUSH brickBrush = CreateSolidBrush(BrickColor[type]);
|
||||
FillRect(hdc, &brickRect, brickBrush);
|
||||
DeleteObject(brickBrush);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 绘制右侧信息面板
|
||||
SetBkMode(hdc, TRANSPARENT);
|
||||
SetTextColor(hdc, RGB(40, 40, 40));
|
||||
|
||||
RECT infoRect =
|
||||
{
|
||||
gameRect.right + GRID,
|
||||
gameRect.top,
|
||||
clientRect.right - GRID,
|
||||
gameRect.bottom
|
||||
};
|
||||
|
||||
DrawText(hdc, _T("Tetris"), -1, &infoRect, DT_TOP | DT_LEFT | DT_SINGLELINE);
|
||||
|
||||
TCHAR scoreText[64];
|
||||
_stprintf_s(scoreText, _T("Score: %d"), tScore);
|
||||
TextOut(hdc, infoRect.left, infoRect.top + GRID * 2, scoreText, lstrlen(scoreText));
|
||||
|
||||
TextOut(hdc, infoRect.left, infoRect.top + GRID * 4, _T("Next:"), 5);
|
||||
|
||||
RECT nextRect =
|
||||
{
|
||||
infoRect.left,
|
||||
infoRect.top + GRID * 5,
|
||||
infoRect.left + GRID * 4,
|
||||
infoRect.top + GRID * 9
|
||||
};
|
||||
|
||||
HBRUSH nextBackBrush = CreateSolidBrush(RGB(220, 220, 220));
|
||||
FillRect(hdc, &nextRect, nextBackBrush);
|
||||
DeleteObject(nextBackBrush);
|
||||
|
||||
HPEN nextBorderPen = CreatePen(PS_SOLID, 1, RGB(120, 120, 120));
|
||||
oldPen = (HPEN)SelectObject(hdc, nextBorderPen);
|
||||
oldBrush = (HBRUSH)SelectObject(hdc, GetStockObject(NULL_BRUSH));
|
||||
Rectangle(hdc, nextRect.left, nextRect.top, nextRect.right, nextRect.bottom);
|
||||
SelectObject(hdc, oldBrush);
|
||||
SelectObject(hdc, oldPen);
|
||||
DeleteObject(nextBorderPen);
|
||||
|
||||
// 绘制下一方块预览
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
for (int j = 0; j < 4; j++)
|
||||
{
|
||||
if (bricks[nType][0][i][j] != 0)
|
||||
{
|
||||
RECT brickRect =
|
||||
{
|
||||
nextRect.left + j * GRID,
|
||||
nextRect.top + i * GRID,
|
||||
nextRect.left + (j + 1) * GRID,
|
||||
nextRect.top + (i + 1) * GRID
|
||||
};
|
||||
|
||||
HBRUSH brickBrush = CreateSolidBrush(BrickColor[nType]);
|
||||
FillRect(hdc, &brickRect, brickBrush);
|
||||
DeleteObject(brickBrush);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TextOut(hdc, infoRect.left, infoRect.top + GRID * 11, _T("Controls:"), 9);
|
||||
TextOut(hdc, infoRect.left, infoRect.top + GRID * 12, _T("Arrow Keys"), 10);
|
||||
TextOut(hdc, infoRect.left, infoRect.top + GRID * 13, _T("Space: Drop"), 11);
|
||||
|
||||
if (suspendFlag)
|
||||
{
|
||||
TextOut(hdc, infoRect.left, infoRect.top + GRID * 15, _T("Paused"), 6);
|
||||
}
|
||||
|
||||
if (gameOverFlag)
|
||||
{
|
||||
RECT overRect = gameRect;
|
||||
SetTextColor(hdc, RGB(255, 80, 80));
|
||||
DrawText(hdc, _T("GAME OVER"), -1, &overRect, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user