mfc飞机大战课程设计文档.docx
- 文档编号:4187873
- 上传时间:2022-11-28
- 格式:DOCX
- 页数:22
- 大小:97.50KB
mfc飞机大战课程设计文档.docx
《mfc飞机大战课程设计文档.docx》由会员分享,可在线阅读,更多相关《mfc飞机大战课程设计文档.docx(22页珍藏版)》请在冰豆网上搜索。
mfc飞机大战课程设计文档
程序设计综合实践报告
姓名
田梦涛
学号
201301051923
班级
软件13-3
项目名称
飞机大战
实习地点
J-13
实习时间
16、17周
实习成绩
指导教师签字
信息科学与工程学院
年月日
1.概述
飞机大战游戏是基于Windows桌面的射击类游戏,其需要实现的功能为:
实现游戏对象的爆炸特效、文字提示功能和界面背景特效,其主要是遵循一定的游戏规则进行游戏。
游戏中的主要角色可分为如下几个基本部分:
战机、敌机(普通敌机、小BOSS和大BOSS)、战机的导弹、敌机的子弹。
其主要遵循的游戏规则为:
战机数量为1,由玩家通过键盘控制(方向键控制位置、空格键发射导弹)战机;导弹释放存在间隔,有一定的运行速度;导弹遇到敌机发生爆炸,敌机被炸毁,导弹消失,玩家得分;由计算机控制敌机自动向战机发动攻击;敌机数量可以根据难度大小随机生成,计算机生成敌机时随机选择类别;敌机从游戏区域的上端进入,左右位置随机;普通敌机被导弹攻击即死,作为进入第二关的标志的小BOSS的血量稍多一些但是数量较多发射子弹的频率也较高,第三关中的大BOSS不仅比小BOSS血量更厚而且它发射伞状的子弹;敌机行驶期间,不左右移动,不反向移动;运行线路为直线,方向为从上至下,不可左右移动。
纵向由发射位置起至游戏区域结束;敌机子弹遇到战机时发生爆炸,战机被炸毁,子弹消失,游戏结束。
游戏最后根据功能要求,在大BOSS死亡后会生成客机,被击中引擎后改变飞行轨迹,击中油箱后爆炸,战机还要拯救随机从客机上跳机的乘客。
2.相关技术
此次实训的飞机大战游戏其中的技术主要就是一些函数、双向链表的使用、内存释放和双缓冲技术。
2.1建立基类CGameObject
建立基于所有类的父类CGameObject,其中定义了两个纯虚函数作为继承CGameObject类的其他类的某些声明,例如:
//绘制对象
virtualBOOLDraw(CDC*pDC,BOOLbPause)=0;
还有//获得矩形区域
virtualCRectGetRect()=0;
另外还定义了//获得左上角坐标
CPointGetPoint(){returnm_ptPos;}以及
//加载图像
staticBOOLLoadImage(CImageList&imgList,UINTbmpID,COLORREFcrMask,intcx,intcy,intnInitial);
2.2透明图片贴图
此次实训中用于贴图的函数:
staticBOOLLoadImage(CImageList&imgList,UINTbmpID,COLORREFcrMask,intcx,intcy,intnInitial);//此函数主要用于将图片放入图像链表imageList中。
m_Images.Draw(pDC,0,m_ptPos,ILD_TRANSPARENT); //此函数主要是讲m_Images链表中的图像显示在pDC这个句柄中。
ILD_TRANSPARENT表示是透明贴图。
其中主要就是CImageList图像列表。
它是相同大小图像的一个集合,每个集合中均以0为图像的索引序号基数,图像列表通常由大图标或位图构成,其中包含透明位图模式。
可以利用WINDOWS32位应用程序接口函数API来绘制、建立和删除图像,并能实现增加、删除、替换和拖动图像等操作。
2.3CObList链表
CObListm_ObjList[11];//主要是定义一个CObList类的一个链表对象用于存储所有此种相关的对象,易于后续的添加删除和提取数据。
POSITIONbPos1=NULL,bPos2=NULL;//定义指针
bPos1=m_ObjList[enBall].GetHeadPosition();//指针读取头结点
CBall*pBall=(CBall*)m_ObjList[enBall].GetNext(bPos1);//指针读取下一个节点
2.4获得矩形区域函数
CRectmRect=m_pMe->GetRect();
CRectbRect=pBall->GetRect();
CRecttmpRect;
tmpRect.IntersectRect(&bRect,mRect)//判断矩形是否有交接
CRectGetRect(){
returnCRect(m_ptPos,CPoint(m_ptPos.x+ENEMY_HEIGHT,m_ptPos.y+ENEMY_HEIGHT));
}//例子为获得敌机的矩形区域
2.5发射子弹或导弹函数
BOOLCMyPlane:
:
Fired()
{
if(m_nWait==0)
returnTRUE;
else
returnFALSE;
}其中的m_nWait未定义的发射延时变量,即在Draw中m_nWait++;
if(m_nWait>3)
m_nWait=0;可以控制子弹定时发射
2.6添加爆炸效果技术
其实是一种链表的灵活运用,m_ObjList[enExplosion].AddTail(newCExplosion(mRect.left,mRect.top));设置一个放有爆炸对象的链表,在使用的时候直接NEW一个爆炸对象添加到该链表中方便又实用。
2.7对于对象的绘制以及越出边界的处理
//绘制导弹、爆炸、敌机、子弹
for(inti=0;i<11;i++)
{
POSITIONpos1,pos2;
for(pos1=m_ObjList[i].GetHeadPosition();(pos2=pos1)!
=NULL;)
{
CGameObject*pObj=(CGameObject*)m_ObjList[i].GetNext(pos1);
if(!
pObj->Draw(pMemDC,FALSE))
{
m_ObjList[i].RemoveAt(pos2);
deletepObj;
}
}
}对于所有链表进行遍历,定义Draw函数,并在Draw函数中对于越出边界的对象在FALSE是进行m_ObjList[i].RemoveAt(pos2);删除。
实例:
对于敌机的绘制
BOOLCEnemy:
:
Draw(CDC*pDC,BOOLbPause)
{
m_nWait++;
if(m_nWait>20)
m_nWait=0;
if(!
bPause)
{
m_ptPos.y=m_ptPos.y+m_nMotion*m_V;
}
if(m_ptPos.y>GAME_HEIGHT+ENEMY_HEIGHT)
returnFALSE;
if(m_ptPos.y<-ENEMY_HEIGHT)
returnFALSE;
m_Images.Draw(pDC,m_nImgIndex,m_ptPos,ILD_TRANSPARENT);
returnTRUE;
}
2.8字体的个性化输出函数
CRecttc;
CFontnfont;
HFONToldfont;
pMemDC->SetBkMode(TRANSPARENT);
nfont.CreatePointFont(280,_T("正楷"),pMemDC);
oldfont=(HFONT)pMemDC->SelectObject(nfont);
pMemDC->SetTextColor(255*256);
pMemDC->SetBkMode(TRANSPARENT);//设置绘图dc的背景模式为透明模式
pMemDC->SetTextAlign(TA_CENTER);//设置基准点与限定矩形的中心水平对齐
pMemDC->TextOut(GAME_WIDTH/10,GAME_HEIGHT/8,_T("SCORE:
"));
CStringSCORE_STR;
SCORE_STR.Format(_T("%d"),score);
pMemDC->TextOut(GAME_WIDTH/10+100,GAME_HEIGHT/8,SCORE_STR);
2.9获取键盘操作函数
//获得键的状态1->down
intGetKey(intnVirtKey)
{
return(GetKeyState(nVirtKey)&0x8000)?
1:
0;
}
2.10用键盘控制战机的移动
//检测四个方向键,移动战机
for(inti=0;i<4;i++)
{
intnMeMotion=0;
m_pMe->SetVerMotion(0);
m_pMe->SetHorMotion(0);
nMeMotion=GetKey(VK_UP);
if(nMeMotion==1)
m_pMe->SetVerMotion
(1);
nMeMotion=GetKey(VK_DOWN);
if(nMeMotion==1)
m_pMe->SetVerMotion(-1);
nMeMotion=GetKey(VK_RIGHT);
if(nMeMotion==1)
m_pMe->SetHorMotion
(1);
nMeMotion=GetKey(VK_LEFT);
if(nMeMotion==1)
m_pMe->SetHorMotion(-1);
}
在MyPlane类中定义了:
intm_nHorMotion;//飞机水平运行方向0->静止,1->右-1->左
intm_nVerMotion;//飞机垂直运行方向0->静止,1->上-1->下
voidSetHorMotion(intnMotion)
{
m_nHorMotion=nMotion;
}
intGetHorMotion()const
{
returnm_nHorMotion;
}
voidSetVerMotion(intnMotion)
{
m_nVerMotion=nMotion;
}
intGetVerMotion()const
{
returnm_nVerMotion;
}
2.11设置定时器
定时器告诉WINDOWS一个时间间隔,然后WINDOWS以此时间间隔周期性触发程序。
通常有两种方法来实现:
发送WM_TIMER消息和调用应用程序定义的回调函数。
SetTimer(1,30,NULL); //设置每30毫秒刷新一次
通过定时器可以控制游戏对象的自行移动以及某些定时控制的实现。
2.12双缓冲技术
关于双缓冲技术主要就是利用缓存的原理进行将所有的东西都先存在一个缓冲得虚拟的区域,然后再一次性的将所有的虚拟缓存中的东西都放入实在的存储器中。
CDC*pDC=GetDC(); CDC dcMem;
dcMem.CreateCompatibleDC(pDC);//依附窗口DC创建兼容内存DC 依次,所有的图像
文字均存入dcMem中,然后一次性的通过pDC->BitBlt(0,0,rc.Width(),rc.Height(),&dcMem,0,0,SRCCOPY);将内存上的图像拷贝到前台。
dcMem.DeleteDC();
bmp.DeleteObject();
ReleaseDC(pDC);
dcMem.FillSolidRect(rc,RGB(255,255,255));
2.13内存释放技术
在此次实训项目中有太多的对象的生成和运用,造成了内存的极度的紧张,当游戏进行到一定的程度的时候就会出现内存溢出现象。
解决此问题的技术就是内存释放。
内存释放技术的实现主要是通过释放各个满足一定条件的对象和链表来实现的,
//删除子弹
m_ObjList[enBOSSBomb].RemoveAt(bbPos2);//用于删除指针
deletepBomb;//用于删除对象
3.需求分析
●3.1功能需求分析
功能类别
子功能
游戏基本规则
飞机对战规则
游戏特效
界面背景特效
游戏对象特效
声音特效
文字提示
4.总体设计与详细设计
有三个主要的部分组成,分别是规则子系统、游戏对象子系统。
系统的总体结构图如下:
该子系统主要是实现飞机大战各项游戏规则。
实现了需求中的游戏规则。
组成结构如下图所示:
这个系统包含1个重要的模块,人工智能,它实现了敌机对战机的攻击以及游戏对象碰撞监测规则,其实实现的是代表计算机方玉玩家进行对战。
✧攻击规则
⏹敌机在战机上方或下方时发射炸弹,炸弹从下至上或从上至下射向战机
⏹攻击时发出声音
✧碰撞规则
⏹导弹或炸弹本身的矩形区域和敌机或战机的矩形区域相交时,表示导弹或炸弹射中了战机或敌机
⏹战机被炸毁,游戏结束。
⏹敌机被炸毁,战机10分,出现文字提示。
⏹爆炸时产生声音
游戏对象子系统包含了各个游戏对象的实现,它实现了需求中的部分规则以及游戏特效。
本子系统的组织结构图如下:
✧应用程序对象
●游戏程序的加载
●游戏对象的绘制
●游戏规则的调用
●玩家的键盘事件获取
✧游戏对象
●敌机图像加载
●敌机贴图
●位置存储
4.1系统模块划分
游戏规则子系统
模块名称
功能简述
人工智能
人机对战规则的实现
游戏子系统
模块名称
功能简述
应用程序对象
游戏程序的加载、游戏对象的绘制、游戏规则的调用、玩家的键盘事件获取
游戏对象
各个游戏对象的抽象父类
战机对象
战机类
敌机对象
敌机类
导弹对象
导弹类
炸弹对象
炸弹类
爆炸对象
爆炸类
文字对象
文字类
其简单类图如下:
4.2主要功能模块
主要功能模块主要就是那些类的功能模块,主要有:
1、人工智能模块用来定义人机对战规则。
2、应用程序对象模块用来对游戏程序的加载、游戏对象的绘制、游戏规则的调用、玩家的键盘事件获取。
3、游戏对象模块是各个游戏对象的抽象父类。
4、战机对象模块是战机类,用来完成战机图像加载、贴图、位置存储。
5、敌机对象模块时用来完成敌机图像加载、贴图、位置存储。
6、导弹对象模块时用来完成战机导弹图像加载、贴图、位置存储。
7、爆炸对象模块时用来完成爆炸效果图像加载、贴图、位置存储。
8、敌机子弹对象模块时用来完成敌机子弹图像加载、贴图、位置存储。
9、文字对象模块时用来完成文字的图像加载、贴图、位置存储。
10、敌机、子弹和战机、导弹的碰撞检测模块。
11、背景添加模块。
12、游戏关卡游戏难易度设置和游戏关卡选择。
13、游戏得分和生命值控制以及游戏关卡进入控制和游戏结束。
4.3扩展功能设计思路
本次实训由于时间问题还有些扩展功能可进行增加,主要有:
1给游戏增加敌机类型,丰富画面,增加难度。
2、给游戏进行增加boss,通过boss的添加进行游戏的关卡和难度的更加进一步的提升。
主要思路是:
再增加一个类让它继承敌机类,然后再敌机类的基础上进行增加其生命值和被打死后的得分。
当战机得分到达一定的值以后boss出现并进行和敌机一个队伍发射另类的子弹进行攻击战机。
3、完善暂停/重新开始/继续游戏等功能。
4、设置关卡,关卡越往后,难度越大,增加游戏的挑战性。
5、增添多种游戏道具产生各种效果从而增加游戏的趣味性。
主要思路:
可以设计增加新的道具类并让其继承敌机类在满足一定条件时随机从游戏上方落下然后检测道具与战机的碰撞,然后实现道具功能即可。
6、增加一些战机的技能以及男足这些技能所需的条件例如蓝值、能量等模块。
4.4软件结构设计体会
个人认为可以将敌机类、导弹类、道具类等继承CGameObject类的所有类设计成大体规格相同的形式,然后对于View中的函数等模块加以注释区分,将类结构明显的突出出来以便于扩充新功能,其次若要改为通用对战类游戏,只需改变贴图,某些函数的参数使移动轨迹改变,然后对游戏框架进行合理的,灵活的运用。
5.编码实现
5.1游戏初始创建
BOOLCPlaneGameView:
:
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
m_pMemDC->SelectObject(m_pMemBitmap);
CMyPlane:
:
LoadImage();
CEnemy:
:
LoadImage();
CBomb:
:
LoadImage();
CBall:
:
LoadImage();
CExplosion:
:
LoadImage();
CBOSS1:
:
LoadImage();
CBOSS2:
:
LoadImage();
CBOSSBomb:
:
LoadImage();
CAirLiner:
:
LoadImage();
CPassenger:
:
LoadImage();
CBallProp:
:
LoadImage();
CBLOODPROP:
:
LoadImage();
//产生主角(战机)
m_pMe=newCMyPlane;
//启动游戏
SetTimer(1,30,NULL);
returnTRUE;
}
5.2游戏结束处理
voidCPlaneGameView:
:
StopGame()
{
deletem_pMe;
deletem_pMemDC;
deletem_pDC;
deletem_pMemBitmap;
}
5.3背景设定
boolCPlaneGameView:
:
DrawBlack(CDC*pDC,UINTbmpID,CRectDestRect,intpos)
{
CBitmapbitmap;
bitmap.LoadBitmap(bmpID);
BITMAPBitMap;
bitmap.GetBitmap(&BitMap);
CDCdcMem;
dcMem.CreateCompatibleDC(pDC);
dcMem.SelectObject(&bitmap);
pDC->StretchBlt(DestRect.left,DestRect.top,DestRect.Width(),DestRect.Height(),&dcMem,0,-pos,BitMap.bmWidth,BitMap.bmHeight,SRCCOPY);
pDC->StretchBlt(DestRect.left,DestRect.top,DestRect.Width(),DestRect.Height(),&dcMem,0,BitMap.bmHeight-pos,BitMap.bmWidth,BitMap.bmHeight,SRCCOPY);
returntrue;
}
voidCPlaneGameView:
:
UpdateFrame(CDC*pMemDC)
{
//绘制背景
CRectrect;
CRectrc;
GetClientRect(&rect);
DrawBlack(pMemDC,IDB_BEIJING3,rect,pos);
}
在定时器中可以实现背景的滚动
TimerCount++;
pos++;
if(pos>600)//背景宽度为640,故640为一个周期
pos=0;
5.4创建游戏对象
//绘制我方战机
m_pMe->Draw(m_pMemDC,FALSE);
staticintnCreator=rand()%5+10;
//随机产生敌机
if(nCreator<=0/*&&score<=20*/)
{
nCreator=rand()%5+(int)25-level;
m_ObjList[enEnemy].AddTail(newCEnemy);
}
nCreator--;
//添加boss1
if(score>10&&ctr1<0)
{
ctr1=rand()%5+40;
m_ObjList[enBOSS1].AddTail(newCBOSS1);
}
ctr1--;
//添加boos2
if(score>50&&ctr13<0)
{
m_ObjList[enBOSS2].AddTail(newCBOSS2);
ctr13=200;
}
ctr13--;
//添加客机
if(score>100&&ctr11<0)
{
m_ObjList[enAir].AddTail(newCAirLiner);
ctr11=300;
}
ctr11--;
//添加子弹包
if(BULLET<=100&&ctr12<0)
{
ctr12=rand()%5+40;
m_ObjList[enBallProp].AddTail(newCBallProp);
}
ctr12--;
//添加生命包
if(BLOOD<=20&&ctr12<0)
{
ctr12=rand()%5+40;
m_ObjList[enBLOODPROP].AddTail(newCBLOODPROP);
}
ctr12--;
5.4战机技能的创建
//全屏秒杀
if(GetKey('C')==1)//按下了C键
{
for(inti=0;i<=10000;i++)
{
POSITIONePos1=NULL,ePos2=NULL;
for(ePos1=m_ObjList[enEnemy].GetHeadPosition();(ePos2=ePos1)!
=NULL;)
{
CEnemy*pEnemy=(CEnemy*)m_ObjList[enEnemy].GetNext(ePos1);
CRectmRect=pEnemy->GetRect();
CRec
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- mfc 飞机 大战 课程设计 文档