飞机大战实训报告.doc

上传人:仙人指路1688 文档编号:2913817 上传时间:2023-03-03 格式:DOC 页数:22 大小:679.50KB
返回 下载 相关 举报
飞机大战实训报告.doc_第1页
第1页 / 共22页
飞机大战实训报告.doc_第2页
第2页 / 共22页
飞机大战实训报告.doc_第3页
第3页 / 共22页
飞机大战实训报告.doc_第4页
第4页 / 共22页
飞机大战实训报告.doc_第5页
第5页 / 共22页
点击查看更多>>
资源描述

《飞机大战实训报告.doc》由会员分享,可在线阅读,更多相关《飞机大战实训报告.doc(22页珍藏版)》请在三一办公上搜索。

1、程序设计综合实践实习报告学院名称信息科学与工程学院专业班级软件工程2012-3学生姓名程大川学号201201051002指导教师孙红梅山 东 科 技 大 学一、实习题目: 飞机大战游戏的设计与实现 二、实习时间:7周 8周 实习地点:J13-128 三、实习任务: 1基本功能要求:飞机大战游戏必须运用透明贴图、按键处理、定时控制、双缓冲技术等技术实现战机(玩家)和敌机(计算机)对战功能 2扩展功能:在完成基本功能基础上可以增加双人对战、游戏积分制、声音效果、多种子弹类型、客机类型、游戏关卡设计、多种类型敌机、游戏中间结果存贮等功能 四、小组分工说明:此次实习项目,所有内容均由一人完成 五、实习

2、成绩 六、指导教师对实习的评语: 指导教师(签章): 2014年 月 日目 录1. 概述51.1实训概述51.2功能概述52. 相关技术52.1滚动背景技术52.2透明贴图技术52.3定时器技术52.4双缓冲技术62.5连续按键处理技术62.6碰撞处理技术62.7链表存储技术62.8动态效果技术63.需求分析73.1功能需求分析73.2数据需求分析73.3行为需求分析83.4其他需求84. 总体设计与详细设计84.1 系统模块划分84.2 主要功能模块94.2.1玩家控制模块设计图94.2.2游戏逻辑模块设计图(包含关卡控制)94.2.3 图形显示模块设计(包含敌方生成模块)104.3 主要类

3、图124.4 软件结构设计体会125. 编码实现125.1编码规范125.2代码组织策略135.3关键技术代码实现136测试情况说明。216.1主要模块测试情况21模块1、碰撞模块测试21模块2、滚动背景模块测试21模块3、关卡模块测试226.2 主要功能测试情况22功能1、飞机控制功能测试22功能2、能量块吃取功能测试22功能3、BOSS功能测试22功能3、显示功能测试227. 实训中遇到的主要问题及解决方法228. 实训收获与体会231. 概述1.1实训概述这次实训,目的以Window7 + VS 2013为环境,编写一个简单的飞机大战游戏,熟悉软件工程的思想,学习MFC编程的方法,加深对

4、面向对象思想的理解1.2功能概述用户可以左右移动控制战机和发射子弹,子弹命中敌机会造成伤害,敌机被击毁可以获得积分,积分达到一定程度会出现BOSS,BOSS被击杀后即可进行下一关。游戏中会不定期出现道具包,吃取不同的道具包会有不同的增益效果。2. 相关技术本项目涉及的几个主要技术介绍和简要实现方式如下:2.1滚动背景技术为了让游戏场景更加逼真,游戏节奏更加合理,可以通过让背景滚动来提高游戏的场景效应,实现这一技术时,可以将一张背景图片复制为三张,从上到下连续的拼接在一起,并将中间的图片进行垂直翻转,在输出图像时,每次只输出合成后图片的1/3部分,每次输出后,将位图中的纵坐标输出位置增加一个位移

