📄 raiden.cpp
字号:
// Raiden.cpp : 定义应用程序的入口点。
//
#include "stdafx.h"
#include "Raiden.h"
#include "GameEngine.h"
#include "BackGround.h"
#include "MusicPlay.h"
#define MAX_LOADSTRING 100
// 全局变量:
HINSTANCE hInst; // 当前实例
TCHAR szTitle[MAX_LOADSTRING]; // 标题栏文本
TCHAR szWindowClass[MAX_LOADSTRING]; // 主窗口类名
HWND hWnd; // 窗口句柄
HDC g_hOffScreenDC; // 屏幕外设备环境
HBITMAP g_hOffScreenBitmap; // 屏幕外位图
GameEngine *g_pGame = NULL; // 引擎
BackGround *g_pBackGround = NULL; // 背景
MusicPlay *g_pMusic = NULL; // 背景音乐
// 此代码模块中包含的函数的前向声明:
ATOM MyRegisterClass(HINSTANCE hInstance);
BOOL InitInstance(HINSTANCE, int);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK About(HWND, UINT, WPARAM, LPARAM);
BOOL GameInitialize();
void GameStart(HWND hWindow);
void GameEnd();
void GameActivate(HWND hWindow);
void GameDeactivate(HWND hWindow);
void GamePaint(HDC hDC);
void GameCycle();
int APIENTRY _tWinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow)
{
// TODO: 在此放置代码。
MSG msg;
static int iTickTriger = 0;
int iTickCount;
HACCEL hAccelTable;
// 初始化全局字符串
LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
LoadString(hInstance, IDC_RAIDEN, szWindowClass, MAX_LOADSTRING);
MyRegisterClass(hInstance);
g_pGame = new GameEngine();
if (NULL == g_pGame)
return FALSE;
g_pGame->SetFrameRate(50);
g_pGame->Initialize();
// 执行应用程序初始化:
if (!InitInstance (hInstance, nCmdShow))
{
return FALSE;
}
hAccelTable = LoadAccelerators(hInstance, (LPCTSTR)IDC_RAIDEN);
// 主消息循环:
while (TRUE)
{
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
// 处理消息
if (msg.message == WM_QUIT)
break;
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else
{
// 确保游戏引擎没有休眠
if (!g_pGame->GetSleep())
{
// 检查滴答计数, 查看是否过了一个游戏周期
iTickCount = GetTickCount();
if (iTickCount > iTickTriger)
{
iTickTriger = iTickCount + g_pGame->GetFrameDelay();
GameCycle();
}
}
}
}
return (int) msg.wParam;
}
//
// 函数: MyRegisterClass()
//
// 目的: 注册窗口类。
//
// 注释:
//
// 仅当希望在已添加到 Windows 95 的
// “RegisterClassEx”函数之前此代码与 Win32 系统兼容时,
// 才需要此函数及其用法。调用此函数
// 十分重要,这样应用程序就可以获得关联的
// “格式正确的”小图标。
//
ATOM MyRegisterClass(HINSTANCE hInstance)
{
WNDCLASSEX wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = (WNDPROC)WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon(hInstance, (LPCTSTR)IDI_RAIDEN);
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName = (LPCTSTR)IDC_RAIDEN;
wcex.lpszClassName = szWindowClass;
wcex.hIconSm = LoadIcon(wcex.hInstance, (LPCTSTR)IDI_SMALL);
return RegisterClassEx(&wcex);
}
//
// 函数: InitInstance(HANDLE, int)
//
// 目的: 保存实例句柄并创建主窗口
//
// 注释:
//
// 在此函数中,我们在全局变量中保存实例句柄并
// 创建和显示主程序窗口。
//
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
hInst = hInstance; // 将实例句柄存储在全局变量中
// 计算游戏大小计算窗口大小和位置
int iWindowWidth = g_pGame->GetWidth() + GetSystemMetrics(SM_CXFIXEDFRAME) * 2,
iWindowHeight = g_pGame->GetHeight() + GetSystemMetrics(SM_CYFIXEDFRAME) * 2 +
GetSystemMetrics(SM_CYCAPTION);
// 计算菜单高度
iWindowHeight += GetSystemMetrics(SM_CYMENU);
int iXWindowPos = (GetSystemMetrics(SM_CXSCREEN) - iWindowWidth) / 2,
iYWindowPos = (GetSystemMetrics(SM_CYSCREEN) - iWindowHeight) / 2;
hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW |
WS_CAPTION | WS_MINIMIZEBOX,
iXWindowPos, iYWindowPos, iWindowWidth, iWindowHeight,
NULL, NULL, hInstance, NULL);
if (!hWnd)
{
return FALSE;
}
if (GameInitialize() == FALSE)
return FALSE;
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
return TRUE;
}
//
// 函数: WndProc(HWND, unsigned, WORD, LONG)
//
// 目的: 处理主窗口的消息。
//
// WM_COMMAND - 处理应用程序菜单
// WM_PAINT - 绘制主窗口
// WM_DESTROY - 发送退出消息并返回
//
//
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
int wmId, wmEvent;
PAINTSTRUCT ps;
HDC hdc;
switch (message)
{
case WM_CREATE:
// 设置游戏窗口并开始游戏
g_pGame->SetWindow(hWnd);
GameStart(hWnd);
return 0;
case WM_SETFOCUS:
// 激活游戏并更新休眠状态
GameActivate(hWnd);
g_pGame->SetSleep(FALSE);
return 0;
case WM_KILLFOCUS:
// 停用游戏并更新休眠状态
GameDeactivate(hWnd);
g_pGame->SetSleep(TRUE);
return 0;
case WM_PAINT:
{hdc = BeginPaint(hWnd, &ps);
// TODO: 在此添加任意绘图代码...
GamePaint(hdc);
EndPaint(hWnd, &ps);}
return 0;
case WM_DESTROY:
// 结束游戏并推出应用程序
GameEnd();
PostQuitMessage(0);
return 0;
case WM_KEYDOWN:
g_pGame->KeyDown(wParam);
return 0;
case WM_KEYUP:
g_pGame->KeyUp(wParam);
return 0;
case WM_COMMAND:
wmId = LOWORD(wParam);
wmEvent = HIWORD(wParam);
// 分析菜单选择:
switch (wmId)
{
case IDM_ABOUT:
DialogBox(hInst, (LPCTSTR)IDD_ABOUTBOX, hWnd, (DLGPROC)About);
break;
case IDM_EXIT:
DestroyWindow(hWnd);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
// “关于”框的消息处理程序。
LRESULT CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_INITDIALOG:
return TRUE;
case WM_COMMAND:
if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
{
EndDialog(hDlg, LOWORD(wParam));
return TRUE;
}
break;
}
return FALSE;
}
BOOL GameInitialize()
{
srand(GetTickCount());
g_pBackGround = new BackGround(hWnd);
g_pMusic = new MusicPlay();
g_pMusic->Load(".\\Sounds\\flourish.mid");
g_pMusic->Play(-1);
g_pGame->SetFrameRate(30);
// 设置屏幕外缓冲区
g_hOffScreenDC = CreateCompatibleDC(GetDC(hWnd));
g_hOffScreenBitmap = CreateCompatibleBitmap(GetDC(hWnd),
g_pGame->GetWidth(), g_pGame->GetHeight());
SelectObject(g_hOffScreenDC, g_hOffScreenBitmap);
return TRUE;
}
void GameStart(HWND hWindow)
{
}
void GameEnd()
{
SAFE_DELETE(g_pGame);
SAFE_DELETE(g_pBackGround);
SAFE_DELETE(g_pMusic);
ReleaseDC(hWnd, g_hOffScreenDC);
DeleteObject(g_hOffScreenBitmap);
DeleteDC(g_hOffScreenDC);
PostQuitMessage(0);
}
void GameActivate(HWND hWindow)
{}
void GameDeactivate(HWND hWindow)
{}
void GamePaint(HDC hDC)
{
g_pBackGround->Draw(hWnd, hDC);
g_pGame->Draw(hDC);
}
void GameCycle()
{
g_pBackGround->Update();
g_pGame->Update();
HDC hDC = GetDC(hWnd);
if (g_pGame->IsGameOver())
{
Bitmap *pBitmap = new Bitmap(".\\images\\Gameover.bmp", TRUE, RGB(255, 0, 255));
pBitmap->Draw(hDC, (g_pGame->GetWidth() - pBitmap->GetWidth()) / 2,
(g_pGame->GetHeight() - pBitmap->GetHeight()) / 2 - 50,
pBitmap->GetWidth(), pBitmap->GetHeight(), 0, 0);
Sleep(3000);
delete pBitmap;
ReleaseDC(hWnd, hDC);
GameEnd();
return;
}
// 在缓冲区绘制游戏
GamePaint(g_hOffScreenDC);
// 将缓冲区位图送到屏幕
BitBlt(hDC, 0, 0, g_pGame->GetWidth(), g_pGame->GetHeight(),
g_hOffScreenDC, 0, 0, SRCCOPY);
// Cleanup
ReleaseDC(hWnd, hDC);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -