支持界面随窗口尺寸等比缩放
This commit is contained in:
+109
-70
@@ -16,20 +16,59 @@ void TDrawScreen(HDC hdc, HWND hWnd)
|
||||
RECT clientRect;
|
||||
GetClientRect(hWnd, &clientRect);
|
||||
|
||||
int clientWidth = clientRect.right - clientRect.left;
|
||||
int clientHeight = clientRect.bottom - clientRect.top;
|
||||
int scaleX = MulDiv(clientWidth, 1000, WINDOW_CLIENT_WIDTH);
|
||||
int scaleY = MulDiv(clientHeight, 1000, WINDOW_CLIENT_HEIGHT);
|
||||
int scale = (scaleX < scaleY) ? scaleX : scaleY;
|
||||
|
||||
if (scale < 500)
|
||||
{
|
||||
scale = 500;
|
||||
}
|
||||
|
||||
int layoutWidth = MulDiv(WINDOW_CLIENT_WIDTH, scale, 1000);
|
||||
int layoutHeight = MulDiv(WINDOW_CLIENT_HEIGHT, scale, 1000);
|
||||
int offsetX = (clientWidth - layoutWidth) / 2;
|
||||
int offsetY = (clientHeight - layoutHeight) / 2;
|
||||
|
||||
auto SX = [offsetX, scale](int value) -> int
|
||||
{
|
||||
return offsetX + MulDiv(value, scale, 1000);
|
||||
};
|
||||
|
||||
auto SY = [offsetY, scale](int value) -> int
|
||||
{
|
||||
return offsetY + MulDiv(value, scale, 1000);
|
||||
};
|
||||
|
||||
auto SS = [scale](int value) -> int
|
||||
{
|
||||
int result = MulDiv(value, scale, 1000);
|
||||
return result < 1 ? 1 : result;
|
||||
};
|
||||
|
||||
int grid = SS(GRID);
|
||||
int padding = SS(WINDOW_PADDING);
|
||||
int panelGap = SS(SIDE_PANEL_GAP);
|
||||
int panelWidth = SS(SIDE_PANEL_WIDTH);
|
||||
int boardWidth = grid * nGameWidth;
|
||||
int boardHeight = grid * nGameHeight;
|
||||
|
||||
const RECT gameRect =
|
||||
{
|
||||
WINDOW_PADDING,
|
||||
WINDOW_PADDING,
|
||||
WINDOW_PADDING + nGameWidth * GRID,
|
||||
WINDOW_PADDING + nGameHeight * GRID
|
||||
SX(WINDOW_PADDING),
|
||||
SY(WINDOW_PADDING),
|
||||
SX(WINDOW_PADDING) + boardWidth,
|
||||
SY(WINDOW_PADDING) + boardHeight
|
||||
};
|
||||
|
||||
const RECT panelRect =
|
||||
{
|
||||
gameRect.right + SIDE_PANEL_GAP,
|
||||
WINDOW_PADDING,
|
||||
gameRect.right + SIDE_PANEL_GAP + SIDE_PANEL_WIDTH,
|
||||
WINDOW_PADDING + nGameHeight * GRID
|
||||
gameRect.right + panelGap,
|
||||
SY(WINDOW_PADDING),
|
||||
gameRect.right + panelGap + panelWidth,
|
||||
SY(WINDOW_PADDING) + boardHeight
|
||||
};
|
||||
|
||||
const COLORREF pageColor = RGB(255, 244, 248);
|
||||
@@ -64,22 +103,22 @@ void TDrawScreen(HDC hdc, HWND hWnd)
|
||||
|
||||
// 创建中文清晰字体
|
||||
HFONT titleFont = CreateFont(
|
||||
-34, 0, 0, 0, FW_BOLD, FALSE, FALSE, FALSE,
|
||||
-SS(34), 0, 0, 0, FW_BOLD, FALSE, FALSE, FALSE,
|
||||
DEFAULT_CHARSET, OUT_OUTLINE_PRECIS, CLIP_DEFAULT_PRECIS, CLEARTYPE_NATURAL_QUALITY,
|
||||
VARIABLE_PITCH, _T("Microsoft YaHei UI"));
|
||||
|
||||
HFONT sectionFont = CreateFont(
|
||||
-24, 0, 0, 0, FW_BOLD, FALSE, FALSE, FALSE,
|
||||
-SS(24), 0, 0, 0, FW_BOLD, FALSE, FALSE, FALSE,
|
||||
DEFAULT_CHARSET, OUT_OUTLINE_PRECIS, CLIP_DEFAULT_PRECIS, CLEARTYPE_NATURAL_QUALITY,
|
||||
VARIABLE_PITCH, _T("Microsoft YaHei UI"));
|
||||
|
||||
HFONT bodyFont = CreateFont(
|
||||
-20, 0, 0, 0, FW_SEMIBOLD, FALSE, FALSE, FALSE,
|
||||
-SS(20), 0, 0, 0, FW_SEMIBOLD, FALSE, FALSE, FALSE,
|
||||
DEFAULT_CHARSET, OUT_OUTLINE_PRECIS, CLIP_DEFAULT_PRECIS, CLEARTYPE_NATURAL_QUALITY,
|
||||
VARIABLE_PITCH, _T("Microsoft YaHei UI"));
|
||||
|
||||
HFONT smallFont = CreateFont(
|
||||
-17, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE,
|
||||
-SS(17), 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE,
|
||||
DEFAULT_CHARSET, OUT_OUTLINE_PRECIS, CLIP_DEFAULT_PRECIS, CLEARTYPE_NATURAL_QUALITY,
|
||||
VARIABLE_PITCH, _T("Microsoft YaHei UI"));
|
||||
|
||||
@@ -92,9 +131,9 @@ void TDrawScreen(HDC hdc, HWND hWnd)
|
||||
HBRUSH panelBrush = CreateSolidBrush(cardColor);
|
||||
oldPen = (HPEN)SelectObject(hdc, framePen);
|
||||
oldBrush = (HBRUSH)SelectObject(hdc, gameCardBrush);
|
||||
RoundRect(hdc, gameRect.left - 10, gameRect.top - 10, gameRect.right + 10, gameRect.bottom + 10, 28, 28);
|
||||
RoundRect(hdc, gameRect.left - SS(10), gameRect.top - SS(10), gameRect.right + SS(10), gameRect.bottom + SS(10), SS(28), SS(28));
|
||||
SelectObject(hdc, panelBrush);
|
||||
RoundRect(hdc, panelRect.left, panelRect.top, panelRect.right, panelRect.bottom, 30, 30);
|
||||
RoundRect(hdc, panelRect.left, panelRect.top, panelRect.right, panelRect.bottom, SS(30), SS(30));
|
||||
SelectObject(hdc, oldBrush);
|
||||
SelectObject(hdc, oldPen);
|
||||
DeleteObject(gameCardBrush);
|
||||
@@ -108,10 +147,10 @@ void TDrawScreen(HDC hdc, HWND hWnd)
|
||||
|
||||
RECT innerRect =
|
||||
{
|
||||
gameRect.left + 6,
|
||||
gameRect.top + 6,
|
||||
gameRect.right - 6,
|
||||
gameRect.bottom - 6
|
||||
gameRect.left + SS(6),
|
||||
gameRect.top + SS(6),
|
||||
gameRect.right - SS(6),
|
||||
gameRect.bottom - SS(6)
|
||||
};
|
||||
|
||||
HBRUSH innerBrush = CreateSolidBrush(boardInnerColor);
|
||||
@@ -119,10 +158,10 @@ void TDrawScreen(HDC hdc, HWND hWnd)
|
||||
DeleteObject(innerBrush);
|
||||
|
||||
// 绘制游戏区边框
|
||||
HPEN borderPen = CreatePen(PS_SOLID, 2, RGB(132, 108, 146));
|
||||
HPEN borderPen = CreatePen(PS_SOLID, SS(2), RGB(132, 108, 146));
|
||||
oldPen = (HPEN)SelectObject(hdc, borderPen);
|
||||
oldBrush = (HBRUSH)SelectObject(hdc, GetStockObject(NULL_BRUSH));
|
||||
RoundRect(hdc, gameRect.left, gameRect.top, gameRect.right, gameRect.bottom, 18, 18);
|
||||
RoundRect(hdc, gameRect.left, gameRect.top, gameRect.right, gameRect.bottom, SS(18), SS(18));
|
||||
SelectObject(hdc, oldBrush);
|
||||
SelectObject(hdc, oldPen);
|
||||
DeleteObject(borderPen);
|
||||
@@ -133,14 +172,14 @@ void TDrawScreen(HDC hdc, HWND hWnd)
|
||||
|
||||
for (int i = 1; i < nGameWidth; i++)
|
||||
{
|
||||
int x = gameRect.left + i * GRID;
|
||||
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;
|
||||
int y = gameRect.top + i * grid;
|
||||
MoveToEx(hdc, gameRect.left, y, nullptr);
|
||||
LineTo(hdc, gameRect.right, y);
|
||||
}
|
||||
@@ -158,17 +197,17 @@ void TDrawScreen(HDC hdc, HWND hWnd)
|
||||
int colorIndex = workRegion[i][j] - 1;
|
||||
RECT brickRect =
|
||||
{
|
||||
gameRect.left + j * GRID + 2,
|
||||
gameRect.top + i * GRID + 2,
|
||||
gameRect.left + (j + 1) * GRID - 2,
|
||||
gameRect.top + (i + 1) * GRID - 2
|
||||
gameRect.left + j * grid + SS(2),
|
||||
gameRect.top + i * grid + SS(2),
|
||||
gameRect.left + (j + 1) * grid - SS(2),
|
||||
gameRect.top + (i + 1) * grid - SS(2)
|
||||
};
|
||||
|
||||
HBRUSH brickBrush = CreateSolidBrush(BrickColor[colorIndex]);
|
||||
HPEN brickPen = CreatePen(PS_SOLID, 1, RGB(255, 248, 250));
|
||||
oldPen = (HPEN)SelectObject(hdc, brickPen);
|
||||
oldBrush = (HBRUSH)SelectObject(hdc, brickBrush);
|
||||
RoundRect(hdc, brickRect.left, brickRect.top, brickRect.right, brickRect.bottom, 10, 10);
|
||||
RoundRect(hdc, brickRect.left, brickRect.top, brickRect.right, brickRect.bottom, SS(10), SS(10));
|
||||
SelectObject(hdc, oldBrush);
|
||||
SelectObject(hdc, oldPen);
|
||||
DeleteObject(brickBrush);
|
||||
@@ -180,7 +219,7 @@ void TDrawScreen(HDC hdc, HWND hWnd)
|
||||
// 绘制预测落点
|
||||
if (targetFlag)
|
||||
{
|
||||
HPEN targetPen = CreatePen(PS_DOT, 2, RGB(255, 240, 245));
|
||||
HPEN targetPen = CreatePen(PS_DOT, SS(2), RGB(255, 240, 245));
|
||||
oldPen = (HPEN)SelectObject(hdc, targetPen);
|
||||
oldBrush = (HBRUSH)SelectObject(hdc, GetStockObject(NULL_BRUSH));
|
||||
|
||||
@@ -197,11 +236,11 @@ void TDrawScreen(HDC hdc, HWND hWnd)
|
||||
{
|
||||
RoundRect(
|
||||
hdc,
|
||||
gameRect.left + drawX * GRID + 5,
|
||||
gameRect.top + drawY * GRID + 5,
|
||||
gameRect.left + (drawX + 1) * GRID - 5,
|
||||
gameRect.top + (drawY + 1) * GRID - 5,
|
||||
8, 8);
|
||||
gameRect.left + drawX * grid + SS(5),
|
||||
gameRect.top + drawY * grid + SS(5),
|
||||
gameRect.left + (drawX + 1) * grid - SS(5),
|
||||
gameRect.top + (drawY + 1) * grid - SS(5),
|
||||
SS(8), SS(8));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -226,17 +265,17 @@ void TDrawScreen(HDC hdc, HWND hWnd)
|
||||
{
|
||||
RECT brickRect =
|
||||
{
|
||||
gameRect.left + drawX * GRID + 2,
|
||||
gameRect.top + drawY * GRID + 2,
|
||||
gameRect.left + (drawX + 1) * GRID - 2,
|
||||
gameRect.top + (drawY + 1) * GRID - 2
|
||||
gameRect.left + drawX * grid + SS(2),
|
||||
gameRect.top + drawY * grid + SS(2),
|
||||
gameRect.left + (drawX + 1) * grid - SS(2),
|
||||
gameRect.top + (drawY + 1) * grid - SS(2)
|
||||
};
|
||||
|
||||
HBRUSH brickBrush = CreateSolidBrush(BrickColor[type]);
|
||||
HPEN brickPen = CreatePen(PS_SOLID, 1, RGB(255, 250, 252));
|
||||
oldPen = (HPEN)SelectObject(hdc, brickPen);
|
||||
oldBrush = (HBRUSH)SelectObject(hdc, brickBrush);
|
||||
RoundRect(hdc, brickRect.left, brickRect.top, brickRect.right, brickRect.bottom, 12, 12);
|
||||
RoundRect(hdc, brickRect.left, brickRect.top, brickRect.right, brickRect.bottom, SS(12), SS(12));
|
||||
SelectObject(hdc, oldBrush);
|
||||
SelectObject(hdc, oldPen);
|
||||
DeleteObject(brickBrush);
|
||||
@@ -249,12 +288,12 @@ void TDrawScreen(HDC hdc, HWND hWnd)
|
||||
// 绘制右侧信息面板
|
||||
HFONT oldFont = (HFONT)SelectObject(hdc, titleFont);
|
||||
SetTextColor(hdc, titleColor);
|
||||
TextOut(hdc, panelRect.left + 24, panelRect.top + 22, _T("俄罗斯方块"), lstrlen(_T("俄罗斯方块")));
|
||||
TextOut(hdc, panelRect.left + SS(24), panelRect.top + SS(22), _T("俄罗斯方块"), lstrlen(_T("俄罗斯方块")));
|
||||
|
||||
HPEN accentPen = CreatePen(PS_SOLID, 3, accentColor);
|
||||
HPEN accentPen = CreatePen(PS_SOLID, SS(3), accentColor);
|
||||
oldPen = (HPEN)SelectObject(hdc, accentPen);
|
||||
MoveToEx(hdc, panelRect.left + 24, panelRect.top + 68, nullptr);
|
||||
LineTo(hdc, panelRect.left + 160, panelRect.top + 68);
|
||||
MoveToEx(hdc, panelRect.left + SS(24), panelRect.top + SS(68), nullptr);
|
||||
LineTo(hdc, panelRect.left + SS(160), panelRect.top + SS(68));
|
||||
SelectObject(hdc, oldPen);
|
||||
DeleteObject(accentPen);
|
||||
|
||||
@@ -263,23 +302,23 @@ void TDrawScreen(HDC hdc, HWND hWnd)
|
||||
|
||||
TCHAR scoreText[64];
|
||||
_stprintf_s(scoreText, _T("当前得分 %d"), tScore);
|
||||
TextOut(hdc, panelRect.left + 24, panelRect.top + 104, scoreText, lstrlen(scoreText));
|
||||
TextOut(hdc, panelRect.left + SS(24), panelRect.top + SS(104), scoreText, lstrlen(scoreText));
|
||||
|
||||
TextOut(hdc, panelRect.left + 24, panelRect.top + 172, _T("下一个方块"), lstrlen(_T("下一个方块")));
|
||||
TextOut(hdc, panelRect.left + SS(24), panelRect.top + SS(172), _T("下一个方块"), lstrlen(_T("下一个方块")));
|
||||
|
||||
RECT nextCard =
|
||||
{
|
||||
panelRect.left + 24,
|
||||
panelRect.top + 210,
|
||||
panelRect.left + 24 + GRID * 4 + 32,
|
||||
panelRect.top + 210 + GRID * 4 + 32
|
||||
panelRect.left + SS(24),
|
||||
panelRect.top + SS(210),
|
||||
panelRect.left + SS(24) + grid * 4 + SS(32),
|
||||
panelRect.top + SS(210) + grid * 4 + SS(32)
|
||||
};
|
||||
|
||||
HBRUSH nextCardBrush = CreateSolidBrush(RGB(255, 238, 244));
|
||||
HPEN nextCardPen = CreatePen(PS_SOLID, 1, RGB(233, 191, 208));
|
||||
oldPen = (HPEN)SelectObject(hdc, nextCardPen);
|
||||
oldBrush = (HBRUSH)SelectObject(hdc, nextCardBrush);
|
||||
RoundRect(hdc, nextCard.left, nextCard.top, nextCard.right, nextCard.bottom, 22, 22);
|
||||
RoundRect(hdc, nextCard.left, nextCard.top, nextCard.right, nextCard.bottom, SS(22), SS(22));
|
||||
SelectObject(hdc, oldBrush);
|
||||
SelectObject(hdc, oldPen);
|
||||
DeleteObject(nextCardBrush);
|
||||
@@ -294,17 +333,17 @@ void TDrawScreen(HDC hdc, HWND hWnd)
|
||||
{
|
||||
RECT brickRect =
|
||||
{
|
||||
nextCard.left + 16 + j * GRID,
|
||||
nextCard.top + 16 + i * GRID,
|
||||
nextCard.left + 16 + (j + 1) * GRID - 2,
|
||||
nextCard.top + 16 + (i + 1) * GRID - 2
|
||||
nextCard.left + SS(16) + j * grid,
|
||||
nextCard.top + SS(16) + i * grid,
|
||||
nextCard.left + SS(16) + (j + 1) * grid - SS(2),
|
||||
nextCard.top + SS(16) + (i + 1) * grid - SS(2)
|
||||
};
|
||||
|
||||
HBRUSH brickBrush = CreateSolidBrush(BrickColor[nType]);
|
||||
HPEN brickPen = CreatePen(PS_SOLID, 1, RGB(255, 248, 250));
|
||||
oldPen = (HPEN)SelectObject(hdc, brickPen);
|
||||
oldBrush = (HBRUSH)SelectObject(hdc, brickBrush);
|
||||
RoundRect(hdc, brickRect.left, brickRect.top, brickRect.right, brickRect.bottom, 10, 10);
|
||||
RoundRect(hdc, brickRect.left, brickRect.top, brickRect.right, brickRect.bottom, SS(10), SS(10));
|
||||
SelectObject(hdc, oldBrush);
|
||||
SelectObject(hdc, oldPen);
|
||||
DeleteObject(brickBrush);
|
||||
@@ -314,29 +353,29 @@ void TDrawScreen(HDC hdc, HWND hWnd)
|
||||
}
|
||||
|
||||
SelectObject(hdc, sectionFont);
|
||||
TextOut(hdc, panelRect.left + 24, panelRect.top + 390, _T("操作提示"), lstrlen(_T("操作提示")));
|
||||
TextOut(hdc, panelRect.left + SS(24), panelRect.top + SS(390), _T("操作提示"), lstrlen(_T("操作提示")));
|
||||
|
||||
SelectObject(hdc, bodyFont);
|
||||
TextOut(hdc, panelRect.left + 24, panelRect.top + 432, _T("方向键 / WASD:移动 / 旋转"), lstrlen(_T("方向键 / WASD:移动 / 旋转")));
|
||||
TextOut(hdc, panelRect.left + 24, panelRect.top + 468, _T("空格:快速下落"), lstrlen(_T("空格:快速下落")));
|
||||
TextOut(hdc, panelRect.left + 24, panelRect.top + 504, _T("P:暂停 R:重新开始"), lstrlen(_T("P:暂停 R:重新开始")));
|
||||
TextOut(hdc, panelRect.left + 24, panelRect.top + 540, _T("G:显示 / 隐藏落点"), lstrlen(_T("G:显示 / 隐藏落点")));
|
||||
TextOut(hdc, panelRect.left + SS(24), panelRect.top + SS(432), _T("方向键 / WASD:移动 / 旋转"), lstrlen(_T("方向键 / WASD:移动 / 旋转")));
|
||||
TextOut(hdc, panelRect.left + SS(24), panelRect.top + SS(468), _T("空格:快速下落"), lstrlen(_T("空格:快速下落")));
|
||||
TextOut(hdc, panelRect.left + SS(24), panelRect.top + SS(504), _T("P:暂停 R:重新开始"), lstrlen(_T("P:暂停 R:重新开始")));
|
||||
TextOut(hdc, panelRect.left + SS(24), panelRect.top + SS(540), _T("G:显示 / 隐藏落点"), lstrlen(_T("G:显示 / 隐藏落点")));
|
||||
|
||||
if (suspendFlag || gameOverFlag)
|
||||
{
|
||||
RECT overlayRect =
|
||||
{
|
||||
gameRect.left + GRID,
|
||||
gameRect.top + GRID * 6,
|
||||
gameRect.right - GRID,
|
||||
gameRect.top + GRID * 13
|
||||
gameRect.left + grid,
|
||||
gameRect.top + grid * 6,
|
||||
gameRect.right - grid,
|
||||
gameRect.top + grid * 13
|
||||
};
|
||||
|
||||
HBRUSH overlayBrush = CreateSolidBrush(RGB(255, 241, 246));
|
||||
HPEN overlayPen = CreatePen(PS_SOLID, 2, RGB(232, 170, 194));
|
||||
oldPen = (HPEN)SelectObject(hdc, overlayPen);
|
||||
oldBrush = (HBRUSH)SelectObject(hdc, overlayBrush);
|
||||
RoundRect(hdc, overlayRect.left, overlayRect.top, overlayRect.right, overlayRect.bottom, 26, 26);
|
||||
RoundRect(hdc, overlayRect.left, overlayRect.top, overlayRect.right, overlayRect.bottom, SS(26), SS(26));
|
||||
SelectObject(hdc, oldBrush);
|
||||
SelectObject(hdc, oldPen);
|
||||
DeleteObject(overlayBrush);
|
||||
@@ -345,17 +384,17 @@ void TDrawScreen(HDC hdc, HWND hWnd)
|
||||
RECT titleRect =
|
||||
{
|
||||
overlayRect.left,
|
||||
overlayRect.top + GRID,
|
||||
overlayRect.top + grid,
|
||||
overlayRect.right,
|
||||
overlayRect.top + GRID * 3
|
||||
overlayRect.top + grid * 3
|
||||
};
|
||||
|
||||
RECT tipRect =
|
||||
{
|
||||
overlayRect.left + 20,
|
||||
overlayRect.top + GRID * 3,
|
||||
overlayRect.right - 20,
|
||||
overlayRect.bottom - GRID
|
||||
overlayRect.left + SS(20),
|
||||
overlayRect.top + grid * 3,
|
||||
overlayRect.right - SS(20),
|
||||
overlayRect.bottom - grid
|
||||
};
|
||||
|
||||
SetTextColor(hdc, RGB(121, 76, 99));
|
||||
|
||||
Reference in New Issue
Block a user