C++实训报告飞机大战Word文件下载.docx
《C++实训报告飞机大战Word文件下载.docx》由会员分享,可在线阅读,更多相关《C++实训报告飞机大战Word文件下载.docx(34页珍藏版)》请在冰豆网上搜索。
![C++实训报告飞机大战Word文件下载.docx](https://file1.bdocx.com/fileroot1/2023-1/25/a4c65c34-e50a-45ad-942c-2b6af7f7a139/a4c65c34-e50a-45ad-942c-2b6af7f7a1391.gif)
在详细介绍实现过程之前先介绍下所使用的画图函数以及函数参数所代表的功能;
整个绘制过程需要使用到BitBlt()函数。
整个功能的实现过程如下:
(1)创建一张大小与需要绘制图像相同的位图作为“掩码”位图;
(2)将新创建的“掩码”位图存储至掩码位图的设备描述表中;
(3)把位图设备描述表的背景设置成“透明色”,不需要显示的颜色;
(4)复制粘贴位图到“掩码”位图的设备描述表中,这个时候“掩码”位图设备描述表中存放的位图与位图设备描述表中的位图一样;
(5)把需要透明绘制的位图与对话框绘图相应区域的背景进行逻辑异或操作绘制到对话框上;
(6)把“掩码”位图与这个时候对话框相应区域的背景进行逻辑与的操作;
(7)重复步骤5的操作,把需要透明绘制的位图与对话框绘图相应区域的背景进行逻辑异或操作绘制到对话框上;
(8)最后把系统的画笔还给系统,删除使用过的GDIObject,释放非空的指针,最后把新建的设备描述表也删除。
BOOLCGameObject:
:
LoadImage(CImageList&
imgList,UINTbmpID,
COLORREFcrMask,intcx,intcy,intnInitial)
{
CBitmapbmp;
if(!
bmp.LoadBitmap(bmpID))
returnFALSE;
imgList.Create(cx,cy,ILC_COLOR24|ILC_MASK,nInitial,0))
imgList.Add(&
bmp,crMask);
returnTRUE;
}
3.1.2CObList链表
在本程序中我使用了CObList链表来分别存储敌机,炸弹,导弹,爆
炸效果和掉落物品。
CobList类似于一个双向链表,POSITION类型的变量
为链表的键。
使用POSITION变量,既可以作为链表循环中的循环变量,
也可以作为标记某个位置的标签。
我们可以通过获得某元素的
POSITION来访问它。
本程序中主要用到的函数有:
GetHeadPosition()——获取链表首元素的POSITION,AddTail()——向链表尾部添加新的元素,GetNext(POSITION&
rPosition)——返回当前rPosition指向的元素,并使rPosition指向下一个元素。
3.1.3内存释放
在VC/MFC用CDC绘图时,频繁的刷新,屏幕会出现闪烁的现象,CPU时间占用率相当高,绘图效率极低,很容易出现程序崩溃。
及时的释放程序所占用的内存资源是非常重要的。
在程序中使用到的链表、刷子等占用内存资源的对象都要及时的删除。
DeleteBrush,List.removeall()等。
3.1.4双缓冲技术
当数据量很大时,绘图可能需要几秒钟甚至更长的时间,而且有时还会出现闪烁现象,为了解决这些问题,可采用双缓冲技术来绘图。
双缓冲实现过程如下:
在内存中创建与画布一致的缓冲区
在缓冲区画图
将缓冲区位图拷贝到当前画布上
释放内存缓冲区
下面给出实现的程序,同样是在OnDraw(CDC*pDC)中:
CDCMemDC;
//定义一个显示设备对象
CBitmapMemBitmap;
//定义一个位图对像
MemDC.CreateCompatibleDC(NULL);
MemBitmap.CreateCompatibleBitmap(MemDC,nWidth,nHeight);
//将位图选入到内存显示设备中
CBitmap*pOldBit=MemDC.SelectObject(&
MemBitmap);
MemDC.FillSolidRect(0,0,nWidth,nHeight,RGB(255,255,255));
MemDC.MoveTo(……);
MemDC.LineTo(……);
pDC->
BitBlt(0,0,nWidth,nHeight,&
MemDC,0,0,SRCCOPY);
MemDC.SelectObject(pOldBit);
MemBitmap.DeleteObject();
MemDC.DeleteDC();
3.1.5键盘对战机的控制
添加OnKeyDown()和OnKeyUp()函数,用GetKeyState()函数来判断按下了哪个键,通过修改战机的相应参数来实现对战机的控制,如上下左右运动,发射子弹等等。
如果战机此时已处于屏幕边缘,则控制战机飞出屏幕的按键信息无效。
3.2项目实施
按照项目实施计划和技术准备一步一步去实现项目。
3.2.1功能需求
本程序为飞机大战游戏,飞机大战游戏作为PC中一款桌面游戏,界面简洁流畅、游戏方式简单,玩起来易于上手。
主要实现的功能如下:
1.战机数量为1
2.由玩家通过键盘控制(方向键控制位置、默认开启炸弹、空格键发射清屏导弹)战机
3.导弹释放存在间隔,有一定的运行速度
4.导弹遇到敌机发生爆炸,敌机被炸毁,导弹消失,玩家得分,当得分到达一定数目就进入下一关
5.由计算机控制敌机自动向战机发动攻击,击中时战机掉血,初始20条命
6.敌机数量随机,计算机生成敌机时随机选择类别
7.敌机从游戏区域的上端进入,左右位置随机
8.敌机行驶期间,不左右移动,不反向移动
9.当敌机位于战机后方时发射炸弹对战机进行攻击
10.敌机运行线路为直线,方向为从下至上,或从下至上,不可左右移动,纵向由发射位置起至游戏区域结束
11.敌机与敌机炸弹均具有一定的速度,且随着关卡难度的增大,数量和速度均增加
12.炸弹遇到战机时发生爆炸,战机生命数量减少1,炸弹消失,游戏结束炸弹运行时有速度限制
13.游戏过程中会随机掉落物品,得到后可以变换子弹或者得到全屏炸弹
14.根据菜单可以选择重新开始游戏,Esc键可以暂停游戏
15.可以在选择关卡处选择关卡
16.在游戏界面输出当前游戏进行信息,包括当前得分、当前关卡以及剩余生命数量
17.游戏过程中添加了声效
3.2.2总体设计
3.2.2.1系统模块划分
游戏规则子系统
模块名称
功能简述
人工智能
人机对战规则的实现
游戏子系统
应用程序对象
游戏程序的加载、游戏对象的绘制、游戏规则的调用、玩家的键盘事件获取
游戏对象
各个游戏对象的抽象父类
战机对象
战机类
敌机对象
敌机类
导弹对象
导弹类
炸弹对象
炸弹类
爆炸对象
爆炸类
文字对象
文字类
物品对象
物品类
类体系
3.2.2.2主要功能模块
系统对象类图
飞机大战游戏执行流程图:
产生敌机并绘制敌机流程图:
3.2.3详细设计与编码
//PlaneGameView.cpp:
implementationoftheCPlaneGameViewclass
//
#include"
stdafx.h"
PlaneGame.h"
PlaneGameDoc.h"
PlaneGameView.h"
MyPlane.h"
Enemy.h"
Enemy1.h"
Bomb.h"
Ball.h"
Explosion.h"
Nuke.h"
Newbomb.h"
Setlvl3.h"
mmsystem.h"
//windows中与多媒体有关的大多数接口,用于播放声音。
#pragmacomment(lib,"
WINMM.LIB"
)
#ifdef_DEBUG
#definenewDEBUG_NEW
#undefTHIS_FILE
staticcharTHIS_FILE[]=__FILE__;
#endif
staticintinit;
intlvl[31]={550,1100,2200,2933,3758,4583,5408,6233,7058,7883,8708,9533,10358,11183,12008,12833,13658,14483,15308,16133,16958,17783,18608,19433,20258,21083,21908,22733,23558,24383,25208};
/////////////////////////////////////////////////////////////////////////////
//CPlaneGameView
IMPLEMENT_DYNCREATE(CPlaneGameView,CView)
BEGIN_MESSAGE_MAP(CPlaneGameView,CView)
//标准打印命令
ON_COMMAND(ID_FILE_PRINT,CView:
OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_DIRECT,CView:
ON_COMMAND(ID_FILE_PRINT_PREVIEW,CView:
OnFilePrintPreview)
ON_WM_TIMER()
ON_WM_KEYDOWN()
ON_COMMAND(ID_START,CPlaneGameView:
OnStart)
ON_COMMAND(ID_RESTART,CPlaneGameView:
OnRestart)
ON_COMMAND(ID_SETLVL,CPlaneGameView:
OnSetlvl)
END_MESSAGE_MAP()
//CPlaneGameViewconstruction/destruction
CPlaneGameView:
CPlaneGameView():
m_pMe(NULL),lifeNum_Me(20),Score_Me(0),Lvl_Me
(1),Nuke_Me(5),setlvl
(1)
//TODO:
addconstructioncodehere
~CPlaneGameView()
BOOLCPlaneGameView:
PreCreateWindow(CREATESTRUCT&
cs)
ModifytheWindowclassorstylesherebymodifying
//theCREATESTRUCTcs
returnCView:
PreCreateWindow(cs);
//CPlaneGameViewdrawing
voidCPlaneGameView:
OnDraw(CDC*pDC)
CPlaneGameDoc*pDoc=GetDocument();
ASSERT_VALID(pDoc);
//断定宏
if(!
pDoc)//如果不是文档类指针
return;
//绘制游戏开始界面
CDC*m_pMemDC1;
//为绘图提供成员函数
m_pMemDC1=newCDC;
//为绘图申请内存空间
m_pMemDC1->
CreateCompatibleDC(pDC);
CBitmapbmp1;
bmp1.LoadBitmap(IDB_start);
//创建位图
SelectObject(&
bmp1);
BitBlt(0,0,480,644,m_pMemDC1,0,0,SRCCOPY);
DeleteObject(bmp1);
deletem_pMemDC1;
//释放内存
//CPlaneGameViewprinting
OnPreparePrinting(CPrintInfo*pInfo)
//defaultpreparation
returnDoPreparePrinting(pInfo);
OnBeginPrinting(CDC*/*pDC*/,CPrintInfo*/*pInfo*/)
addextrainitializationbeforeprinting
OnEndPrinting(CDC*/*pDC*/,CPrintInfo*/*pInfo*/)
addcleanupafterprinting
//CPlaneGameView诊断
AssertValid()const
CView:
AssertValid();
Dump(CDumpContext&
dc)const
Dump(dc);
CPlaneGameDoc*CPlaneGameView:
GetDocument()//非调试版本是内联的
ASSERT(m_pDocument->
IsKindOf(RUNTIME_CLASS(CPlaneGameDoc)));
return(CPlaneGameDoc*)m_pDocument;
#endif//_DEBUG
OnStart()
在此添加命令处理程序代码
init)
{
InitGame();
init=1;
}
OnRestart()//重新开始
if(init==0)
OnStart();
else
KillTimer
(1);
m_pMe=newMyPlane;
//重新申请内存空间
Score_Me=0;
lifeNum_Me=20;
Lvl_Me=1;
Nuke_Me=5;
for(inti=0;
i<
7;
i++)
m_ObjList[i].RemoveAll();
//删除链表中所有的元素
SetTimer(1,30,NULL);
OnInitialUpdate()
OnInitialUpdate();
在此添加专用代码和/或调用基类
//初始化游戏
StopGame()//清除指针
deletem_pMe;
deletem_pMemDC;
deletem_pDC;
deletem_pMemBitmap;
InitGame()//初始化游戏
CRectrc;
GetClientRect(rc);
//产生随机数种子
srand((unsigned)time(NULL));
//建立设备DC
m_pDC=newCClientDC(this);
//建立内存DC
m_pMemDC=newCDC;
m_pMemDC->
CreateCompatibleDC(m_pDC);
//建立内存位图
m_pMemBitmap=newCBitmap;
m_pMemBitmap->
CreateCompatibleBitmap(m_pDC,GAME_WIDTH,GAME_HEIGHT);
//将位图选入内存DC
SelectObject(m_pMemBitmap);
MyPlane:
LoadImage();
Enemy:
Enemy1:
Bomb:
Ball:
Explosion:
Nuke:
Newbomb:
//产生主角(战机)
m_pMe=newMyPlane;
//启动游戏
SetTimer(1,30,NULL);
pause=0;
//暂停标志:
0->
继续1->
暂停
returntrue;
intmy=0;
//移动背景标志
UpdateFrame(CDC*pDC)
wchar_tlifeleft[20];
//存储剩余生命
wchar_tScore[20];
//存储分数
wchar_tLvl[20];
//存储关卡
wchar_tNuke[20];
//存储导弹
//绘制背景
CBitmapbmp;
if(m_pMe!
=NULL)
intpn=(Lvl_Me)%5+1;
switch(pn)
{
case1:
bmp.LoadBitmap(IDB_background1);
break;
case2:
bmp.LoadBitmap(IDB_background2);
case3:
bmp.LoadBitmap(IDB_background3);
case4:
bmp.LoadBitmap(IDB_background4);
case5:
bmp.LoadBitmap(IDB_background5);
}
m_pMemDC->
bmp);
pDC->
BitBlt(0,0,480,644,m_pMemDC,10,my,SRCCOPY);
if(my>
0)
my--;
elseif(my<
=0)
my=644;
else
if(Lvl_Me<
31)
bmp.LoadBitmap(IDB_win);
else
bmp.LoadBitmap(IDB_win);
my=0;
//绘制我方战机
m_pMe->
Draw(m_pMemDC,FALSE);
SetBkMode(TRANSPARENT);
//透明文字背景
SetTextColor(RGB(0,255,0));
TextOut(10,10,"
生命值:
"
);
wsprintfW(lifeleft,L"
%d"
lifeNum_Me);
SetTextColor(RGB(255,0,0));
TextOut(80,10,lifeleft);
TextOut(10,35,"
得分:
wsprintfW(Score,L"
%d"
Score_Me);
SetTe