From e8bbf609fd80d8234a56e4eb5aeb32b9d412e581 Mon Sep 17 00:00:00 2001 From: Qi-huanye <2728290997@qq.com> Date: Fri, 24 Apr 2026 11:08:38 +0800 Subject: [PATCH] =?UTF-8?q?=E6=94=AF=E6=8C=81=E7=95=8C=E9=9D=A2=E9=9A=8F?= =?UTF-8?q?=E7=AA=97=E5=8F=A3=E5=B0=BA=E5=AF=B8=E7=AD=89=E6=AF=94=E7=BC=A9?= =?UTF-8?q?=E6=94=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- image.png | Bin 22334 -> 8427 bytes src/source/Tetris.cpp | 3 + src/source/TetrisRender.cpp | 179 ++++++++++++++++++++++-------------- 3 files changed, 112 insertions(+), 70 deletions(-) diff --git a/image.png b/image.png index e0526fb91a40e4559f1eec6e0317e0c4a4f85bb3..545a4b1afc6b7c46da5c05f6f1c9957b3ead714c 100644 GIT binary patch literal 8427 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 VUc_24;CUXc{l{{gl9><|C| diff --git a/src/source/Tetris.cpp b/src/source/Tetris.cpp index ed79fbe..63bf6aa 100644 --- a/src/source/Tetris.cpp +++ b/src/source/Tetris.cpp @@ -200,6 +200,9 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) InvalidateRect(hWnd, nullptr, FALSE); } break; + case WM_SIZE: + InvalidateRect(hWnd, nullptr, FALSE); + break; case WM_KEYDOWN: if (wParam == 'R') { diff --git a/src/source/TetrisRender.cpp b/src/source/TetrisRender.cpp index 7f05468..07a35f0 100644 --- a/src/source/TetrisRender.cpp +++ b/src/source/TetrisRender.cpp @@ -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));