




已阅读5页,还剩15页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
目 录1. 概述31.1 实训项目简介31.2 实训功能说明31.2.1 基本功能31.2.2 附加功能32. 相关技术42.1 Windows定时器技术42.2 透明贴图实现技术42.3 CObList链表52.4获取矩形区域62.5使用AfxMessageBox显示游戏过程中的提示信息62.6内存释放62.7 CImageList处理爆炸效果62.8对话框的应用63. 总体设计与详细设计73.1 系统模块划分73.2 主要功能模块83.2.1 系统对象类图83.2.2 系统主程序活动图93.2.3 系统部分流程图94. 编码实现124.1 绘制游戏背景位图程序124.2 飞机大战游戏对象的绘制程序134.3 飞机大战游戏对象战机位置的动态控制154.4 飞机大战游戏对象之间的碰撞实现174.5 游戏界面输出当前信息195. 项目程序测试205.1战机移动及子弹发射模块测试205.2 敌机及炸弹模块测试205.3 爆炸模块测试206. 实训中遇到的主要问题及解决方法217. 实训体会211. 概述1.1 实训项目简介本次实训项目是做一个飞机大战的游戏,应用MFC编程,完成一个界面简洁流畅、游戏方式简单,玩起来易于上手的桌面游戏。该飞机大战项目运用的主要技术即是MFC编程中的一些函数、链表思想以及贴图技术。1.2 实训功能说明1.2.1 基本功能(1)设置一个战机具有一定的速度,通过键盘,方向键可控制战机的位置,空格键发射子弹。(2)界面中敌机出现的位置,以及敌机炸弹的发射均为随机的,敌机与敌机炸弹均具有一定的速度,且随着关卡难度的增大,数量和速度均增加。(3)对于随机产生的敌机和敌机炸弹,若超过矩形区域,则释放该对象。(4)添加爆炸效果,包括战机子弹打中敌机爆炸、敌机炸弹打中战机爆炸、战机与敌机相撞爆炸以及战机子弹与敌机炸弹相撞爆炸四种爆炸效果。且爆炸发生后敌机、子弹、炸弹均消失,战机生命值减一。1.2.2 附加功能(1) 为游戏界面添加了背景图片,并在战机发射子弹、战机击中敌机、敌机击中战机、以及战机敌机相撞时均添加了背景音效。(2)为游戏设置了不同的关卡,每个关卡难度不同,敌机与敌机炸弹的速度随着关卡增大而加快,进入第二关以后敌机从上下方均会随机出现,且随机发射炸弹。(3)第一关卡敌机从上方飞出,速度一定,战机每打掉一直敌机则增加一分,每积十分,则为战机增加一个生命值,当战机得分超过50分则可进入下一关;进入第二、三关时敌机速度加快,分别从上下两方飞出,此时战机每得分20、30分,才会增加一个生命值,得分超过100、150分则进入下一关、通关。(4) 在游戏界面输出当前游戏进行信息,包括当前得分、当前关卡以及击中敌机数量。(5)增加了鼠标控制战机位置这一效果,战绩的位置随着鼠标的移动而移动,并且点击鼠标左键可使得战机发射子弹。(6)实现了暂停游戏的功能,玩家可通过键盘上的Z键,对游戏进行暂停。(7)通过对话框的弹出可提示玩家是否查看游戏说明、是否进入下一关、是否重新开始等消息,使得玩家可自己选择。2. 相关技术2.1 Windows定时器技术Windows定时器是一种输入设备,它周期性地在每经过一个指定的时间间隔后就通知应用程序一次。程序将时间间隔告诉Windows,然后Windows给您的程序发送周期性发生的WM_TIMER消息以表示时间到了。本程序中使用多个定时器,分别控制不同的功能。在MFC的API函数中使用SetTimer()函数设置定时器,设置系统间隔时间,在OnTimer()函数中实现响应定时器的程序。2.2 透明贴图实现技术绘制透明位图的关键就是创建一个“掩码”位图(mask bitmap),这个“掩码”位图是一个单色位图,它是位图中图像的一个单色剪影。在详细介绍实现过程之前先介绍下所使用的画图函数以及函数参数所代表的功能;整个绘制过程需要使用到BitBlt()函数。整个功能的实现过程如下: (1) 创建一张大小与需要绘制图像相同的位图作为“掩码”位图;(2) 将新创建的“掩码”位图存储至掩码位图的设备描述表中;(3) 把位图设备描述表的背景设置成“透明色”,不需要显示的颜色;(4) 复制粘贴位图到“掩码”位图的设备描述表中,这个时候“掩码”位图设备描述表中存放的位图与位图设备描述表中的位图一样;(5) 把需要透明绘制的位图与对话框绘图相应区域的背景进行逻辑异或操作绘制到对话框上;(6) 把“掩码”位图与这个时候对话框相应区域的背景进行逻辑与的操作;(7) 重复步骤5的操作,把需要透明绘制的位图与对话框绘图相应区域的背景进行逻辑异或操作绘制到对话框上;(8) 最后把系统的画笔还给系统,删除使用过的GDIObject,释放非空的指针,最后把新建的设备描述表也删除。2.3 CObList链表MFC类库中提供了丰富的CObList类的成员函数,此程序主要用到的成员函数如下:(1) 构造函数,为CObject指针构造一个空的列表。(2) GetHead(),访问链表首部,返回列表中的首元素(列表不能为空)。(3) AddTail(),在列表尾增加一个元素或另一个列表的所有元素。(4) RemoveAll(),删除列表中所有的元素。(5) GetNext(),返回列表中尾元素的位置。(6) GetHeadPosition(),返回列表中首元素的位置。(7) RemoveAt(),从列表中删除指定位置的元素。(8) GetCount(),返回列表中的元素数。在CPlaneGameView.h文件中声明各游戏对象与游戏对象链表:(1)/创建各游戏对象CMyPlane *myplane;CEnemy *enemy;CBomb *bomb;CBall *ball;CExplosion *explosion;(2)/创建存储游戏对象的对象链表CObList ListEnemy;CObList ListMe;CObList ListBomb;CObList ListBall;CObList ListExplosion;2.4获取矩形区域首先,使用CRect定义一个对象,然后使用GetClientRect(&对象名)函数,获取界面的矩形区域rect.Width() 为矩形区域的宽度,rect.Height()为矩形区域的高度。使用IntersectRect(&,&)函数来判断两个源矩形是否有重合的部分。如果有不为空,则返回非零值;否则,返回0。2.5使用AfxMessageBox显示游戏过程中的提示信息AfxMessageBox()是模态对话框,你不进行确认时程序是否往下运行时,它会阻塞你当前的线程,除非你程序是多线程的程序,否则只有等待模态对话框被确认。在MFC中,afxmessagebox是全局的对话框最安全,也最方便。2.6内存释放在VC/MFC用CDC绘图时,频繁的刷新,屏幕会出现闪烁的现象,CPU时间占用率相当高,绘图效率极低,很容易出现程序崩溃。及时的释放程序所占用的内存资源是非常重要的。在程序中使用到的链表、刷子等占用内存资源的对象都要及时的删除。Delete Brush,List.removeall()等。2.7 CImageList处理爆炸效果爆炸效果是连续的显示一系列的图片。如果把每一张图片都显示出来的话,占用的时间是非常多的,必然后导致程序的可行性下降。CImageList是一个“图象列表”是相同大小图象的集合,每个图象都可由其基于零的索引来参考。可以用来存放爆炸效果的一张图片,使用Draw()函数来绘制在某拖拉操作中正被拖动的图象,即可连续绘制出多张图片做成的爆炸效果。2.8对话框的应用在设置游戏难度、炸弹的速度等,使用对话框进行设置非常方便,又体现出界面的友好。对话框的应用过程如下:(1). 资源视图下,添加Dialog对话框。然后添加使用到的控件,并修改控件的ID以便于后面的使用。(2). 为对话框添加类,在对话框模式下,点击项目,添加类。(3). 在类视图中,为对话框类添加成员变量(控件变量)。设置变量的名称、类型、最值等信息。(4). 在资源视图菜单中,选择相应的菜单项,右击添加时间监听程序,设置函数处理程序名称。(5). 在处理程序函数中添加相应的信息。3. 总体设计与详细设计3.1 系统模块划分该飞机大战游戏程序分为游戏背景位图绘制模块、各游戏对象绘制模块、游戏对象之间的碰撞模块、爆炸效果产生模块、游戏界面输出玩家得分关卡信息模块。其中在游戏对象绘制模块中,战机是唯一对象,在游戏开始时产生该对象,赋予其固定的生命值,当其与敌机对象、敌机炸弹碰撞时使其生命值减一,直至生命值为零,便删除战机对象。敌机对象与敌机炸弹对象的绘制中采用定时器技术,定时产生。爆炸对象初始化为空,当游戏过程中即时发生碰撞时,在碰撞位置产生爆炸对象,添加到爆炸链表中。3.2 主要功能模块3.2.1 系统对象类图CGameObject是各个游戏对象的抽象父类,继承自CObject类,其他的类:战机类、敌机类、爆炸类、子弹类、炸弹类、文字类都继承了此类。每个游戏对象类中既继承了来自父类CGameObject的属性,又有自己的特有属性和方法。3.2.2 系统主程序活动图3.2.3 系统部分流程图(1) 该飞机大战游戏执行流程图:(2) 利用定时器定时产生敌机并绘制敌机流程图4. 编码实现4.1 绘制游戏背景位图程序 CDC *pDC=GetDC();/获得矩形区域对象CRect rect;GetClientRect(&rect);/设备环境对象类-CDC类。CDC cdc;/内存中承载临时图像的位图CBitmap bitmap1;/该函数创建一个与指定设备兼容的内存设备上下文环境(DC)cdc.CreateCompatibleDC(pDC);/该函数创建与指定的设备环境相关的设备兼容的位图。bitmap1.CreateCompatibleBitmap(pDC,rect.Width(),rect.Height();/该函数选择一对象到指定的设备上下文环境中,该新对象替换先前的相同类型的对象。CBitmap *pOldBit=cdc.SelectObject(&bitmap1);/用固定的固体色填充文本矩形框cdc.FillSolidRect(rect,RGB(51,255,255);/添加背景图片CBitmap bitmap_BackGround;bitmap_BackGround.LoadBitmap(IDB_BACKGROUND);BITMAP bimap2;/位图图像bitmap_BackGround.GetBitmap(&bimap2);CDC cdc_BackGround;/定义一个兼容的DCcdc_BackGround.CreateCompatibleDC(&cdc);/创建DCCBitmap*Old=cdc_BackGround.SelectObject(&bitmap_BackGround);cdc.StretchBlt(0,0,rect.Width(),rect.Height(),&cdc_BackGround,0,0,bimap2.bmWidth,bimap2.bmHeight,SRCCOPY);4.2 飞机大战游戏对象的绘制程序/画战机对象(唯一)if(myplane!= NULL)myplane-Draw(&cdc,TRUE);/设置定时器,随机添加敌机,敌机随机发射炸弹,此时敌机速度与数量和关卡有关 SetTimer(2,300,NULL);/敌机产生的定时器SetTimer(3,500,NULL);/敌机炸弹产生的定时器if(myplane!=NULL& is_Pause = 0)switch(nIDEvent)case 2:/设置定时器产生敌机if(pass_Num = 1)/第一关int motion =1;/设置敌机的方向,从上方飞出CEnemy *enemy=new CEnemy(motion);ListEnemy.AddTail(enemy);/随机产生敌机/ifelse if(pass_Num = 2)/第一关以后的关卡int motion1 = 1;/设置敌机的方向,从上方飞出CEnemy *enemy1=new CEnemy(motion1);enemy1-SetSpeed_en(rand()%5 +1)* pass_Num);ListEnemy.AddTail(enemy1);/随机产生敌机int motion2 = -1;/设置敌机的方向,从下方飞出CEnemy *enemy2=new CEnemy(motion2);enemy2-SetSpeed_en(rand()%5 +1)* pass_Num);ListEnemy.AddTail(enemy2);/随机产生敌机/else if/casebreak;/switch/判断产生的敌机是否出界,若已经出界,则删除该敌机POSITION posEn=NULL,posEn_t=NULL;posEn=ListEnemy.GetHeadPosition();int motion = 1;while(posEn!=NULL)posEn_t=posEn;CEnemy *enemy= (CEnemy *)ListEnemy.GetNext(posEn);/判断敌机是否出界if(enemy-GetPoint().xGetPoint().xrect.right|enemy-GetPoint().yGetPoint().yrect.bottom) ListEnemy.RemoveAt(posEn_t);delete enemy;/ifelseenemy-Draw(&cdc,TRUE);switch(nIDEvent)case 3:/设置定时器产生敌机炸弹CBall*ball=newCBall(enemy-GetPoint().x+17,enemy-GetPoint().y+30,enemy-GetMotion();ListBall.AddTail(ball);/casebreak;/switch/else/while/判断产生的敌机炸弹是否出界,若已经出界,则删除该敌机炸弹POSITION posball=NULL,posball_t=NULL;posball= ListBall.GetHeadPosition();while(posball!=NULL)posball_t=posball; ball= (CBall *) ListBall.GetNext(posball);if( ball-GetPoint().xGetPoint().xrect.right| ball-GetPoint().yGetPoint().yrect.bottom) ListBall.RemoveAt(posball_t);delete ball;/ifelse ball-Draw(&cdc,1);/else/while/if4.3 飞机大战游戏对象战机位置的动态控制if(myplane!= NULL)myplane-Draw(&cdc,TRUE);/获得键盘消息,战机位置响应,战机速度speed为30if(GetKeyState(VK_UP) 0 | GetKeyState(W) GetPoint().ySetPoint( myplane-GetPoint().x,rect.bottom);elsemyplane-SetPoint(myplane-GetPoint().x,( myplane-GetPoint().y - speed) );/ifif(GetKeyState(VK_DOWN) 0| GetKeyState(S) 0)& is_Pause= 0)/下方向键/ifif(GetKeyState(VK_LEFT) 0| GetKeyState(A) 0)& is_Pause= 0)/左方向键/ifif(GetKeyState(VK_RIGHT) 0| GetKeyState(D) 0)& is_Pause= 0)/右方向键/ifif(GetKeyState(VK_SPACE)GetPoint().x, myplane-GetPoint().y,1);ListBomb.AddTail(BombOne);CBomb*BombTwo=newCBomb(myplane-GetPoint().x+35, myplane-GetPoint().y,1);ListBomb.AddTail(BombTwo);PlaySound(LPCTSTR)IDR_WAVE2,AfxGetInstanceHandle(),SND_RESOURCE |SND_ASYNC);/ifif(GetKeyState(Z)SetPoint(point.x,point.y);/鼠标控制战机,发射战机子弹void CPlaneGameView:OnLButtonDown(UINT nFlags, CPoint point)/ TODO: 在此添加消息处理程序代码和/或调用默认值CView:OnLButtonDown(nFlags, point);if( is_Pause = 0)CBomb *BombOne=new CBomb( myplane-GetPoint().x, myplane-GetPoint().y,1);PlaySound(LPCTSTR)IDR_WAVE2, AfxGetInstanceHandle(), SND_RESOURCE |SND_ASYNC);ListBomb.AddTail(BombOne);CBomb *BombTwo=new CBomb( myplane-GetPoint().x+35, myplane-GetPoint().y,1);ListBomb.AddTail(BombTwo);4.4 飞机大战游戏对象之间的碰撞实现本飞机大战游戏中的碰撞考虑了飞机子弹打中敌机、敌机炸弹打中战机、战机与敌机相撞、敌机炸弹与战机子弹相撞四种情况,根据游戏对象的矩形区域是否有交叉,而确认两者是否相撞,而产生爆炸对象,添加到爆炸链表中。以战机与敌机相撞为例:if(myplane != NULL& is_Pause= 0)POSITION enemyPos,enemyTemp;for(enemyPos= ListEnemy.GetHeadPosition();(enemyTemp=enemyPos)!=NULL;) enemy =(CEnemy *) ListEnemy.GetNext(enemyPos); /获得敌机的矩形区域 CRect enemyRect = enemy-GetRect(); /获得战机的矩形区域 CRect myPlaneRect = myplane-GetRect(); /判断两个矩形区域是否有交接 CRect tempRect; if(tempRect.IntersectRect(&enemyRect,myPlaneRect)CExplosion *explosion = new CExplosion( enemy-GetPoint().x+18 , enemy-GetPoint().y + 18);PlaySound(LPCTSTR)IDR_WAVE,AfxGetInstanceHandle(), SND_RESOURCE |SND_ASYNC);ListExplosion.AddTail(explosion);/战机生命值减一lifeNum_Me-;/删除敌机 ListEnemy.RemoveAt(enemyTemp);delete enemy;if(lifeNum_Me = 0)/删除战机对象delete myplane;myplane=NULL;/ifbreak;/if/for/if战机子弹打中敌机、敌机炸弹打中战机以及战机子弹与敌机炸弹对象的碰撞实现同上。4.5 游戏界面输出当前信息if(myplane != NULL& is_Pause= 0)HFONT font;font=CreateFont(20,10,0,0,0,0,0,0,0,0,0,100,10,0);cdc.SelectObject(font);CString str;cdc.SetTextColor(RGB(255,0,0);str.Format(_T(当前关卡:%d),pass_Num);cdc.TextOutW(10,20,str);str.Format(_T(当前得分:%d),score_Me);cdc.TextOutW(10,40,str);str.Format(_T(剩余生命:%d),lifeNum_Me);cdc.TextOutW(10,60,str); /ifif(myplane !=NULL & lifeNum_Me 0)if(score_Me 10*count_Life*pass_Num)lifeNum_Me+;/生命值加1count_Life+;/已增加生命值加1游戏进入下一关,以及结束游戏界面设计代码与上类似。5. 项目程序测试5.1战
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 建筑街道改造方案(3篇)
- 管道金属封堵定制方案(3篇)
- 土建投标备选方案(3篇)
- 家具搬运装卸方案模板(3篇)
- 楼层地面保洁方案(3篇)
- 科学小实验讲课件
- 期刊论文怎么
- 小学六年级心理健康教育记录
- 课题的研究思路咋写
- 心理健康类论文
- 广东省珠海市金湾区2023-2024学年七年级下学期期末考试生物试题(无答案)
- 2024年湖南中考化学试卷及答案
- DL-T-300-2011火电厂凝气器管防腐防垢导则
- 何家弘法律英语第四版翻译完整版
- 机修钳工实训室整体方案及流程
- 2024年中考地理简答题答题模板
- 农村自建房施工安全建议
- 2024助贷委托服务协议合同模板
- 2024年湖北省丹江口市初中毕业生适应性考试地理·生物试题
- 承包商安全管理培训课件
- 学校体检服务投标方案(技术方案技术标)
评论
0/150
提交评论