C++语言学习笔记9:飞机大战

已上传资源:点击此行文字可进行下载<飞机大战>并直接运行。

预准备:游戏壳封装 - 利用多态

父类
//Gameapp.h

#pragma once
#include <windows.h>

class CGameApp {
public:

	HINSTANCE m_hInstance;
	HWND m_hWnd;

public:

	CGameApp() {}
	virtual ~CGameApp() {}

public:

	void SetHandle(HINSTANCE hIns, HWND hWnd) {
		m_hInstance = hIns;
		m_hWnd = hWnd;
	}

public:

	//case WM_CREATE: //窗口创建消息
	virtual void OnCreate() {}

	//case WM_PAINT:  //重绘消息
	virtual void OnPaint() {}

	//case WM_TIMER:   //定时器,需要我们在子类中手动添加定时器并设置触发间隔
	virtual void OnTimer(WPARAM wParam) {}

	//case WM_KEYDOWN:  //键盘按下触发消息
	virtual void OnKeyDown(WPARAM wParam) {}

	//case WM_KEYUP:  //键盘抬起触发消息
	virtual void OnKeyUp(WPARAM wParam) {}

	//case WM_LBUTTONDOWN: //鼠标左键按下触发消息
	virtual void OnLbuttonDown(POINT& po) {}

	//case WM_LBUTTONUP: //鼠标左键抬起触发消息
	virtual void OnLbuttonUp(POINT& po) {}

	//case WM_MOUSEMOVE:  //鼠标移动
	virtual void OnMouseMove(POINT& po) {}

};

CGameApp* Get_Object();


#define GET_OBJECT(CHILD_CLASS)\
	CGameApp* Get_Object() {\
		return new CHILD_CLASS;\
	}

#define CLASS_CONFIG(PARAM_X,PARAM_Y,PARAM_WIDTH,PARAM_HEIGH,PARAM_TITLE)\
	int nx = PARAM_X;\
	int ny = PARAM_Y;\
	int nwidth = PARAM_WIDTH;\
	int nheigh = PARAM_HEIGH;\
	CHAR* strTitle = (CHAR*)PARAM_TITLE;
子类示例
//Class_SonAA.h

#pragma once
#include "Gameapp.h"

class CsonAA:public CGameApp
{
public:
	virtual void OnCreate() {
		int a = 0;
	}
protected:
private:
};
//AA.cpp

#include "Class_sonAA.h"

GET_OBJECT(CsonAA)
CLASS_CONFIG(200,5,400,400,"标题")
WinMain
//WinMain.cpp
//window 应用程序,多字符集

#include <windows.h>
#include <windowsx.h>
#include "Gameapp.h"
#include "Class_sonAA.h"

LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
HINSTANCE hIns = 0;  //全局变量,程序实例句柄

int CALLBACK WinMain(HINSTANCE hInstance, HINSTANCE hPreInstance, LPSTR lpCmdLine, int nShowCmd)
{
	//-----------------------------------------------------
	HWND hwnd = 0;
	MSG msg;       //  装消息的结构体
	WNDCLASSEX wndclass;
	//-----------------------------------------------------

	hIns = hInstance;
	LPCSTR lClassName = "yue";				//窗口类名CN
	extern int nx;							//窗口位置X
	extern int ny;							//窗口位置Y
	extern int nwidth;						//窗口宽度W
	extern int nheigh;						//窗口高度H
	extern CHAR* strTitle;					//窗口标题名T
	int pos_x = nx;
	if (pos_x < 0) {
		pos_x = 0;
	}
	int pos_y = ny;
	if (pos_y < 0) {
		pos_y = 0;
	}
	int nWidth = nwidth;
	if (nWidth <= 0) {
		nWidth = 500;
	}
	int nHeight = nheigh;
	if (nHeight <= 0) {
		nHeight = 500;
	}

	//----------------------创建窗口过程-----------------------------------
	//  1. 设计
	wndclass.cbClsExtra = 0;
	wndclass.cbWndExtra = 0;
	wndclass.cbSize = sizeof(wndclass);
	wndclass.hbrBackground = (HBRUSH)COLOR_WINDOW;
	wndclass.hCursor = LoadCursor(0, MAKEINTRESOURCE(IDC_ARROW));
	wndclass.hIcon = 0;
	wndclass.hIconSm = 0;
	wndclass.hInstance = hInstance;
	wndclass.lpfnWndProc = WindowProc;
	wndclass.lpszClassName = lClassName;
	wndclass.lpszMenuName = 0;
	wndclass.style = CS_HREDRAW | CS_VREDRAW;
	// 2.  注册
	if (RegisterClassEx(&wndclass) == FALSE)
	{
		MessageBox(0, "注册失败", "提示", MB_OK);
		return 0;
	}
	//  3.  创建
	hwnd = CreateWindow(lClassName, strTitle, WS_OVERLAPPEDWINDOW, pos_x, pos_y, nWidth, nHeight, 0, 0, hInstance, 0);
	if (hwnd == 0)
	{
		MessageBox(0, "创建失败", "提示", MB_OK);
		return 0;
	}
	//  4.  显示窗口
	ShowWindow(hwnd, SW_SHOW);
	//---------------------------创建窗口过程-----------------------------------------

	//----------------------------消息循环-------------------------------------------
	while (GetMessage(&msg, 0, 0, 0))
	{
		TranslateMessage(&msg);
		DispatchMessage(&msg);
	}
	//----------------------------消息循环-------------------------------------------

	return 0;
}

CGameApp* pGameAPP = NULL;


LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	switch (uMsg)
	{
	case WM_CREATE: //窗口创建消息
	{
		if (pGameAPP == NULL) 
		{
			pGameAPP = Get_Object();	//获取子类
			pGameAPP->SetHandle(hIns, hwnd);
			pGameAPP->OnCreate();

		}
	}
	break;
	case WM_PAINT:  //重绘消息
	{
		if (pGameAPP)
		{
			pGameAPP->OnPaint();
		}
	}
	break;
	case WM_TIMER:   //定时器,需要我们在子类中手动添加定时器并设置触发间隔
	{
		if (pGameAPP)
		{
			pGameAPP->OnTimer(wParam);
		}
	}
	break;
	case WM_KEYDOWN:  //键盘按下触发消息
	{
		if (pGameAPP)
		{
			pGameAPP->OnKeyDown(wParam);
		}
	}
	break;
	case WM_KEYUP:  //键盘抬起触发消息
	{
		if (pGameAPP)
		{
			pGameAPP->OnKeyUp(wParam);
		}
	}
	break;
	case WM_LBUTTONDOWN: //鼠标左键按下触发消息
	{
		if (pGameAPP)
		{
			POINT po = { 0 };
			po.x = GET_X_LPARAM(lParam);
			po.y = GET_Y_LPARAM(lParam);
			pGameAPP->OnLbuttonDown(po);
		}
	}
	break;
	case WM_LBUTTONUP: //鼠标左键抬起触发消息
	{
		if (pGameAPP)
		{
			POINT po = { 0 };
			po.x = GET_X_LPARAM(lParam);
			po.y = GET_Y_LPARAM(lParam);
			pGameAPP->OnLbuttonUp(po);
		}
	}
	break;
	case WM_MOUSEMOVE:  //鼠标移动
	{
		if (pGameAPP)
		{
			POINT po = { 0 };
			po.x = GET_X_LPARAM(lParam);
			po.y = GET_Y_LPARAM(lParam);
			pGameAPP->OnMouseMove(po);
		}
	}
	break;
	case WM_CLOSE:
	{
		int res = ::MessageBox(NULL, "[WM_CLOSE] 是否确定退出", "提示", MB_OKCANCEL);
		if (res == IDOK) { //点击 【确定】按钮

		}
		else if (res == IDCANCEL) {//点击【取消】按钮,不调用默认的消息处理 DefWindowProc 

			return 0;
		}
		else {
			return 0;
		}
	}
	break;
	case WM_DESTROY:
	{
		//::MessageBox(NULL, "WM_DESTROY", "提示", MB_OK);
		//释放游戏资源

		if (pGameAPP) {
			delete pGameAPP;
			pGameAPP = NULL;
		}

		PostQuitMessage(0);
	}
	break;
	case WM_QUIT:
	{
		::MessageBox(NULL, "WM_QUIT", "提示", MB_OK);
	}
	break;
	}
	return DefWindowProc(hwnd, uMsg, wParam, lParam);

}

