添加致谢页

This commit is contained in:
2026-04-27 16:46:23 +08:00
parent 7c747ac9fd
commit b01d48a88d
8 changed files with 516 additions and 18 deletions
+117 -4
View File
@@ -6,8 +6,11 @@
#define MAX_LOADSTRING 100
#define GAME_TIMER_ID 1
#define EFFECT_TIMER_ID 2
#define CREDIT_TIMER_ID 3
#define WM_CREDIT_TICK (WM_APP + 1)
#define GAME_TIMER_INTERVAL 500
#define EFFECT_TIMER_INTERVAL 16
#define CREDIT_TIMER_INTERVAL 5
HINSTANCE hInst;
TCHAR szTitle[MAX_LOADSTRING];
@@ -16,6 +19,7 @@ bool bgmEnabled = true;
static bool bgmPlaying = false;
static bool bgmUsingMci = false;
static MMRESULT creditTimerHandle = 0;
static constexpr const wchar_t* kBgmAlias = L"TereisBgm";
static constexpr const wchar_t* kReviveVideoAlias = L"TereisReviveVideo";
@@ -29,6 +33,18 @@ static bool FileExists(const std::wstring& path);
static void StopBackgroundMusic();
static void StartBackgroundMusic();
/**
* @brief 多媒体定时器回调,用于高频率请求致谢页动画刷新。
*/
static void CALLBACK CreditTimerCallback(UINT, UINT, DWORD_PTR userData, DWORD_PTR, DWORD_PTR)
{
HWND hWnd = reinterpret_cast<HWND>(userData);
if (hWnd != nullptr)
{
PostMessage(hWnd, WM_CREDIT_TICK, 0, 0);
}
}
/**
* @brief 将指定滚动偏移按步长调整,并限制在非负范围内。
*/
@@ -195,6 +211,29 @@ static RECT GetHelpBackHintRect(HWND hWnd)
return rect;
}
/**
* @brief 获取致谢页左右切换按钮的绘制和点击区域。
*/
static RECT GetCreditArrowRect(HWND hWnd, int direction)
{
LayoutMetrics metrics = GetLayoutMetrics(hWnd);
RECT rulesCard = GetRulesCardRect(hWnd);
int size = ScaleValue(metrics, 54);
int centerY = (rulesCard.top + rulesCard.bottom) / 2;
int left = direction < 0
? rulesCard.left + ScaleValue(metrics, 52)
: rulesCard.right - ScaleValue(metrics, 52) - size;
RECT rect =
{
left,
centerY - size / 2,
left + size,
centerY + size / 2
};
return rect;
}
static RECT GetUpgradeOverlayRect(HWND hWnd)
{
LayoutMetrics metrics = GetLayoutMetrics(hWnd);
@@ -681,11 +720,22 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
switch (message)
{
case WM_CREATE:
timeBeginPeriod(1);
srand((unsigned int)time(nullptr));
ReturnToMainMenu();
StartBackgroundMusic();
ResetGameTimer(hWnd);
SetTimer(hWnd, EFFECT_TIMER_ID, EFFECT_TIMER_INTERVAL, nullptr);
creditTimerHandle = timeSetEvent(
CREDIT_TIMER_INTERVAL,
1,
CreditTimerCallback,
reinterpret_cast<DWORD_PTR>(hWnd),
TIME_PERIODIC | TIME_CALLBACK_FUNCTION);
if (creditTimerHandle == 0)
{
SetTimer(hWnd, CREDIT_TIMER_ID, CREDIT_TIMER_INTERVAL, nullptr);
}
InvalidateRect(hWnd, nullptr, FALSE);
break;
case WM_COMMAND:
@@ -705,6 +755,12 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
}
}
break;
case WM_CREDIT_TICK:
if (currentScreen == SCREEN_RULES && helpState.currentPage == 4 && TickCreditAnimation())
{
InvalidateRect(hWnd, nullptr, FALSE);
}
break;
case WM_TIMER:
if (wParam == EFFECT_TIMER_ID)
{
@@ -714,6 +770,14 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
}
break;
}
if (wParam == CREDIT_TIMER_ID && creditTimerHandle == 0)
{
if (currentScreen == SCREEN_RULES && helpState.currentPage == 4 && TickCreditAnimation())
{
InvalidateRect(hWnd, nullptr, FALSE);
}
break;
}
if (wParam == GAME_TIMER_ID)
{
@@ -902,10 +966,14 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
StartGameWithMode(MODE_ROGUE);
}
else
else if (i == 2)
{
OpenRulesScreen();
}
else
{
OpenCreditScreen();
}
ResetGameTimer(hWnd);
InvalidateRect(hWnd, nullptr, FALSE);
break;
@@ -936,8 +1004,25 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
}
else if (IsPointInRect(GetHelpBackHintRect(hWnd), mouseX, mouseY))
{
helpState.currentPage = 0;
helpScrollOffset = 0;
if (helpState.currentPage == 4)
{
ReturnToMainMenu();
}
else
{
helpState.currentPage = 0;
helpScrollOffset = 0;
}
InvalidateRect(hWnd, nullptr, FALSE);
}
else if (helpState.currentPage == 4 && IsPointInRect(GetCreditArrowRect(hWnd, -1), mouseX, mouseY))
{
ChangeCreditPage(-1);
InvalidateRect(hWnd, nullptr, FALSE);
}
else if (helpState.currentPage == 4 && IsPointInRect(GetCreditArrowRect(hWnd, 1), mouseX, mouseY))
{
ChangeCreditPage(1);
InvalidateRect(hWnd, nullptr, FALSE);
}
break;
@@ -1108,10 +1193,14 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
StartGameWithMode(MODE_ROGUE);
}
else
else if (menuState.selectedIndex == 2)
{
OpenRulesScreen();
}
else
{
OpenCreditScreen();
}
ResetGameTimer(hWnd);
InvalidateRect(hWnd, nullptr, FALSE);
break;
@@ -1141,6 +1230,11 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
}
InvalidateRect(hWnd, nullptr, FALSE);
}
else if (helpState.currentPage == 4)
{
ChangeCreditPage(-1);
InvalidateRect(hWnd, nullptr, FALSE);
}
break;
case VK_DOWN:
case VK_RIGHT:
@@ -1155,6 +1249,11 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
}
InvalidateRect(hWnd, nullptr, FALSE);
}
else if (helpState.currentPage == 4)
{
ChangeCreditPage(1);
InvalidateRect(hWnd, nullptr, FALSE);
}
break;
case VK_RETURN:
case VK_SPACE:
@@ -1172,6 +1271,10 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
ReturnToMainMenu();
}
else if (helpState.currentPage == 4)
{
ReturnToMainMenu();
}
else
{
helpState.currentPage = 0;
@@ -1454,7 +1557,17 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
case WM_DESTROY:
KillTimer(hWnd, GAME_TIMER_ID);
KillTimer(hWnd, EFFECT_TIMER_ID);
if (creditTimerHandle != 0)
{
timeKillEvent(creditTimerHandle);
creditTimerHandle = 0;
}
else
{
KillTimer(hWnd, CREDIT_TIMER_ID);
}
StopBackgroundMusic();
timeEndPeriod(1);
PostQuitMessage(0);
break;
default: