基于Visual Studio开发的数位飞机大战小游戏设计

目录

  1. 游戏介绍 1
  2. 游戏流程 1
  3. 界面设计 2
  4. 概要设计 2
    4.1 系统架构 2
    4.2 核心代码流程 2
  5. 总结与感悟 3
  6. 参考资料 3
    4.2核心代码流程
    游戏逻辑的主要部分,核心代码之所在,Run_Timer函数的流程如下所示。
    流程开始:由WinProc调用。
    S0:更新计时器全局变量。
    S1:遍历所有敌机,调用HitHero判断是否与我机相撞(如相撞,标记敌机)。
    S2:遍历所有子弹和所有飞机,调用Hit判断是否击中(如击中,标记子弹和飞机)。
    S3:遍历所有道具,调用GetToy判断是否被我机拾获(如拾获,标记道具,产生道具效果,设置相应全局变量)。
    S4:判断当前分数和关卡,如果需要,升级关卡。
    S5:判断计时器全局变量的值,如符合频率要求,创建一架新敌机。
    S6:遍历所有敌机,产生位移。
    S7:判断计时器全局变量的值,如符合频率要求,以一定概率随机使敌机产生新的子弹。
    S8:遍历所有敌机,若飞出屏幕,调用DestroyPlane清除。
    S9:遍历所有子弹,产生位移。
    S10:遍历所有道具,产生位移。
    S11:判断计时器全局变量的值,如符合频率要求,使我机产生新的子弹。根据全局变量记录的道具信息产生不同子弹,更新道具冷却时间全局变量。
    S12:加分。
    S13:清除无效的飞机。遍历所有敌机,若发现被标记,调用DestroyPlane清除之。在大飞机被清除时产生道具,在Hero快没血的时候以更大的概率产生 toyBLD。
    S14:清除无效的子弹。遍历所有子弹,若发现被标记,调用DestoryBullet清除之。
    S15:清除无效的道具。遍历所有道具,若发现被标记,调用DestoryToy清除之。
    S16:动画进帧。
    流程结束,控制流交还WinProc以绘图。
#include "DigitPlane.h"

int WINAPI WinMain(HINSTANCE hInstance,
	HINSTANCE hPrevInstance,
	LPSTR lpCmdLine,
	int nCmdShow)
{
	WNDCLASSEX wcex;
	HWND hWnd;
	MSG msg;

	wcex.cbSize = sizeof(WNDCLASSEX);
	wcex.style = CS_HREDRAW | CS_VREDRAW;
	wcex.lpfnWndProc = WndProc;
	wcex.cbClsExtra = 0;
	wcex.cbWndExtra = 0;
	wcex.hInstance = hInstance;
	wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_APP_ICON));
	wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
	wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
	wcex.lpszMenuName = NULL;
	wcex.lpszClassName = szWindowClass;
	wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_APPLICATION));

	if (!RegisterClassEx(&wcex))
	{
		MessageBox(NULL,
			_T("Call to RegisterClassEx failed!"),
			_T("Mega Plane"),
			MB_OK);

		return 1;
	}

	// The parameters to CreateWindow explained:
	// szWindowClass: the name of the application
	// szTitle: the text that appears in the title bar
	// WS_OVERLAPPEDWINDOW: the type of window to create,~WS_THICKFRAME  fixed window size
	// CW_USEDEFAULT, CW_USEDEFAULT: initial position (x, y)
	// WNDWIDTH, WNDHEIGHT: initial size (width, length)
	// NULL: the parent of this window
	// NULL: this application does not have a menu bar
	// hInstance: the first parameter from WinMain
	// NULL: not used in this application
	hWnd = CreateWindow(
		szWindowClass,
		szTitle,
		WS_OVERLAPPEDWINDOW, //& ~WS_THICKFRAME,
		//CW_USEDEFAULT, CW_USEDEFAULT,
		20,20,
		O_WNDWIDTH + WNDWIDTH_PLUS, O_WNDHEIGHT + WNDHEIGHT_PLUS,
		NULL,
		NULL,
		hInstance,
		NULL
		);

	if (!hWnd)
	{
		MessageBox(NULL,
			_T("Call to CreateWindow failed!"),
			_T("Mega Plane"),
			MB_OK);

		return 1;
	}

	// The parameters to ShowWindow explained:
	// hWnd: the value returned from CreateWindow
	// nCmdShow: the fourth parameter from WinMain
	ShowWindow(hWnd,
		nCmdShow);
	UpdateWindow(hWnd);

	// Main message loop:
	while (GetMessage(&msg, NULL, 0, 0))
	{
		TranslateMessage(&msg);
		DispatchMessage(&msg);
	}

	return (int)msg.wParam;
}


LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	PAINTSTRUCT ps;
	HDC hdc;
	BITMAP bmp;
	POINT ptMouse;
	

	int i;

	switch (message)
	{
	case WM_CREATE:
		

		//加载位图资源
		m_hBackgroundBmp = LoadBitmap(((LPCREATESTRUCT)lParam)->hInstance,
			MAKEINTRESOURCE(IDB_BACKGROUND));
		m_hHeroBmp = LoadBitmap(((LPCREATESTRUCT)lParam)->hInstance,
			MAKEINTRESOURCE(IDB_HERO));
		m_hHeroBulletBmp = LoadBitmap(((LPCREATESTRUCT)lParam)->hInstance,
			MAKEINTRESOURCE(IDB_HERO_BULLET));
		for (i = 0; i < ENEMY_TYPE_NUM; i++)
		{
			m_hEnemyBmp[i] = LoadBitmap(((LPCREATESTRUCT)lParam)->hInstance,
				MAKEINTRESOURCE(m_enemyBmpNames[i]));
		}
		m_hGameStatusBmp = LoadBitmap(((LPCREATESTRUCT)lParam)->hInstance,
			MAKEINTRESOURCE(IDB_GAME_STATUS));
		m_hToysBmp = LoadBitmap(((LPCREATESTRUCT)lParam)->hInstance,
			MAKEINTRESOURCE(IDB_TOYS));

		Initialize_Game();
		
		m_gameStatus.isPaused = FALSE;
		m_gameStatus.isStarting = TRUE;


		{
			//位图相关
			GetObject(m_hGameStatusBmp, sizeof(BITMAP), &bmp);
			m_gameStatus.size.cx = bmp.bmWidth;
			m_gameStatus.size.cy = bmp.bmHeight / 2;
			m_gameStatus.hBmp = m_hGameStatusBmp;
		}

		srand((unsigned int)time(NULL));
		timer_i = 0;
		
		//开始背景音乐
		PlaySound(MAKEINTRESOURCE(IDR_WAVE1),GetModuleHandle(NULL),SND_LOOP|SND_ASYNC|SND_RESOURCE);

		break;
	case WM_SIZE:
		cxClient = LOWORD(lParam);
		cyClient = HIWORD(lParam);
		break;
	case WM_PAINT:
		
		hdc = BeginPaint(hWnd, &ps);
		//绘制
		Render(hdc);
		EndPaint(hWnd, &ps);
		break;
	case WM_KEYUP:
		switch (wParam)
		{
		case VK_LEFT:
		case VK_RIGHT:
		case VK_UP:
		case VK_DOWN:
			MOVE_HERO = 0;
			break;
		}
		break;
	case WM_KEYDOWN:
		switch (wParam)
		{
		case VK_LEFT:
		case VK_RIGHT:
		case VK_UP:
		case VK_DOWN:
			MOVE_HERO = wParam;
			break;

		case VK_SPACE:

			if(m_Planes[0].status == 0)
			{
				//Restart_Game
				Initialize_Game();
				
			}
			else
			{
				if(m_gameStatus.isStarting)
				{
					SetTimer(hWnd, TIMER, 50, NULL);
					m_gameStatus.isStarting = FALSE;
					InvalidateRect(hWnd, NULL, FALSE);
				}
				else 
					Pause_Game(hWnd);
			}
			break;
		case 'B':
			m_Toys[Toy_Count] = CreateToy(toyBLD);
			break;
		case 'D':
			m_Toys[Toy_Count] = CreateToy(toyDBL);
			break;
		case 'C':
			m_Toys[Toy_Count] = CreateToy(toyCLS);
			break;
		case 'R':
			m_Toys[Toy_Count] = CreateToy(toyRAD);
			break;
		case 'S':
			m_Toys[Toy_Count] = CreateToy(toySUB);
			break;
		case 'M'://狂躁模式,各种子弹特效全开
			DBLBullet = TRUE;
			RADBullet = TRUE;
			SUBBullet = TRUE;
			break;
		default:
			break;
		}
		break;
	case WM_LBUTTONDOWN:
		ptMouse.x = LOWORD(lParam);
		ptMouse.y = HIWORD(lParam);

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/sheziqiong/article/details/130872881