飞机大战资源图

敌军小飞机

在这里插入图片描述

炮弹

在这里插入图片描述

玩家飞机

在这里插入图片描述

游戏背景图

在这里插入图片描述

敌军大飞机

在这里插入图片描述

敌军中飞机

在这里插入图片描述

飞机大战程序文件

BackGround
---------------------//BackGround.h//---------------------

#pragma once
#include <windows.h>

class CBackGround
{
public:
	int m_nx;
	int m_ny;
	HBITMAP m_backUp;
	HBITMAP m_backDown;
public:
	CBackGround();
	~CBackGround();
public:
	void InitBackGround(int x, int y, HINSTANCE hIns);
	void ShowBackGround(HDC hdc, HDC compHdc);
	void MoveBackGround(int step);
};
---------------------//BackGround.cpp//---------------------
    
#include "BackGround.h"
#include "../resource.h"
#include "../GameConfig/GameConfig.h"

CBackGround::CBackGround() {
	m_nx = 0;
	m_ny = 0;
	m_backUp = NULL;
	m_backDown = NULL;
}

CBackGround::~CBackGround() {
	m_nx = 0;
	m_ny = 0;
	::DeleteObject(m_backUp);
	::DeleteObject(m_backDown);
}

void CBackGround::InitBackGround(int x, int y, HINSTANCE hIns) {
	m_nx = x;
	m_ny = y;
	m_backUp = ::LoadBitmap(hIns, MAKEINTRESOURCE(IDB_BACKGROUND));
	m_backDown = ::LoadBitmap(hIns, MAKEINTRESOURCE(IDB_BACKGROUND));
}

void CBackGround::ShowBackGround(HDC hdc, HDC compHdc) {
	::SelectObject(compHdc, m_backDown);
	::BitBlt(hdc, m_nx, m_ny, BACKGOUND_MAPSIZE_WIDTH, BACKGOUND_MAPSIZE_HEIGH, compHdc, 0, 0, SRCCOPY);
	::SelectObject(compHdc, m_backUp);
	::BitBlt(hdc, m_nx, m_ny - BACKGOUND_MAPSIZE_HEIGH, BACKGOUND_MAPSIZE_WIDTH, BACKGOUND_MAPSIZE_HEIGH, compHdc, 0, 0, SRCCOPY);
}

void CBackGround::MoveBackGround(int step) {
	if (m_ny + step >= 550) 
	{
		m_ny = 0;
	}
	else {
		m_ny += step;
	}
}
FoePlaneBox
---------------------//FoePlane.h//---------------------

#pragma once
#include <windows.h>
#include "../PlayerPlane/PlayerPlane.h"

class CFoePlane
{
public:
	HBITMAP m_foePlane;
	int m_nx;
	int m_ny;
	int m_nBlood;
	int m_nBoomshowID;
public:
	CFoePlane();
	~CFoePlane();
public:
	virtual void InitFoePlane(HINSTANCE hIns) = 0;
	void MoveFoePlane(int step);
	virtual void ShowFoePlane(HDC hdc, HDC compHdc) = 0;
	virtual bool IsHitGunner(CGunner* pGunner) = 0;
	virtual bool IsHitPlayerPlane(CPlayerPlane& playerPlane) = 0;
};
---------------------//FoePlane.cpp//---------------------
    
#include "FoePlane.h"

CFoePlane::CFoePlane() {
	m_foePlane = NULL;
	m_nx = 0;
	m_ny = 0;
	m_nBlood = 0;
	m_nBoomshowID = 0;
}

CFoePlane::~CFoePlane() {
	::DeleteObject(m_foePlane);
	m_foePlane = NULL;
	m_nx = 0;
	m_ny = 0;
	m_nBlood = 0;
	m_nBoomshowID = 0;
}

void CFoePlane::MoveFoePlane(int step) {
	m_ny += step;
}
---------------------//FoePlaneSmall.h//---------------------
    
#pragma once

#include "FoePlane.h"

class CFoePlaneSmall:public CFoePlane
{
public:
	CFoePlaneSmall();
	~CFoePlaneSmall();
public:
	virtual void InitFoePlane(HINSTANCE hIns);
	virtual void ShowFoePlane(HDC hdc, HDC compHdc);
	virtual bool IsHitGunner(CGunner* pGunner);
	virtual bool IsHitPlayerPlane(CPlayerPlane& playerPlane);
};
---------------------//FoePlaneSmall.cpp//---------------------

#include "FoePlaneSmall.h"
#include "../resource.h"
#include "../GameConfig/GameConfig.h"

CFoePlaneSmall::CFoePlaneSmall() {

}

CFoePlaneSmall::~CFoePlaneSmall() {

}

void CFoePlaneSmall::InitFoePlane(HINSTANCE hIns) {
	m_foePlane = ::LoadBitmap(hIns, MAKEINTRESOURCE(IDB_FOESMALL));
	m_nx = rand() % (BACKGOUND_MAPSIZE_WIDTH - FOEPLANE_SMALL_SIZE_WEIGH + 1);
	m_ny = -FOEPLANE_SMALL_SIZE_HEIGH;
	m_nBlood = FOEPLANE_SMALL_BLOOD;
	m_nBoomshowID = 1;
}

void CFoePlaneSmall::ShowFoePlane(HDC hdc, HDC compHdc) {
	::SelectObject(compHdc, m_foePlane);
	::BitBlt(hdc, m_nx, m_ny, FOEPLANE_SMALL_SIZE_WEIGH, FOEPLANE_SMALL_SIZE_HEIGH, compHdc, 0, (1- m_nBoomshowID)* FOEPLANE_SMALL_SIZE_HEIGH, SRCAND);
}

bool CFoePlaneSmall::IsHitGunner(CGunner* pGunner) {
	int x = (pGunner->m_nx) + GUNNER_SIZE_WIDTH / 2;
	if (m_nx <= x && x <= m_nx + FOEPLANE_SMALL_SIZE_WEIGH && pGunner->m_ny >= m_ny && pGunner->m_ny <= m_ny + FOEPLANE_SMALL_SIZE_HEIGH) {
		return true;
	}
	return false;
}

bool CFoePlaneSmall::IsHitPlayerPlane(CPlayerPlane& playerPlane) {
	int x1 = (playerPlane.m_nx) + PALYERPLANE_SIZE_WIDTH / 2;
	if (m_nx <= x1 && x1 <= m_nx + FOEPLANE_SMALL_SIZE_WEIGH && playerPlane.m_ny >= m_ny && playerPlane.m_ny <= m_ny + FOEPLANE_SMALL_SIZE_HEIGH) {
		return true;
	}
	int y1 = (playerPlane.m_ny) + PALYERPLANE_SIZE_HEIGH * 2 / 3;
	if (m_nx <= playerPlane.m_nx && playerPlane.m_nx <= m_nx + FOEPLANE_SMALL_SIZE_WEIGH && y1 >= m_ny && y1 <= m_ny + FOEPLANE_SMALL_SIZE_HEIGH) {
		return true;
	}

	int x2 = (playerPlane.m_nx) + PALYERPLANE_SIZE_WIDTH;
	int y2 = (playerPlane.m_ny) + PALYERPLANE_SIZE_HEIGH * 2 / 3;
	if (m_nx <= x2 && x2 <= m_nx + FOEPLANE_SMALL_SIZE_WEIGH && y2 >= m_ny && y2 <= m_ny + FOEPLANE_SMALL_SIZE_HEIGH) {
		return true;
	}
	return false;
}
---------------------//FoePlaneMiddle.h//---------------------

#pragma once
#include "FoePlane.h"


class CFoePlaneMid :public CFoePlane
{
public:
	CFoePlaneMid();
	~CFoePlaneMid();
public:
	virtual void InitFoePlane(HINSTANCE hIns);
	virtual void ShowFoePlane(HDC hdc, HDC compHdc);
	virtual bool IsHitGunner(CGunner* pGunner);
	virtual bool IsHitPlayerPlane(CPlayerPlane& playerPlane);
};
---------------------//FoePlaneMiddle.cpp//---------------------

#include "FoePlaneMiddle.h"
#include "../resource.h"
#include "../GameConfig/GameConfig.h"

CFoePlaneMid::CFoePlaneMid() {
}

CFoePlaneMid::~CFoePlaneMid() {
}

void CFoePlaneMid::InitFoePlane(HINSTANCE hIns) {
	m_foePlane = ::LoadBitmap(hIns, MAKEINTRESOURCE(IDB_FOEMIDDLE));
	m_nx = rand() % (BACKGOUND_MAPSIZE_WIDTH - FOEPLANE_MIDDLE_SIZE_WEIGH + 1);
	m_ny = -FOEPLANE_MIDDLE_SIZE_HEIGH;
	m_nBlood = FOEPLANE_MIDDLE_BLOOD;
	m_nBoomshowID = 2;
}

void CFoePlaneMid::ShowFoePlane(HDC hdc, HDC compHdc) {
	::SelectObject(compHdc, m_foePlane);
	::BitBlt(hdc, m_nx, m_ny, FOEPLANE_MIDDLE_SIZE_WEIGH, FOEPLANE_MIDDLE_SIZE_HEIGH, compHdc, 0, (2 - m_nBoomshowID) * FOEPLANE_MIDDLE_SIZE_HEIGH, SRCAND);
}

bool CFoePlaneMid::IsHitGunner(CGunner* pGunner) {
	int x = (pGunner->m_nx) + GUNNER_SIZE_WIDTH / 2;
	if (m_nx <= x && x <= m_nx + FOEPLANE_MIDDLE_SIZE_WEIGH && pGunner->m_ny >= m_ny && pGunner->m_ny <= m_ny + FOEPLANE_MIDDLE_SIZE_HEIGH) {
		return true;
	}
	return false;
}


bool CFoePlaneMid::IsHitPlayerPlane(CPlayerPlane& playerPlane) {
	int x1 = (playerPlane.m_nx) + PALYERPLANE_SIZE_WIDTH / 2;
	if (m_nx <= x1 && x1 <= m_nx + FOEPLANE_MIDDLE_SIZE_WEIGH && playerPlane.m_ny >= m_ny && playerPlane.m_ny <= m_ny + FOEPLANE_MIDDLE_SIZE_HEIGH) {
		return true;
	}
	int y1 = (playerPlane.m_ny) + PALYERPLANE_SIZE_HEIGH * 2 / 3;
	if (m_nx <= playerPlane.m_nx && playerPlane.m_nx <= m_nx + FOEPLANE_MIDDLE_SIZE_WEIGH && y1 >= m_ny && y1 <= m_ny + FOEPLANE_MIDDLE_SIZE_HEIGH) {
		return true;
	}

	int x2 = (playerPlane.m_nx) + PALYERPLANE_SIZE_WIDTH;
	int y2 = (playerPlane.m_ny) + PALYERPLANE_SIZE_HEIGH * 2 / 3;
	if (m_nx <= x2 && x2 <= m_nx + FOEPLANE_MIDDLE_SIZE_WEIGH && y2 >= m_ny && y2 <= m_ny + FOEPLANE_MIDDLE_SIZE_HEIGH) {
		return true;
	}
	return false;
}
---------------------//FoePlaneBig.h//---------------------

#pragma once
#include "FoePlane.h"

class CFoePlaneBig :public CFoePlane
{
public:
	CFoePlaneBig();
	~CFoePlaneBig();
public:
	virtual void InitFoePlane(HINSTANCE hIns);
	virtual void ShowFoePlane(HDC hdc, HDC compHdc);
	virtual bool IsHitGunner(CGunner* pGunner);
	virtual bool IsHitPlayerPlane(CPlayerPlane& playerPlane);
};
---------------------//FoePlaneBig.cpp//---------------------

#include "FoePlaneBig.h"
#include "../resource.h"
#include "../GameConfig/GameConfig.h"


CFoePlaneBig::CFoePlaneBig() {

}
CFoePlaneBig::~CFoePlaneBig() {

}

void CFoePlaneBig::InitFoePlane(HINSTANCE hIns) {
	m_foePlane = ::LoadBitmap(hIns, MAKEINTRESOURCE(IDB_FOEBIG));
	m_nx = rand() % (BACKGOUND_MAPSIZE_WIDTH - FOEPLANE_BIG_SIZE_WEIGH + 1);
	m_ny = -FOEPLANE_BIG_SIZE_HEIGH;
	m_nBlood = FOEPLANE_BIG_BLOOD;
	m_nBoomshowID = 3;

}

void CFoePlaneBig::ShowFoePlane(HDC hdc, HDC compHdc) {
	::SelectObject(compHdc, m_foePlane);
	::BitBlt(hdc, m_nx, m_ny, FOEPLANE_BIG_SIZE_WEIGH, FOEPLANE_BIG_SIZE_HEIGH, compHdc, 0, (3 - m_nBoomshowID) * FOEPLANE_BIG_SIZE_HEIGH, SRCAND);
}