5、量,当输出位置到达图片的2/3部分时,将图片的纵坐标输出位置置为0,由于图片的起始位置和图片的2/3位置是一致,所以在背景图片的显示中,不会出现图片的卡顿和瞬移现象。2.2透明贴图技术在飞机大战项目中,需要将很多的BMP图像贴到画布上,结合逻辑处理完成对整个游戏的设计,为了实现更好的显示效果,使移动元素所用的图像更加贴合背景,则需要利用透明贴图技术,将BMP图像中的无关颜色做透明处理,实现方式为调用CDC中的TransparentBlt函数,并且利用函数的最后一个参数填写RGB信息,实现对对应颜色的透明化。2.3定时器技术为了实现屏幕的定时刷新功能和暂停功能,需要设置定时器,当设置好时间间隔时

6、,每次经过一个设置的时间间隔,Windows都会向程序发送一个WM_TIMER,并且调用相关函数,程序执行OnTimer函数,并根据定时器编号执行相应的操作。实现方式为使用SetTimer函数设置定时器标识和时间间隔。另外也可以利用定时器实现对连续按键的处理,使子弹发射和移动效果更加平滑合理。2.4双缓冲技术利用普通的绘制函数对项目中元素进行绘图时,由于绘图时机不一定连续,绘图效率不一定统一,会造成重影和闪屏的不良效果,为了解决这一问题,可以利用双缓冲技术,先将要绘制的每部分内容存储到内存中的一个虚拟的绘图设备中,当所有部分的内容都绘制完毕后,再一次性的将内存中的内容绘制到真实屏幕上,实现这一

7、方式,可以在程序定义一个CDC指针变量和CBitmap指针向量实现,在构造函数中为两个指针分配内存空间,将所有的图像绘制完毕后,再利用GetDC函数取得真实窗口CDC指针和BitBlt函数将内存中的内容完整的拷贝至真实屏幕上。2.5连续按键处理技术在飞机大战项目中,需要根据键盘输入决定游戏中各种位置的改变和一些变量的内容,在利用战机发射子弹或者进行移动时,需要按下键盘的空格键或者方向键,在该项目中,如果利用MFC中提供的默认消息处理函数进行按键消息的处理,则会导致子弹发射频率过快,战机移动过快,甚至程序卡死等严重问题,所以应将按键消息处理放在OnTimer函数里,以达到平滑的移动和发射子弹效果

8、2.6碰撞处理技术在该项目中,需要处理对象之间的各种碰撞,比如,战机子弹与敌机的碰撞、敌机子弹与战机的碰撞、敌机与战机的碰撞、子弹与客机的碰撞等等。在处理碰撞时,可以为每个对象设置一个与位图大小相同的矩形,矩形的位置与对应位图所在位置一直,当判断两个元素是否发生了碰撞时,只需要利用IntersectRect函数判断两个矩形是否相交即可。2.7链表存储技术一局游戏中会有很多的敌机,敌机子弹以及战机子弹,并且需要其进行添加、删除、遍历等操作,为了提高程序执行效率,选用链表存储这些类型,当需要生产一个敌机或者敌机子弹时,只需要在链表尾部添加一个对应的对象即可,时间复杂度为O(1),当敌机被击毁或者子

9、弹失效时,只需要在链表中将对应位置的对象删除即可,时间复杂度为O(1),当绘图时,需要对所有的对象进行遍历,此时只需要从头至尾遍历一个链表即可,时间复杂度为O(n),所有的复杂度已经是最低,所以利用CList链表存储项目各种对象,是一个非常合理的选择。2.8动态效果技术在敌机被击毁时,需要显示敌机爆炸的画面,这个动态的画面是由一组静态图像连续绘制形成的,为了实现这一效果,可以利用MFC中的CImageList类,将一组由静态图像组成的连续位图按照一定格式转化为CImageList对象,并为每个对象设置一个index,在敌机生命值为0时,根据index逐帧播放图像,实现敌机爆炸的动态效果。3.需

