c++飞机大战实训报告附带码.docx
《c++飞机大战实训报告附带码.docx》由会员分享,可在线阅读,更多相关《c++飞机大战实训报告附带码.docx(12页珍藏版)》请在冰豆网上搜索。
c++飞机大战实训报告附带码
1.概述3
实训项目简介3
实训功能说明3
基本功能3
附加功能3
2.相关技术4
Windows定时器技术4
透明贴图实现技术4
CObList链表5
获取矩形区域6
使用AfxMessageBox显示游戏过程中的提示信息6
内存释放6
CImageList处理爆炸效果6
对话框的应用6
3.总体设计与详细设计7
系统模块划分7
主要功能模块8
系统对象类图8
系统主程序活动图9
系统部分流程图9
4.编码实现12
绘制游戏背景位图程序12
飞机大战游戏对象的绘制程序13
飞机大战游戏对象战机位置的动态控制15
飞机大战游戏对象之间的碰撞实现17
游戏界面输出当前信息19
5.项目程序测试20
战机移动及子弹发射模块测试20
敌机及炸弹模块测试20
爆炸模块测试20
6.实训中遇到的主要问题及解决方法21
7.实训体会21
1.概述
实训项目简介
本次实训项目是做一个飞机大战的游戏,应用MFC编程,完成一个界面简洁流畅、游戏方式简单,玩起来易于上手的桌面游戏。
该飞机大战项目运用的主要技术即是MFC编程中的一些函数、链表思想以及贴图技术。
实训功能说明
基本功能
(1)设置一个战机具有一定的速度,通过键盘,方向键可控制战机的位置,空格键发射子弹。
(2)界面中敌机出现的位置,以及敌机炸弹的发射均为随机的,敌机与敌机炸弹均具有一定的速度,且随着关卡难度的增大,数量和速度均增加。
(3)对于随机产生的敌机和敌机炸弹,若超过矩形区域,则释放该对象。
(4)添加爆炸效果,包括战机子弹打中敌机爆炸、敌机炸弹打中战机爆炸、战机与敌机相撞爆炸以及战机子弹与敌机炸弹相撞爆炸四种爆炸效果。
且爆炸发生后敌机、子弹、炸弹均消失,战机生命值减一。
附加功能
(1)为游戏界面添加了背景图片,并在战机发射子弹、战机击中敌机、敌机击中战机、以及战机敌机相撞时均添加了背景音效。
(2)为游戏设置了不同的关卡,每个关卡难度不同,敌机与敌机炸弹的速度随着关卡增大而加快,进入第二关以后敌机从上下方均会随机出现,且随机发射炸弹。
(3)第一关卡敌机从上方飞出,速度一定,战机每打掉一直敌机则增加一分,每积十分,则为战机增加一个生命值,当战机得分超过50分则可进入下一关;进入第二、三关时敌机速度加快,分别从上下两方飞出,此时战机每得分20、30分,才会增加一个生命值,得分超过100、150分则进入下一关、通关。
(4)在游戏界面输出当前游戏进行信息,包括当前得分、当前关卡以及击中敌机数量。
(5)增加了鼠标控制战机位置这一效果,战绩的位置随着鼠标的移动而移动,并且点击鼠标左键可使得战机发射子弹。
(6)实现了暂停游戏的功能,玩家可通过键盘上的‘Z’键,对游戏进行暂停。
(7)通过对话框的弹出可提示玩家是否查看游戏说明、是否进入下一关、是否重新开始等消息,使得玩家可自己选择。
2.相关技术
Windows定时器技术
Windows定时器是一种输入设备,它周期性地在每经过一个指定的时间间隔后就通知应用程序一次。
程序将时间间隔告诉Windows,然后Windows给您的程序发送周期性发生的WM_TIMER消息以表示时间到了。
本程序中使用多个定时器,分别控制不同的功能。
在MFC的API函数中使用SetTimer()函数设置定时器,设置系统间隔时间,在OnTimer()函数中实现响应定时器的程序。
透明贴图实现技术
绘制透明位图的关键就是创建一个“掩码”位图(maskbitmap),这个“掩码”位图是一个单色位图,它是位图中图像的一个单色剪影。
在详细介绍实现过程之前先介绍下所使用的画图函数以及函数参数所代表的功能;整个绘制过程需要使用到BitBlt()函数。
整个功能的实现过程如下:
(1)创建一张大小与需要绘制图像相同的位图作为“掩码”位图;
(2)将新创建的“掩码”位图存储至掩码位图的设备描述表中;
(3)把位图设备描述表的背景设置成“透明色”,不需要显示的颜色;
(4)复制粘贴位图到“掩码”位图的设备描述表中,这个时候“掩码”位图设备描述表中存放的位图与位图设备描述表中的位图一样;
(5)把需要透明绘制的位图与对话框绘图相应区域的背景进行逻辑异或操作绘制到对话框上;
(6)把“掩码”位图与这个时候对话框相应区域的背景进行逻辑与的操作;
(7)重复步骤5的操作,把需要透明绘制的位图与对话框绘图相应区域的背景进行逻辑异或操作绘制到对话框上;
(8)最后把系统的画笔还给系统,删除使用过的GDIObject,释放非空的指针,最后把新建的设备描述表也删除。
CObList链表
MFC类库中提供了丰富的CObList类的成员函数,此程序主要用到的成员函数如下:
(1)构造函数,为CObject指针构造一个空的列表。
(2)GetHead(),访问链表首部,返回列表中的首元素(列表不能为空)。
(3)AddTail(),在列表尾增加一个元素或另一个列表的所有元素。
(4)RemoveAll(),删除列表中所有的元素。
(5)GetNext(),返回列表中尾元素的位置。
(6)GetHeadPosition(),返回列表中首元素的位置。
(7)RemoveAt(),从列表中删除指定位置的元素。
(8)GetCount(),返回列表中的元素数。
在文件中声明各游戏对象与游戏对象链表:
(1)资源视图下,添加Dialog对话框。
然后添加使用到的控件,并修改控件的ID以便于后面的使用。
(2).为对话框添加类,在对话框模式下,点击项目,添加类。
(3).在类视图中,为对话框类添加成员变量(控件变量)。
设置变量的名称、类型、最值等信息。
(4).在资源视图菜单中,选择相应的菜单项,右击添加时间监听程序,设置函数处理程序名称。
(5).在处理程序函数中添加相应的信息。
3.总体设计与详细设计
系统模块划分
该飞机大战游戏程序分为游戏背景位图绘制模块、各游戏对象绘制模块、游戏对象之间的碰撞模块、爆炸效果产生模块、游戏界面输出玩家得分关卡信息模块。
其中在游戏对象绘制模块中,战机是唯一对象,在游戏开始时产生该对象,赋予其固定的生命值,当其与敌机对象、敌机炸弹碰撞时使其生命值减一,直至生命值为零,便删除战机对象。
敌机对象与敌机炸弹对象的绘制中采用定时器技术,定时产生。
爆炸对象初始化为空,当游戏过程中即时发生碰撞时,在碰撞位置产生爆炸对象,添加到爆炸链表中。
主要功能模块
系统对象类图
CGameObject是各个游戏对象的抽象父类,继承自CObject类,其他的类:
战机类、敌机类、爆炸类、子弹类、炸弹类、文字类都继承了此类。
每个游戏对象类中既继承了来自父类CGameObject的属性,又有自己的特有属性和方法。
系统主程序活动图
系统部分流程图
(1)该飞机大战游戏执行流程图:
(2)利用定时器定时产生敌机并绘制敌机流程图
4.编码实现
绘制游戏背景位图程序
CDC*pDC=GetDC();
<||enemy->GetPoint().x>
||enemy->GetPoint().y<||enemy->GetPoint().y>
{
(posEn_t);
deleteenemy;
}+17,
enemy->GetPoint().y+30,enemy->GetMotion());
(ball);
}<||ball->GetPoint().x>
||ball->GetPoint().y<||ball->GetPoint().y>
{
(posball_t);
deleteball;
}<
myplane->SetPoint(myplane->GetPoint().x,;
else
myplane->SetPoint(myplane->GetPoint().x,(myplane->GetPoint().y-speed));
},myplane->GetPoint().y,1);
(BombOne);
CBomb*BombTwo=newCBomb(myplane->GetPoint().x+35,myplane->GetPoint().y,1);
(BombTwo);
PlaySound((LPCTSTR)IDR_WAVE2,AfxGetInstanceHandle(),SND_RESOURCE|SND_ASYNC);
},myplane->GetPoint().y,1);
PlaySound((LPCTSTR)IDR_WAVE2,AfxGetInstanceHandle(),SND_RESOURCE|SND_ASYNC);
(BombOne);
CBomb*BombTwo=newCBomb(myplane->GetPoint().x+35,myplane->GetPoint().y,1);
(BombTwo);
}
}
飞机大战游戏对象之间的碰撞实现
本飞机大战游戏中的碰撞考虑了飞机子弹打中敌机、敌机炸弹打中战机、战机与敌机相撞、敌机炸弹与战机子弹相撞四种情况,根据游戏对象的矩形区域是否有交叉,而确认两者是否相撞,而产生爆炸对象,添加到爆炸链表中。
以战机与敌机相撞为例:
if(myplane!
=NULL&&is_Pause==0)
{
POSITIONenemyPos,enemyTemp;
for(enemyPos=();(enemyTemp=enemyPos)!
=NULL;)
{
enemy=(CEnemy*)(enemyPos);
+18,enemy->GetPoint().y+18);
PlaySound((LPCTSTR)IDR_WAVE,AfxGetInstanceHandle(),SND_RESOURCE|SND_ASYNC);
(explosion);
项目程序测试
战机移动及子弹发射模块测试
用例
预期结果
实际结果
问题描述
修改方案
点击A键或鼠标左移
战机向左移动
战机向左移动
点击D键或鼠标右移
战机向右移动
战机向右移动
点击W键或鼠标上移
战机向上移动
战机向上移动
点击S键或鼠标上移
战机向下移动
战机向下移动
敌机及炸弹模块测试
用例
预期结果
实际结果
问题描述
修改方案
玩家得分<50(未通过第一关)
敌机只从上方飞出,速度固定
敌机只从上方飞出,速度固定
玩家得分>50(通过第一关后)
敌机从上下两方向均可飞出,且速度不断增加
敌机从上下两方向均可飞出,且速度不断增加
爆炸模块测试
用例
预期结果
实际结果
问题描述
修改方案
战机子弹打中敌机
敌机位置处爆炸,敌机消失,战机生命-1
敌机位置处爆炸,敌机消失,战机生命-1
敌机炸弹打中战机
战机位置处爆炸,战机生命-1
战机位置处爆炸,战机生命-1
敌机战机相撞
敌机位置处爆炸,敌机消失,战机生命-1
敌机位置处爆炸,敌机消失,战机生命-1
战机子弹与敌机炸弹相撞
敌机炸弹处爆炸,子弹与炸弹均消失消失
敌机炸弹处爆炸,子弹与炸弹均消失消失
战机生命值==0
战机消失,GameOver或者过关
战机消失,GameOver或者过关
6.实训中遇到的主要问题及解决方法
(1)由于对C++的面向对象的思想和逻辑思路不熟悉,不明白其中的封装之类的以及多态的思想,致使开始真正的进入实训接触到项目时没有开发思路,通过逐步查询书籍整理C++面向对象编程思路,才逐步理清项目的开发步骤。
(2)本飞机大战的游戏要求使用链表实现各游戏对象的存储和释放,由于链表知识掌握的不牢固,使用起来总是出现这样那样的错误,给整个游戏开发带来了很大的障碍,通过不断的调试修改,最终使程序正确运行。
(3)在绘制各种游戏对象—敌机和敌机炸弹时,开始使用随机函数,画出敌机时而很少,总是打不到预定的效果,后来经过修改使用定时器产生敌机和敌机炸弹,使整个游戏更加人性化。
7.实训体会
(1)在本次飞机大战游戏项目的开发过程中遇到很多问题,大部分是因为对MFC编程的不熟悉以及链表掌握不牢固所导致的。
(2)MFC编程中有很多可以直接调用的函数,由于之前缺乏对这方面编程的经验,以至于本次项目开发过程中走了很多弯路。
(3)通过寻求老师和同学的帮助,解决了开发中遇到的很多问题,也提升了自己调试错误的能力。
(4)通过本次实训,使我熟悉了MFC编程技术、巩固了链表的使用方法并加深了对面向对象编程思想的理解,对以后程序的编写打下了良好的基础。