bool CFoePlaneBig::IsHitGunner(CGunner* pGunner) {
	int x = (pGunner->m_nx) + GUNNER_SIZE_WIDTH / 2;
	if (m_nx <= x && x <= m_nx + FOEPLANE_BIG_SIZE_WEIGH && pGunner->m_ny >= m_ny && pGunner->m_ny <= m_ny + FOEPLANE_BIG_SIZE_HEIGH) {
		return true;
	}
	return false;
}

bool CFoePlaneBig::IsHitPlayerPlane(CPlayerPlane& playerPlane) {
	int x1 = (playerPlane.m_nx) + PALYERPLANE_SIZE_WIDTH / 2;
	if (m_nx <= x1 && x1 <= m_nx + FOEPLANE_BIG_SIZE_WEIGH && playerPlane.m_ny >= m_ny && playerPlane.m_ny <= m_ny + FOEPLANE_BIG_SIZE_HEIGH) {
		return true;
	}
	int y1 = (playerPlane.m_ny) + PALYERPLANE_SIZE_HEIGH * 2 / 3;
	if (m_nx <= playerPlane.m_nx && playerPlane.m_nx <= m_nx + FOEPLANE_BIG_SIZE_WEIGH && y1 >= m_ny && y1 <= m_ny + FOEPLANE_BIG_SIZE_HEIGH) {
		return true;
	}

	int x2 = (playerPlane.m_nx) + PALYERPLANE_SIZE_WIDTH;
	int y2 = (playerPlane.m_ny) + PALYERPLANE_SIZE_HEIGH * 2 / 3;
	if (m_nx <= x2 && x2 <= m_nx + FOEPLANE_BIG_SIZE_WEIGH && y2 >= m_ny && y2 <= m_ny + FOEPLANE_BIG_SIZE_HEIGH) {
		return true;
	}
	return false;
}
---------------------//FoePlaneBox.h//---------------------

#pragma once
#include <list>
#include "FoePlane.h"
using namespace std;


class CFoePlaneBox
{
public:
	list<CFoePlane*> m_lstFoePlane;
	list<CFoePlane*> m_lstBoomFoe;
public:
	CFoePlaneBox();
	~CFoePlaneBox();
public:
	void ShowAllFoePlane(HDC hdc, HDC compHdc);
	void MoveAllFoePlane();
	void ShowBoomPlane(HDC hdc, HDC compHdc);
};
---------------------//FoePlaneBox.cpp//---------------------

#include "FoePlaneBox.h"
#include <typeinfo>
#include "FoePlaneSmall.h"
#include "FoePlaneMiddle.h"
#include "FoePlaneBig.h"
#include "../GameConfig/GameConfig.h"


CFoePlaneBox::CFoePlaneBox() {
	m_lstFoePlane.clear();
	m_lstBoomFoe.clear();
}

CFoePlaneBox::~CFoePlaneBox() {
	list<CFoePlane*>::iterator ite = m_lstFoePlane.begin();
	while (ite != m_lstFoePlane.end()) 
	{
		delete *ite;
		*ite = NULL;
		ite++;
	}
	m_lstFoePlane.clear();
	list<CFoePlane*>::iterator ite1 = m_lstBoomFoe.begin();
	while (ite1 != m_lstBoomFoe.end())
	{
		delete *ite1;
		*ite1 = NULL;
		ite1++;
	}
	m_lstBoomFoe.clear();
}

void CFoePlaneBox::ShowAllFoePlane(HDC hdc, HDC compHdc) {
	list<CFoePlane*>::iterator ite = m_lstFoePlane.begin();
	while (ite != m_lstFoePlane.end()) 
	{
		//显示所有敌军飞机
		(*ite)->ShowFoePlane(hdc, compHdc);
		ite++;
	}
}

void CFoePlaneBox::MoveAllFoePlane() {
	list<CFoePlane*>::iterator ite = m_lstFoePlane.begin();
	while (ite != m_lstFoePlane.end())
	{
		//移动所有飞机
		//RTTI	运行时类型识别
		//const type_info &ti = typeid(CFoePlaneSmall);	
		//const char*pName = ti.name();	
		//typeid type_infode的返回值及相关使用

		//typeid((*ite))		 CFoePlane *
		//typeid(*(*ite))		 *(CFoePlane*)
		if (typeid(*(*ite)) == typeid(CFoePlaneSmall)) //确定其为敌军小飞机
		{
			(*ite)->MoveFoePlane(FOEPLANE_SMALL_STEP);
		}else if (typeid(*(*ite)) == typeid(CFoePlaneMid)) //确定其为敌军中飞机
		{
			(*ite)->MoveFoePlane(FOEPLANE_MIDDLE_STEP);
		}else if (typeid(*(*ite)) == typeid(CFoePlaneBig)) //确定其为敌军大飞机
		{
			(*ite)->MoveFoePlane(FOEPLANE_BIG_STEP);
		}

		//判断是否出界 出界需要删除
		if ((*ite)->m_ny > BACKGOUND_MAPSIZE_HEIGH) 
		{
			ite = m_lstFoePlane.erase(ite);
			continue;
		}
		ite++;
	}
}

void CFoePlaneBox::ShowBoomPlane(HDC hdc, HDC compHdc) {
	list<CFoePlane*>::iterator ite = m_lstBoomFoe.begin();
	while (ite != m_lstBoomFoe.end()) {
		(*ite)->ShowFoePlane(hdc, compHdc);
		ite++;
	}
}
GunnerBox
---------------------//Gunner.h//---------------------

#pragma once
#include <windows.h>


class CGunner
{
public:
	HBITMAP m_hGunner;
	int m_nx;
	int m_ny;
public:
	CGunner();
	~CGunner();
public:
	void InitGunner(int x, int y, HINSTANCE hIns);
	void ShowGunner(HDC hdc, HDC compHdc);
	void MoveGunner(int step);
};
---------------------//Gunner.cpp//---------------------

#include "Gunner.h"
#include "../resource.h"
#include "../GameConfig/GameConfig.h"

CGunner::CGunner() {
	m_hGunner = NULL;
	m_nx = 0;
	m_ny = 0;
}

CGunner::~CGunner() {
	::DeleteObject(m_hGunner);
	m_hGunner = NULL;
	m_nx = 0;
	m_ny = 0;
}

void CGunner::InitGunner(int x, int y, HINSTANCE hIns) {
	m_nx = x;
	m_ny = y;
	m_hGunner = ::LoadBitmap(hIns, MAKEINTRESOURCE(IDB_GUNNER));
}

void CGunner::ShowGunner(HDC hdc, HDC compHdc) {
	::SelectObject(compHdc, m_hGunner);
	::BitBlt(hdc, m_nx, m_ny, GUNNER_SIZE_WIDTH, GUNNER_SIZE_HEIGH, compHdc, 0, 0, SRCAND);
}

void CGunner::MoveGunner(int step) {
	m_ny -= step;
}
---------------------//GunnerBox.h//---------------------

#pragma once
#include <windows.h>
#include "Gunner.h"
#include <list>
using namespace std;