10、求分析3.1功能需求分析l 飞机大战项目需要实现的主要功能如下:l 战机在用户的控制下可以自由移动,但不可以移动到窗体外。l 战机可以连续发射子弹,子弹的起始位置和战机位置有关。l 敌机在窗口顶部随机产生,产生后垂直向下移动。l 敌机可以发射子弹,每个敌机在一个发射时刻可以发射两枚子弹。l 客机在窗口顶部随机产生,产生后由极慢的速度向下移动。l 客机的大小十分庞大,远大于敌机和战机l 战机子弹由战机产生,垂直向上飞行,并且可以击中敌机和客机l 敌机子弹由敌机产生,垂直向下飞行,并且可以击中战机和客机l 游戏中会不定期出现道具包,飞机经过道具包会出现不同的效果l 击毁敌机可以获得一定的得分,得分

11、到达一定数量会出现BOSSl BOSS产生于顶部,不会向下移动,会被子弹击中,击毁后可通过关卡。l 通过关卡后会使游戏难度增加,通过所有关卡会通关,完成游戏。3.2数据需求分析飞机大战项目中所需要的数据有类型数据战机战机位置,战机生命值,战机伤害值敌机敌机位置,敌机生命值,敌机伤害值,敌机的生成速度,敌机的移动速度战机子弹子弹位置,子弹发射相应速度,子弹移动速度,子弹伤害值敌机子弹子弹位置,子弹发射生成速度,子弹移动速度,子弹伤害值道具包道具包类型,道具包位置,道具包移动速度BOSSBOSS位置,BOSS伤害,BOSS生命值关卡关卡编号,关卡难度,得分3.3行为需求分析飞机大战项目中的行为可以

12、用下面的用例图表示3.4其他需求背景可以滚动4. 总体设计与详细设计(介绍游戏的功能模块划分,主要类图、状态图、活动图或顺序图)4.1 系统模块划分4.2 主要功能模块4.2.1玩家控制模块设计图4.2.2游戏逻辑模块设计图(包含关卡控制)4.2.3 图形显示模块设计(包含敌方生成模块)4.3 主要类图4.4 软件结构设计体会软件结构设计部分是软件工程开发过程的重要部分,设计内容的好坏关系到整个软件的优劣,在这次飞机大战项目开发中,对结构设计中出现的种种问题以及解决方法,加深了对软件结构设计方法的理解,熟悉了对其的应用,从系统功能模块设计到主要功能设计,从类图到状态图,都是着软件开发的每一个步

13、骤,从宏观和细节处展示了整个软件的体系结构,使整个软件更有层次感。5. 编码实现5.1编码规范l 在这次飞机大战设计开发项目中,涉及到的编码规范主要包括l 类、对象、变量、常量、函数的名称含义准确不臃肿l 类的命名必须以C开头。l 类的名称中的单词首字母大写。l 变量名称中的单词首字母大写。l 函数名称中的单词首字母大写l 对象、变量、常量的定义尽量定义在CPaperPlaneDoc里。l 函数定义在CPaperPlaneView里。l 对不易理解的部分进行注释5.2代码组织策略以MFC代码标准组织方式为主。5.3关键技术代码实现5.3.1双缓冲的实现CDC* pMemDC;CBitmap*

14、pBitmap;CPaperPlaneView:CPaperPlaneView()/ TODO: 在此处添加构造代码pMemDC = new CDC();pBitmap = new CBitmap();DrawBG(pMemDC);pDC-BitBlt(0, 0, 600, 600, pMemDC, 0, 0, SRCCOPY); CPaperPlaneView:CPaperPlaneView()delete pMemDC;delete pBitmap;5.3.2透明贴图的实现void CCloud:draw(CDC* pDC)CDC memDC;memDC.CreateCompatibleD

