添加看视频复活

This commit is contained in:
2026-04-26 14:19:27 +08:00
parent aa3d4d3945
commit 96ab175877
8 changed files with 158 additions and 801 deletions
+106
View File
@@ -1,6 +1,7 @@
#include "stdafx.h"
#include "Tetris.h"
#include <string>
#include <shellapi.h>
#define MAX_LOADSTRING 100
#define GAME_TIMER_ID 1
@@ -16,11 +17,17 @@ bool bgmEnabled = true;
static bool bgmPlaying = false;
static bool bgmUsingMci = false;
static constexpr const wchar_t* kBgmAlias = L"TereisBgm";
static constexpr const wchar_t* kReviveVideoAlias = L"TereisReviveVideo";
ATOM MyRegisterClass(HINSTANCE hInstance);
BOOL InitInstance(HINSTANCE, int);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
INT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM);
static std::wstring BuildAssetPath(const wchar_t* relativePath);
static std::wstring BuildWorkingDirAssetPath(const wchar_t* relativePath);
static bool FileExists(const std::wstring& path);
static void StopBackgroundMusic();
static void StartBackgroundMusic();
static void ResetGameTimer(HWND hWnd)
{
@@ -28,6 +35,90 @@ static void ResetGameTimer(HWND hWnd)
SetTimer(hWnd, GAME_TIMER_ID, currentFallInterval > 0 ? currentFallInterval : GAME_TIMER_INTERVAL, nullptr);
}
static bool PlayReviveVideo(HWND hWnd)
{
std::wstring videoPath = BuildAssetPath(L"assets\\video\\video.avi");
if (!FileExists(videoPath))
{
videoPath = BuildWorkingDirAssetPath(L"assets\\video\\video.avi");
}
if (!FileExists(videoPath))
{
videoPath = BuildAssetPath(L"assets\\video\\video.mp4");
}
if (!FileExists(videoPath))
{
videoPath = BuildWorkingDirAssetPath(L"assets\\video\\video.mp4");
}
if (!FileExists(videoPath))
{
return false;
}
bool shouldResumeBgm = bgmEnabled;
if (bgmPlaying)
{
StopBackgroundMusic();
}
auto tryPlayWithMci = [&](bool forceMpegVideo) -> bool
{
mciSendStringW((std::wstring(L"close ") + kReviveVideoAlias).c_str(), nullptr, 0, nullptr);
std::wstring openCommand = L"open \"" + videoPath + L"\" ";
if (forceMpegVideo)
{
openCommand += L"type mpegvideo ";
}
openCommand += L"alias ";
openCommand += kReviveVideoAlias;
if (mciSendStringW(openCommand.c_str(), nullptr, 0, hWnd) != 0)
{
return false;
}
std::wstring playCommand = std::wstring(L"play ") + kReviveVideoAlias + L" fullscreen wait";
MCIERROR playResult = mciSendStringW(playCommand.c_str(), nullptr, 0, hWnd);
mciSendStringW((std::wstring(L"close ") + kReviveVideoAlias).c_str(), nullptr, 0, nullptr);
return playResult == 0;
};
bool played = tryPlayWithMci(true);
if (!played)
{
played = tryPlayWithMci(false);
}
if (!played)
{
SHELLEXECUTEINFOW shellInfo = {};
shellInfo.cbSize = sizeof(shellInfo);
shellInfo.fMask = SEE_MASK_NOCLOSEPROCESS;
shellInfo.hwnd = hWnd;
shellInfo.lpVerb = L"open";
shellInfo.lpFile = videoPath.c_str();
shellInfo.nShow = SW_SHOWNORMAL;
if (ShellExecuteExW(&shellInfo))
{
if (shellInfo.hProcess != nullptr)
{
WaitForSingleObject(shellInfo.hProcess, INFINITE);
CloseHandle(shellInfo.hProcess);
}
played = true;
}
}
if (shouldResumeBgm)
{
StartBackgroundMusic();
}
return played;
}
static std::wstring BuildAssetPath(const wchar_t* relativePath)
{
wchar_t modulePath[MAX_PATH] = {};
@@ -729,6 +820,21 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
break;
}
if (gameOverFlag && reviveAvailable && wParam == 'V')
{
if (PlayReviveVideo(hWnd))
{
ReviveAfterVideo();
ResetGameTimer(hWnd);
}
else
{
SetFeedbackMessage(_T("视频播放失败"), _T("无法打开复活视频,复活机会未消耗。"), 14);
}
InvalidateRect(hWnd, nullptr, FALSE);
break;
}
if (gameOverFlag || suspendFlag)
{
break;