class CGunnerBox
{
public:
	list<CGunner*> m_lstGunner;
public:
	CGunnerBox();
	~CGunnerBox();
public:
	void ShowAllGunner(HDC hdc, HDC compHdc);
	void MoveAllGunner(int step);
};
---------------------//GunnerBox.cpp//---------------------

#include "GunnerBox.h"
#include "../GameConfig/GameConfig.h"

CGunnerBox::CGunnerBox() {
	m_lstGunner.clear();
}

CGunnerBox::~CGunnerBox() {
	list<CGunner*>::iterator ite = m_lstGunner.begin();
	while (ite != m_lstGunner.end()) 
	{
		delete(*ite);
		(*ite) = NULL;
		ite++;
	}
	m_lstGunner.clear();
}

void CGunnerBox::ShowAllGunner(HDC hdc, HDC compHdc) {
	list<CGunner*>::iterator ite = m_lstGunner.begin();
	while (ite != m_lstGunner.end())
	{
		(*ite)->ShowGunner(hdc, compHdc);
		ite++;
	}
}

void CGunnerBox::MoveAllGunner(int step) {
	list<CGunner*>::iterator ite = m_lstGunner.begin();
	while (ite != m_lstGunner.end())
	{
		(*ite)->MoveGunner(step);
		if ((*ite)->m_ny <= -GUNNER_SIZE_HEIGH) 
		{
			ite = m_lstGunner.erase(ite);
			continue;
		}
		ite++;
	}
}
PlayerPlane
---------------------//PlayerPlane.h//---------------------

#pragma once
#include <windows.h>
#include "../GunnerBox/Gunner.h"

class CPlayerPlane
{
public:
	HBITMAP m_player;
	int m_nx;
	int m_ny;
public:
	CPlayerPlane();
	~CPlayerPlane();
public:
	void InitPlayerPlane(int x, int y, HINSTANCE hIns);
	void ShowPlayerPlane(HDC hdc, HDC compHdc);
	void MovePlayerPlane(int direct, int step);
	CGunner* SendGunner(HINSTANCE hIns);
};
---------------------//PlayerPlane.cpp//---------------------

#include "PlayerPlane.h"
#include "../resource.h"
#include "../GameConfig/GameConfig.h"


CPlayerPlane::CPlayerPlane() {
	m_player = NULL;
	m_nx = 0;
	m_ny = 0;
}
CPlayerPlane::~CPlayerPlane() {
	::DeleteObject(m_player);
	m_player = NULL;
	m_nx = 0;
	m_ny = 0;
}

void CPlayerPlane::InitPlayerPlane(int x, int y, HINSTANCE hIns) {
	m_nx = x;
	m_ny = y;
	m_player = ::LoadBitmap(hIns, MAKEINTRESOURCE(IDB_PLAYERPLANE));
}

void CPlayerPlane::ShowPlayerPlane(HDC hdc, HDC compHdc) {
	::SelectObject(compHdc, m_player);
	::BitBlt(hdc, m_nx, m_ny, PALYERPLANE_SIZE_WIDTH, PALYERPLANE_SIZE_HEIGH, compHdc, 0, 0, SRCAND);
}

void CPlayerPlane::MovePlayerPlane(int direct, int step) {
	switch (direct)
	{
	case VK_LEFT:
		{
			if (m_nx - step <= 0)
				m_nx = 0;
			else 
				m_nx -= step;
		}
		break;
	case VK_RIGHT:
		{
			if (m_nx + step >= BACKGOUND_MAPSIZE_WIDTH - PALYERPLANE_SIZE_WIDTH)
				m_nx = BACKGOUND_MAPSIZE_WIDTH - PALYERPLANE_SIZE_WIDTH;
			else
				m_nx += step;
		}
	break;
	case VK_UP:
		{
			if (m_ny - step <= 0)
				m_ny = 0;
			else
				m_ny -= step;
		}
	break;
	case VK_DOWN:
		{
			if (m_ny + step >= BACKGOUND_MAPSIZE_HEIGH - PALYERPLANE_SIZE_HEIGH)
				m_nx = BACKGOUND_MAPSIZE_HEIGH - PALYERPLANE_SIZE_HEIGH;
			else
				m_ny += step;
		}
	break;
	}
}

CGunner* CPlayerPlane::SendGunner(HINSTANCE hIns) {
	CGunner* pGunner = new CGunner;
	pGunner->InitGunner(m_nx + (PALYERPLANE_SIZE_WIDTH - GUNNER_SIZE_WIDTH) / 2, m_ny - GUNNER_SIZE_HEIGH, hIns);

	return pGunner;
}
GameConfig
---------------------//GameConfig.h//---------------------

#pragma once

#define WND_PARAM_X		500
#define WND_PARAM_Y		0
#define WND_PARAM_WIDTH	396
#define WND_PARAM_HEIGH	589
#define WND_PARAM_TITLE "*飞机大战*"

#define BACKGOUND_MAPSIZE_WIDTH	 380
#define BACKGOUND_MAPSIZE_HEIGH	 550

#define PALYERPLANE_SIZE_WIDTH	60	
#define PALYERPLANE_SIZE_HEIGH	60

#define GUNNER_SIZE_WIDTH	6
#define GUNNER_SIZE_HEIGH	9

#define TIMER_BACKGROUND_MOVE_ID			1
#define TIMER_BACKGROUND_MOVE_FREQUENCY_MS	200

#define PLAYERPLANE_MOVE_STEP				4
#define TIMER_PLAYERPLANE_MOVE_ID			2
#define TIMER_PLAYERPLANE_MOVE_FREQUENCY_MS	20

#define GUNNER_MOVE_STEP				8
#define TIMER_GUNNER_MOVE_ID			3
#define TIMER_GUNNER_MOVE_FREQUENCY_MS	100
#define TIMER_GUNNER_SEND_ID			4
#define TIMER_GUNNER_SEND_FREQUENCY_MS	800

#define FOEPLANE_SMALL_BLOOD		2
#define FOEPLANE_MIDDLE_BLOOD		6
#define FOEPLANE_BIG_BLOOD			10

#define GUNNER_HURT_BLOOD			2

#define FOEPLANE_SMALL_SIZE_WEIGH	34
#define FOEPLANE_SMALL_SIZE_HEIGH	28
#define FOEPLANE_MIDDLE_SIZE_WEIGH	70
#define FOEPLANE_MIDDLE_SIZE_HEIGH	90
#define FOEPLANE_BIG_SIZE_WEIGH		108
#define FOEPLANE_BIG_SIZE_HEIGH		129

#define FOEPLANE_SMALL_STEP						14
#define TIMER_SMALLFOE_CREATE_ID				5	
#define TIMER_SMALLFOE_CREATE_FREQUENCY_MS		6000

#define FOEPLANE_MIDDLE_STEP					9
#define TIMER_MIDDLEFOE_CREATE_ID				6
#define TIMER_MIDDLEFOE_CREATE_FREQUENCY_MS		9000

#define FOEPLANE_BIG_STEP						5
#define TIMER_BIGFOE_CREATE_ID					7
#define TIMER_BIGFOE_CREATE_FREQUENCY_MS		12000