15、C(pDC);CBitmap bmpDraw;bmpDraw.LoadBitmap(CloudBitmapNum);memDC.SelectObject(&bmpDraw);pDC-TransparentBlt(pos.x, pos.y, 80,50, &memDC, 0, 0, 80,50, RGB(255, 255, 255);5.3.3滚动背景的实现DrawBG(pMemDC);void CPaperPlaneView:DrawBG(CDC* pDC)CPaperPlaneDoc* pDoc = GetDocument();ASSERT_VALID(pDoc);if (!pDoc)ret

16、urn;/*/CBitmap bitmap;bitmap.LoadBitmap(pDoc-BackGroundNum);BITMAP BitMap;bitmap.GetBitmap(&BitMap);CDC dcMem;dcMem.CreateCompatibleDC(pDC);dcMem.SelectObject(&bitmap);pDC-StretchBlt(0, 0, 600, 600, &dcMem, 0, pDoc-BGposY, 600, 600, SRCCOPY);pDoc-BGposY -= 10;if (pDoc-BGposYBGposY = 1200;5.3.4主要游戏逻辑

17、void CPaperPlaneView:OnTimer(UINT_PTR nIDEvent)/ TODO: 在此添加消息处理程序代码和/或调用默认值CPaperPlaneDoc* pDoc = GetDocument();ASSERT_VALID(pDoc);if (!pDoc)return;CDC* pDC = GetDC();switch (nIDEvent)case 1:DrawBG(pMemDC);CloudInPlane(pDoc-myPlane,pDoc-enemy);FireInCloud(pDoc-FireList,pDoc-enemy);WaterInPlane(pDoc-

18、WaterList, pDoc-myPlane);PackageInPlane(pDoc-package, pDoc-myPlane);FireInBusiness(pDoc-FireList, pDoc-business);DrawFire(pDoc-FireList);DrawCloud(pDoc-enemy);DrawWater(pDoc-WaterList);pDoc-myPlane.Draw(pMemDC);pDoc-package.Draw(pMemDC);pDoc-business.Draw(pMemDC);DrawTitle();if (pDoc-PlaneScore = pD

19、oc-PassBase*100*(3*pDoc-NowLevel-2)+300)KillTimer(1);if (pDoc-NowLevelNowLevel);if (pDoc-NowLevelPlaneScore = pDoc-PassBase *100* (3 * pDoc-NowLevel - 2) - 300 & pDoc-PlaneScorePassBase * 100*(3 * pDoc-NowLevel - 2)if (pDoc-boss.pos.y = -200)killAllEnemy();FireInBoss(pDoc-FireList, pDoc-boss);pDoc-b

20、oss.Draw(pMemDC);else if (pDoc-PlaneScore = pDoc-PassBase * 100*(3 * pDoc-NowLevel - 2)if (pDoc-boss.pos.y PlaneScore = pDoc-PassBase * 100 * (3 * pDoc-NowLevel - 2) + 1000;pDoc-boss.DrawUp(pMemDC);if (pDoc-myPlane.life PlaneScore = 0;SetLevel(pDoc-NowLevel=1);SetTimer(1,25,0);else exit(1);/GetKeyCo

21、mmand();if (GetAsyncKeyState(P)KillTimer(1);SetTimer(2,300, 0);if (GetAsyncKeyState(VK_UP)pDoc-myPlane.up();if (GetAsyncKeyState(VK_DOWN)pDoc-myPlane.down();if (GetAsyncKeyState(VK_LEFT) pDoc-myPlane.left();if (GetAsyncKeyState(VK_RIGHT) pDoc-myPlane.right();pDoc-TimerCnt+;if (pDoc-TimerCnt % (40 /

22、CFire:FireMakeSpeed) FireList.AddTail(CFire(pDoc-myPlane.pos + CPoint(25, -20);if (pDoc-TimerCnt % (40 / CCloud:CloudMakeSpeed) boss.pos.y enemy.AddTail(CCloud();rain(pDoc-enemy, pDoc-WaterList);if (pDoc-TimerCnt400&pDoc-TimerCnt % (800 / CPackage:PackageMakeSpeed) package.pos.y = 0;pDoc-package.Pac

23、kType = rand() % 3 + 1;if (pDoc-havePower 0 & pDoc-TimerCnt - pDoc-havePower 300)CFire:FireMakeSpeed = 6;if (pDoc-boss.pos.y -200 & pDoc-TimerCnt % (40 / 1) 1)int base = rand() % 200;for (int i = 0; i WaterList.AddTail(CWater(CPoint(base+i * 20, 200);for (int i = 0; i WaterList.AddTail(CWater(CPoint

24、(base + 300 + i * 20, 200);if (pDoc-TimerCnt % 4000 business.pos.x = rand() % 450;pDoc-business.pos.y = 0;break;case 2:CBitmap bitmap;bitmap.LoadBitmap(IDB_PAUSE);BITMAP BitMap;bitmap.GetBitmap(&BitMap);CDC dcMem;dcMem.CreateCompatibleDC(pMemDC);dcMem.SelectObject(&bitmap);pMemDC-StretchBlt(0, 0, 60

25、0, 600, &dcMem, 0, 0, 600, 600, SRCCOPY);if (GetAsyncKeyState(P)KillTimer(2);SetTimer(1,25,0);if (GetAsyncKeyState(Q)KillTimer(2);SetLevel(pDoc-NowLevel = 1);SetTimer(1, 25, 0);if (GetAsyncKeyState(E)KillTimer(2);if (AfxMessageBox(L确定退出游戏?, MB_YESNO) = 6)exit(1);elseSetTimer(2,300, 0);pDC-BitBlt(0,

26、0, 600, 600, pMemDC, 0, 0, SRCCOPY);ReleaseDC(pDC);CView:OnTimer(nIDEvent);5.3.5碰撞判断int CPaperPlaneView:FireInCloud(CList& list, CList& enemy)CPaperPlaneDoc* pDoc = GetDocument();ASSERT_VALID(pDoc);if (!pDoc)return 0;POSITION pos = enemy.GetHeadPosition();while (pos != NULL)pDoc-PlaneScore+=enemy.Ge

27、tNext(pos).beFired(list);return 0;void CPaperPlaneView:FireInBoss(CList& list, CBoss& boss)CPaperPlaneDoc* pDoc = GetDocument();ASSERT_VALID(pDoc);if (!pDoc)return ;boss.beFired(list);if (boss.life PlaneScore = pDoc-PassBase * 100 * (3 * pDoc-NowLevel - 2);return ;int CPaperPlaneView:WaterInPlane(CL

28、ist& list,CPlane& plane)POSITION ps2,pos = list.GetHeadPosition();while (pos != NULL)ps2 = pos;if (plane.beWatered(list.GetNext(pos)list.RemoveAt(ps2);return 0;int CPaperPlaneView:CloudInPlane(CPlane& plane, CList& enemy)POSITION pos = enemy.GetHeadPosition();while (pos != NULL)CCloud& tmp = enemy.G

29、etNext(pos);CRect planeRect1, planeRect2, cloudRect, temRect;planeRect1.SetRect(plane.pos + CPoint(10, 10), plane.pos + CPoint(60, 30);planeRect2.SetRect(plane.pos + CPoint(0, 30), plane.pos + CPoint(70, 80);cloudRect.SetRect(tmp.pos, tmp.pos + CPoint(80, 50);if (plane.life0 &tmp.life0& (temRect.Int

30、ersectRect(cloudRect, planeRect1) | temRect.IntersectRect(cloudRect, planeRect2) plane.life -= tmp.damage;tmp.life -= plane.damage;return 1;return 0;5.3.6 链表遍历int CPaperPlaneView:FireInCloud(CList& list, CList& enemy)CPaperPlaneDoc* pDoc = GetDocument();ASSERT_VALID(pDoc);if (!pDoc)return 0;POSITION

31、 pos = enemy.GetHeadPosition();while (pos != NULL)pDoc-PlaneScore+=enemy.GetNext(pos).beFired(list);return 0;5.3.7 关卡设置void CPaperPlaneView:SetLevel(int nLevel)CPaperPlaneDoc* pDoc = GetDocument();ASSERT_VALID(pDoc);if (!pDoc) return;switch (nLevel)case 1:CPlane:PlaneLife = 6;CPlane:PlaneDamage = 1;

32、CPlane:PlaneBitmapNum = IDB_PLANE1;CCloud:CloudBitmapNum = IDB_CLOUD1;CCloud:CloudBoommapNum = IDB_CLOUDBOOM1;CCloud:CloudLife = 1;CCloud:CloudDamage = 1;CCloud:CloudMakeSpeed = 1;CCloud:CloudMoveSpeed = 2;CFire:FireMakeSpeed = 6; /1 - 9CFire:FireMoveSpeed = 15;CFire:FireDamage = 1;CFire:FireBitmapN

33、um = IDB_FIRE1;CWater:WaterMakePossible = 40;CWater:WaterMoveSpeed = 4;CWater:WaterDamage = 1;CWater:WaterBitmapNum = IDB_WATER1;CPackage:PackageMakeSpeed = 3;/every 20sCPackage:PackageMoveSpeed = 2;CBoss:BossBitmapNum = IDB_BOSS1;pDoc-PassBase = 10;pDoc-PlaneScore = 0;pDoc-boss.pos.y = - 200;pDoc-T

34、imerCnt = 0;pDoc-BGposY = 0;pDoc-WaterList.RemoveAll();pDoc-enemy.RemoveAll();pDoc-FireList.RemoveAll();pDoc-myPlane.init();pDoc-NowLevel = 1; pDoc-havePower = 0;pDoc-package.PackType = rand() % 3 + 1;pDoc-BackGroundNum = IDB_BACKGROUND1;pDoc-boss.life = 10;break;case 2:CPlane:PlaneLife = 6;CPlane:P

35、laneDamage = 1;CPlane:PlaneBitmapNum = IDB_PLANE2;CCloud:CloudBitmapNum = IDB_CLOUD2;CCloud:CloudBoommapNum = IDB_CLOUDBOOM1;CCloud:CloudLife = 2;CCloud:CloudDamage = 1;CCloud:CloudMakeSpeed = 1;CCloud:CloudMoveSpeed = 2;CFire:FireMakeSpeed = 6; /1 - 40CFire:FireMoveSpeed = 15;CFire:FireDamage = 1;C

36、Fire:FireBitmapNum = IDB_FIRE2;CWater:WaterMakePossible = 60;CWater:WaterMoveSpeed = 3;CWater:WaterDamage = 1;CWater:WaterBitmapNum = IDB_WATER2;CPackage:PackageMakeSpeed = 3;/every 20sCPackage:PackageMoveSpeed = 2;CBoss:BossBitmapNum = IDB_BOSS1;pDoc-TimerCnt = 0;pDoc-PassBase = 10;pDoc-BGposY = 0;

37、pDoc-WaterList.RemoveAll();pDoc-enemy.RemoveAll();pDoc-FireList.RemoveAll();pDoc-myPlane.init();pDoc-havePower = 0;pDoc-package.PackType = rand() % 3 + 1;pDoc-BackGroundNum = IDB_BACKGROUND2; pDoc-NowLevel = 2;pDoc-boss.pos.y = -200;pDoc-boss.life = 3;break;default:KillTimer(1);AfxMessageBox(L恭喜你,通关了!, MB_OK);SetTimer(2,300, 0);break;5.3.8 子弹生成void CPaperPlaneView:rain(CList& enemy, CList& list)POSITION pos = enemy.GetHeadPosition();POSITION ps2;wh

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 建筑/施工/环境 > 项目建议


备案号:宁ICP备20000045号-2

经营许可证:宁B2-20210002

宁公网安备 64010402000987号