#define TIMER_FOEPLANE_MOVE_ID					8
#define TIMER_FOEPLANE_MOVE_FREQUENCY_MS		80

//定时检查敌人飞机是否撞击炮弹及玩家飞机
#define TIMER_CHEAK_ISHIT_ID					9
#define TIMER_CHEAK_ISHIT_FREQUENCY_MS			20

//定时切换敌人飞机爆炸效果
#define TIMER_BOOMPLANE_CHANGE_ID				10
#define TIMER_BOOMPLANE_FREQUENCY_MS			400
GameFrame(前面封装好的游戏壳)
---------------------//WinMain.cpp//---------------------
    
// window 应用程序,多字符集
#include <windows.h>
#include <windowsx.h>
#include "Gameapp.h"

LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
HINSTANCE hIns = 0;  //全局变量,程序实例句柄

int CALLBACK WinMain(HINSTANCE hInstance, HINSTANCE hPreInstance, LPSTR lpCmdLine, int nShowCmd)
{
	//-----------------------------------------------------
	HWND hwnd = 0;
	MSG msg;       //  装消息的结构体
	WNDCLASSEX wndclass;
	//-----------------------------------------------------

	hIns = hInstance;
	LPCSTR lClassName = "yue";				//窗口类名CN
	extern int nx;							//窗口位置X
	extern int ny;							//窗口位置Y
	extern int nwidth;						//窗口宽度W
	extern int nheigh;						//窗口高度H
	extern CHAR* strTitle;					//窗口标题名T
	int pos_x = nx;
	if (pos_x < 0) {
		pos_x = 0;
	}
	int pos_y = ny;
	if (pos_y < 0) {
		pos_y = 0;
	}
	int nWidth = nwidth;
	if (nWidth <= 0) {
		nWidth = 500;
	}
	int nHeight = nheigh;
	if (nHeight <= 0) {
		nHeight = 500;
	}

	//----------------------创建窗口过程-----------------------------------
	//  1. 设计
	wndclass.cbClsExtra = 0;
	wndclass.cbWndExtra = 0;
	wndclass.cbSize = sizeof(wndclass);
	wndclass.hbrBackground = (HBRUSH)COLOR_WINDOW;
	wndclass.hCursor = LoadCursor(0, MAKEINTRESOURCE(IDC_ARROW));
	wndclass.hIcon = 0;
	wndclass.hIconSm = 0;
	wndclass.hInstance = hInstance;
	wndclass.lpfnWndProc = WindowProc;
	wndclass.lpszClassName = lClassName;
	wndclass.lpszMenuName = 0;
	wndclass.style = CS_HREDRAW | CS_VREDRAW;
	// 2.  注册
	if (RegisterClassEx(&wndclass) == FALSE)
	{
		MessageBox(0, "注册失败", "提示", MB_OK);
		return 0;
	}
	//  3.  创建
	hwnd = CreateWindow(lClassName, strTitle, WS_OVERLAPPEDWINDOW, pos_x, pos_y, nWidth, nHeight, 0, 0, hInstance, 0);
	if (hwnd == 0)
	{
		MessageBox(0, "创建失败", "提示", MB_OK);
		return 0;
	}
	//  4.  显示窗口
	ShowWindow(hwnd, SW_SHOW);
	//---------------------------创建窗口过程------------------------------------------------

	//----------------------------消息循环-------------------------------------------
	while (GetMessage(&msg, 0, 0, 0))
	{
		TranslateMessage(&msg);
		DispatchMessage(&msg);
	}
	//----------------------------消息循环-------------------------------------------

	return 0;
}

CGameApp* pGameAPP = NULL;


LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	switch (uMsg)
	{
	case WM_CREATE: //窗口创建消息
	{
		if (pGameAPP == NULL) 
		{
			pGameAPP = Get_Object();	//获取子类
			pGameAPP->SetHandle(hIns, hwnd);
			pGameAPP->OnCreate();

		}
	}
	break;
	case WM_PAINT:  //重绘消息
	{
		if (pGameAPP)
		{
			pGameAPP->OnPaint();
		}
	}
	break;
	case WM_TIMER:   //定时器,需要我们在子类中手动添加定时器并设置触发间隔
	{
		if (pGameAPP)
		{
			pGameAPP->OnGameRun(wParam);
		}
	}
	break;
	case WM_KEYDOWN:  //键盘按下触发消息
	{
		if (pGameAPP)
		{
			pGameAPP->OnKeyDown(wParam);
		}
	}
	break;
	case WM_KEYUP:  //键盘抬起触发消息
	{
		if (pGameAPP)
		{
			pGameAPP->OnKeyUp(wParam);
		}
	}
	break;
	case WM_LBUTTONDOWN: //鼠标左键按下触发消息
	{
		if (pGameAPP)
		{
			POINT po = { 0 };
			po.x = GET_X_LPARAM(lParam);
			po.y = GET_Y_LPARAM(lParam);
			pGameAPP->OnLbuttonDown(po);
		}
	}
	break;
	case WM_LBUTTONUP: //鼠标左键抬起触发消息
	{
		if (pGameAPP)
		{
			POINT po = { 0 };
			po.x = GET_X_LPARAM(lParam);
			po.y = GET_Y_LPARAM(lParam);
			pGameAPP->OnLbuttonUp(po);
		}
	}
	break;
	case WM_MOUSEMOVE:  //鼠标移动
	{
		if (pGameAPP)
		{
			POINT po = { 0 };
			po.x = GET_X_LPARAM(lParam);
			po.y = GET_Y_LPARAM(lParam);
			pGameAPP->OnMouseMove(po);
		}
	}
	break;
	case WM_CLOSE:
	{
		int res = ::MessageBox(NULL, "[WM_CLOSE] 是否确定退出", "提示", MB_OKCANCEL);
		if (res == IDOK) { //点击 【确定】按钮

		}
		else if (res == IDCANCEL) {//点击【取消】按钮,不调用默认的消息处理 DefWindowProc 

			return 0;
		}
		else {
			return 0;
		}
	}
	break;
	case WM_DESTROY:
	{
		//::MessageBox(NULL, "WM_DESTROY", "提示", MB_OK);
		//释放游戏资源

		if (pGameAPP) {
			delete pGameAPP;
			pGameAPP = NULL;
		}

		PostQuitMessage(0);
	}
	break;
	case WM_QUIT:
	{
		::MessageBox(NULL, "WM_QUIT", "提示", MB_OK);
	}
	break;
	}
	return DefWindowProc(hwnd, uMsg, wParam, lParam);

}
---------------------//Gameapp.h//---------------------

#pragma once
#include <windows.h>

class CGameApp {
public:
	HINSTANCE m_hInstance;
	HWND m_hWnd;
public:
	CGameApp() {}
	virtual ~CGameApp() {}
public:
	void SetHandle(HINSTANCE hIns, HWND hWnd) {
		m_hInstance = hIns;
		m_hWnd = hWnd;
	}
public:
	virtual void OnCreate() {}//窗口创建消息
	virtual void OnPaint() {}//重绘消息
	virtual void OnGameRun(WPARAM wParam) {}//定时器,需要在子类中手动添加定时器并设置触发间隔
	virtual void OnKeyDown(WPARAM wParam) {}//键盘按下触发消息
	virtual void OnKeyUp(WPARAM wParam) {}//键盘抬起触发消息
	virtual void OnLbuttonDown(POINT& po) {}//鼠标左键按下触发消息
	virtual void OnLbuttonUp(POINT& po) {}//鼠标左键抬起触发消息
	virtual void OnMouseMove(POINT& po) {}//鼠标移动
};

CGameApp* Get_Object();

#define GET_OBJECT(CHILD_CLASS)\
	CGameApp* Get_Object() {\
		return new CHILD_CLASS;\
	}

#define CLASS_CONFIG(PARAM_X,PARAM_Y,PARAM_WIDTH,PARAM_HEIGH,PARAM_TITLE)\
	int nx = PARAM_X;\
	int ny = PARAM_Y;\
	int nwidth = PARAM_WIDTH;\
	int nheigh = PARAM_HEIGH;\
	CHAR* strTitle = (CHAR*)PARAM_TITLE;
PlaneAPP
---------------------//PlaneApp.h//---------------------

#pragma once

#include "../GameFrame/Gameapp.h"
#include "../BackGround/BackGround.h"
#include "../PlayerPlane/PlayerPlane.h"
#include "../GunnerBox/GunnerBox.h"
#include "../FoePlaneBox/FoePlaneBox.h"

class CPlaneApp :public CGameApp
{
public:
	CBackGround m_back;
	CGunnerBox m_gunbox;
	CPlayerPlane m_player;
	CFoePlaneBox m_foebox;
public:
	CPlaneApp();
	~CPlaneApp();
public:
	virtual void OnCreate();//窗口创建消息
	virtual void OnPaint();//重绘消息
	virtual void OnGameRun(WPARAM wParam);//定时器,需要在子类中手动添加定时器并设置触发间隔
	//virtual void OnKeyDown(WPARAM wParam);//键盘按下触发消息
public:
	void SetTimmer();
	void GameOver();
};
---------------------//PlaneApp.cpp//---------------------

#include "PlaneApp.h"
#include "../GameConfig/GameConfig.h"
#include <time.h>
#include "../FoePlaneBox/FoePlane.h"
#include "../FoePlaneBox/FoePlaneBig.h"
#include "../FoePlaneBox/FoePlaneMiddle.h"
#include "../FoePlaneBox/FoePlaneSmall.h"

GET_OBJECT(CPlaneApp)
CLASS_CONFIG(WND_PARAM_X, WND_PARAM_Y, WND_PARAM_WIDTH, WND_PARAM_HEIGH, WND_PARAM_TITLE)

CPlaneApp::CPlaneApp() {

}
CPlaneApp::~CPlaneApp() {

}

void CPlaneApp::OnCreate() {
	//随机数种子
	srand((unsigned int)time(NULL));

	//创建定时器
	SetTimmer();

	//初始化背景
	m_back.InitBackGround(0, 0, this->m_hInstance);
	m_player.InitPlayerPlane((BACKGOUND_MAPSIZE_WIDTH - PALYERPLANE_SIZE_WIDTH) / 2, BACKGOUND_MAPSIZE_HEIGH - PALYERPLANE_SIZE_HEIGH, this->m_hInstance);

}//窗口创建消息

void CPlaneApp::OnPaint() {

	//获取窗口DC
	PAINTSTRUCT ps = { 0 };
	HDC hdc = ::BeginPaint(this->m_hWnd, &ps);

	//创建缓冲的兼容性DC和兼容性位图(缓存中间区~)
	HDC cacheDC = ::CreateCompatibleDC(hdc);
	HBITMAP cachemap = ::CreateCompatibleBitmap(hdc, BACKGOUND_MAPSIZE_WIDTH, BACKGOUND_MAPSIZE_HEIGH);
	::SelectObject(cacheDC, cachemap);

	//创建兼容性DC
	HDC compDC = ::CreateCompatibleDC(cacheDC);
	m_back.ShowBackGround(cacheDC, compDC);
	m_player.ShowPlayerPlane(cacheDC, compDC);
	m_gunbox.ShowAllGunner(cacheDC, compDC);
	m_foebox.ShowAllFoePlane(cacheDC, compDC);
	m_foebox.ShowBoomPlane(cacheDC, compDC);
	
	//闪烁问题实际是刷新率的问题,没有同时刷新,解决方式可以是把所有要贴的先贴到一个缓存中间区,然后再一次性贴到窗口dc上。(双缓冲)
	BitBlt(hdc, 0, 0, BACKGOUND_MAPSIZE_WIDTH, BACKGOUND_MAPSIZE_HEIGH, cacheDC, 0, 0, SRCCOPY);

	//删除释放DC
	DeleteDC(compDC);
	compDC = NULL;

	::DeleteObject(cachemap);
	cachemap = NULL;
	DeleteDC(cacheDC);
	cacheDC = NULL;

	::EndPaint(this->m_hWnd, &ps);

}//重绘消息

void CPlaneApp::OnGameRun(WPARAM wParam) {
	switch (wParam)
	{
	case TIMER_BACKGROUND_MOVE_ID:	//背景移动
		{
			m_back.MoveBackGround(4);
		}
		break;
	case TIMER_PLAYERPLANE_MOVE_ID:	//玩家飞机移动
		{
			if (::GetAsyncKeyState(VK_LEFT)) {
				m_player.MovePlayerPlane(VK_LEFT, PLAYERPLANE_MOVE_STEP);
			}
			if (::GetAsyncKeyState(VK_RIGHT)) {
				m_player.MovePlayerPlane(VK_RIGHT, PLAYERPLANE_MOVE_STEP);
			}
			if (::GetAsyncKeyState(VK_UP)) {
				m_player.MovePlayerPlane(VK_UP, PLAYERPLANE_MOVE_STEP);
			}
			if (::GetAsyncKeyState(VK_DOWN)) {
				m_player.MovePlayerPlane(VK_DOWN, PLAYERPLANE_MOVE_STEP);
			}
		}
		break;
	case TIMER_GUNNER_MOVE_ID:	//炮弹移动
		{
			m_gunbox.MoveAllGunner(GUNNER_MOVE_STEP);
		}
		break;
	case TIMER_GUNNER_SEND_ID:	//炮弹发射
		{
			CGunner* pGunner = m_player.SendGunner(this->m_hInstance);
			m_gunbox.m_lstGunner.push_back(pGunner);
		}
		break;
	case TIMER_SMALLFOE_CREATE_ID:	//创建敌军小飞机
		{
			CFoePlane* pFoe = new CFoePlaneSmall;
			pFoe->InitFoePlane(this->m_hInstance);
			//加到敌军飞机盒子里
			m_foebox.m_lstFoePlane.push_back(pFoe);
		}
		break;
	case TIMER_MIDDLEFOE_CREATE_ID:	//创建敌军中飞机
		{
			CFoePlane* pFoe = new CFoePlaneMid;
			pFoe->InitFoePlane(this->m_hInstance);
			//加到敌军飞机盒子里
			m_foebox.m_lstFoePlane.push_back(pFoe);
		}
		break;
	case TIMER_BIGFOE_CREATE_ID:	//创建敌军大飞机
		{
			CFoePlane* pFoe = new CFoePlaneBig;
			pFoe->InitFoePlane(this->m_hInstance);
			//加到敌军飞机盒子里
			m_foebox.m_lstFoePlane.push_back(pFoe);
		}
		break;
	case TIMER_FOEPLANE_MOVE_ID:	//敌军飞机移动
		{
			m_foebox.MoveAllFoePlane();
		}
		break;
	case TIMER_CHEAK_ISHIT_ID:	//敌军飞机是否撞击玩家飞机or炮弹
		{
			bool isBOOM = false;
			list<CFoePlane*>::iterator iteFoe = m_foebox.m_lstFoePlane.begin();
			while (iteFoe != m_foebox.m_lstFoePlane.end()) 
			{
				//遍历所有敌军飞机
				//判断是否撞击玩家飞机
				if ((*iteFoe)->IsHitPlayerPlane(m_player)) 
				{
					//撞击则游戏结束
					GameOver();
					return;
				}
				//判断是否撞击炮弹
				list<CGunner*>::iterator iteGun = m_gunbox.m_lstGunner.begin();
				while (iteGun != m_gunbox.m_lstGunner.end())	//遍历所有炮弹 
				{
					if ((*iteFoe)->IsHitGunner((*iteGun))) //判断敌军飞机是否撞击到了炮弹
					{
						//撞击需要删除炮弹
						iteGun = m_gunbox.m_lstGunner.erase(iteGun);
                        //因为erase的返回值是下一个,等同于已经++了,所以利用break和continue
						//敌军飞机血量减少
						(*iteFoe)->m_nBlood -= GUNNER_HURT_BLOOD;
						//判断血量是否为0,为0则显示爆炸
						if ((*iteFoe)->m_nBlood <= 0) {
							isBOOM = true;
							//移动敌军飞机(从正常链表移动到爆炸链表)
							m_foebox.m_lstBoomFoe.push_back(*iteFoe);
							//删除正常链表里已经移动完的敌军飞机
							iteFoe = m_foebox.m_lstFoePlane.erase(iteFoe);
							//因为erase的返回值是下一个,等同于已经++了,所以利用isBOOM作为标记值
							break;
						}
						continue;
					}
					iteGun++;
				}
				if (isBOOM)
				{
					isBOOM = false;
				}
				else
				{
					iteFoe++;
				}
			}
		}
		break;
	case TIMER_BOOMPLANE_CHANGE_ID:	//敌军飞机爆炸效果切换
		{
			list<CFoePlane*>::iterator ite = m_foebox.m_lstBoomFoe.begin();
			while (ite != m_foebox.m_lstBoomFoe.end()) {
				(*ite)->m_nBoomshowID--;
				if ((*ite)->m_nBoomshowID < 0)
				{
					delete (*ite);
					(*ite) = NULL;
					ite = m_foebox.m_lstBoomFoe.erase(ite);
					continue;
				}
				ite++;
			}
		}
		break;
	}
	RECT rect = { 0,0,BACKGOUND_MAPSIZE_WIDTH ,BACKGOUND_MAPSIZE_HEIGH };
	::InvalidateRect(this->m_hWnd, &rect, FALSE);

}//定时器,需要在子类中手动添加定时器并设置触发间隔

//void CPlaneApp::OnKeyDown(WPARAM wParam) {
//	
//	//m_player.MovePlayerPlane(wParam, PLAYERPLANE_MOVE_STEP);
//
//}//键盘按下触发消息

void CPlaneApp::SetTimmer() {

	//设置背景移动的定时器
	::SetTimer(this->m_hWnd, TIMER_BACKGROUND_MOVE_ID, TIMER_BACKGROUND_MOVE_FREQUENCY_MS, NULL);

	//设置监测键盘是否按下的定时器(玩家飞机移动)
	::SetTimer(this->m_hWnd, TIMER_PLAYERPLANE_MOVE_ID, TIMER_PLAYERPLANE_MOVE_FREQUENCY_MS, NULL);

	//炮弹移动的定时器
	::SetTimer(this->m_hWnd, TIMER_GUNNER_MOVE_ID, TIMER_GUNNER_MOVE_FREQUENCY_MS, NULL);

	//炮弹发射的定时器
	::SetTimer(this->m_hWnd, TIMER_GUNNER_SEND_ID, TIMER_GUNNER_SEND_FREQUENCY_MS, NULL);

	//创建敌军小飞机的定时器
	::SetTimer(this->m_hWnd, TIMER_SMALLFOE_CREATE_ID, TIMER_SMALLFOE_CREATE_FREQUENCY_MS, NULL);

	//创建敌军中飞机的定时器
	::SetTimer(this->m_hWnd, TIMER_MIDDLEFOE_CREATE_ID, TIMER_MIDDLEFOE_CREATE_FREQUENCY_MS, NULL);

	//创建敌军大飞机的定时器
	::SetTimer(this->m_hWnd, TIMER_BIGFOE_CREATE_ID, TIMER_BIGFOE_CREATE_FREQUENCY_MS, NULL);

	//敌军飞机移动的定时器
	::SetTimer(this->m_hWnd, TIMER_FOEPLANE_MOVE_ID, TIMER_FOEPLANE_MOVE_FREQUENCY_MS, NULL);

	//敌军飞机是否撞击的定时器
	::SetTimer(this->m_hWnd, TIMER_CHEAK_ISHIT_ID, TIMER_CHEAK_ISHIT_FREQUENCY_MS, NULL);

	//切换飞机爆炸效果的定时器
	::SetTimer(this->m_hWnd, TIMER_BOOMPLANE_CHANGE_ID, TIMER_BOOMPLANE_FREQUENCY_MS, NULL);
}


void CPlaneApp::GameOver() {
	//杀死所有定时器
	::KillTimer(this->m_hWnd, TIMER_BACKGROUND_MOVE_ID);
	::KillTimer(this->m_hWnd, TIMER_PLAYERPLANE_MOVE_ID);
	::KillTimer(this->m_hWnd, TIMER_GUNNER_MOVE_ID);
	::KillTimer(this->m_hWnd, TIMER_GUNNER_SEND_ID);
	::KillTimer(this->m_hWnd, TIMER_SMALLFOE_CREATE_ID);
	::KillTimer(this->m_hWnd, TIMER_MIDDLEFOE_CREATE_ID);
	::KillTimer(this->m_hWnd, TIMER_BIGFOE_CREATE_ID);
	::KillTimer(this->m_hWnd, TIMER_FOEPLANE_MOVE_ID);
	::KillTimer(this->m_hWnd, TIMER_CHEAK_ISHIT_ID);
	::KillTimer(this->m_hWnd, TIMER_BOOMPLANE_CHANGE_ID);

	//提示游戏结束
	::MessageBox(this->m_hWnd, "GameOver", "提示", MB_OK);

	//发送程序退出消息
	PostMessage(this->m_hWnd, WM_DESTROY, 0, 0);
}

Windows程序思维导图速查~

在这里插入图片描述

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

97Marcus

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值