C++实训报告.doc_第1页
C++实训报告.doc_第2页
C++实训报告.doc_第3页
C++实训报告.doc_第4页
C++实训报告.doc_第5页
已阅读5页,还剩24页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

_实 训 报 告飞机大战游戏设计与开发姓名* 专业名称: 数学专业班 级: * 学 号: *信息科学与工程学院二零一三年十一月-可编辑修改-目 录1.概述22. 相关技术 22.1获取矩形区域函数22.2添加爆炸效果函数22.3弹出对话框函数32.4字体的个性化输出函数42.5键盘控制战机位置和发射子弹的函数42.6设置定时器42.7双缓冲技术52.8内存释放技术53.需求分析53.1功能需求分析53.2 数据需求分析63.3 行为需求分析64. 总体设计与详细设计 64.1系统模块划分84.2主要功能模块84.3扩展功能设计思路95. 编码实现 9 6. 测试情况说明 246.1主要模块测试情况(白盒) 246.2 主要功能测试情况(黑盒)247. 实训中遇到的主要问题及解决方法 258. 实训体会 25 1. 概述飞机大战游戏是基于Windows桌面的射击类游戏。做为一个游戏首先要保证游戏本身的规则,而这个版本的一个重要的功能就是其2D的展现形式。飞机大战游戏作为PC中一款桌面游戏,界面简洁流畅、游戏方式简单,玩起来易于上手。其实现的功能为:实现游戏对象的爆炸特效、声音特效、文字提示功能和界面背景,其主要是遵循一定的游戏规则进行游戏。游戏中的主要角色可分为如下几个基本部分:战机、敌机、战机的导弹、敌机的子弹。其主要遵循的游戏规则为:战机数量为1;由玩家通过键盘控制(方向键控制位置、空格键发射导弹)战机;导弹释放存在间隔,有一定的运行速度;导弹遇到敌机发生爆炸,敌机被炸毁,玩家得分;由计算机控制敌机自动向战机发动攻击;敌机数量随机,计算机生成敌机时随机选择位置;敌机从游戏区域的上下两端进入;敌机行驶期间,不左右移动,不反向移动;敌机发射炸弹对战机进行攻击,运行线路为直线,方向为从下至上,或从下至上,不可左右移动,敌机炸弹击中战机,战机生命值减1。该游戏有关卡,战机生命值减为0,游戏结束,选择是否重新开始;战机仍有生命值时,并且得到要求的分数可进入下一关。2. 相关技术此次实训的飞机大战游戏其中的技术主要就是一些函数(获取矩形区域函数、添加爆炸效果函数、弹出对话框函数、字体的个性化输出函数、键盘控制战机位置和发射子弹的函数)、设置定时器、内存释放和双缓冲技术。2.1获取矩形区域函数CRect CBomb:getRect(void)return CRect(CPoint(Pos.x,Pos.y),CPoint(Pos.x+55,Pos.y+20);CRect bombRect = bomb-getRect();CRect CEnemy:getRect(void)return CRect(CPoint(Pos.x,Pos.y),CPoint(Pos.x+35,Pos.y+35);CRect enemyRect = enemy-getRect();CRect tempRect;tempRect.IntersectRect(&bombRect,enemyRect)/判断两个矩形是否有交接2.2添加爆炸效果函数PlaySound(LPCTSTR)IDR_WAVE2,AfxGetInstanceHandle(),SND_RESOURCE|SND_ASYNC);/此函数用于将ID为IDR_WAVE1的音频在执行此语句时进行播放。2.3弹出对话框函数if(AfxMessageBox(LGAME OVER!重新开始?,MB_YESNO)=1)/清空敌机链表ListEnemy1.RemoveAll();ListEnemy2.RemoveAll();/清空敌机炸弹链表ListBall1.RemoveAll();ListBall2.RemoveAll();/清空战机子弹链表ListBomb1.RemoveAll();ListBomb2.RemoveAll();/清空爆炸链表ListExplosion.RemoveAll();/添加新的战机对象/*myplane = new CMyPlane;*/myscore=0;lifeNum = 20;SetTimer(1,100,NULL);/ifelseexit(1);/此函数主要是弹出对话框供用户进行选择,当用户点击确定按钮时执行此函数的内的语句进行继续运行。2.4字体的个性化输出函数HFONT font;font=CreateFont(20,10,0,0,0,0,0,0,0,0,0,100,10,0);MemDC.SelectObject(font);CString str;MemDC.SetTextColor(RGB(239,7,7);MemDC.SetBkColor(RGB(0,0,0);str.Format(_T(游戏得分:%d),myscore);MemDC.TextOut(10,10,str);str.Format(_T(剩余生命:%d),lifeNum);MemDC.TextOut(10,30,str);str.Format(_T(当前关卡:%d),passnum);MemDC.TextOut(10,50,str);2.5键盘控制战机位置和发射子弹的函数if (GetKeyState(VK_LEFT)rect.left)myplane.move(1);if (GetKeyState(VK_RIGHT)0)if(myplane.Pos.xrect.right-50)myplane.move(2);if (GetKeyState(VK_UP)rect.top)myplane.move(3);if (GetKeyState(VK_DOWN)0)if(myplane.Pos.yrect.bottom-50)myplane.move(4);if (GetKeyState(VK_SPACE)SetTimer(1,100,0); /设置每100毫秒刷新一次2.7双缓冲技术关于双缓冲技术主要就是利用缓存的原理进行将所有的东西都先存在一个缓冲得虚拟的区域,然后再一次性的将所有的虚拟缓存中的东西都放入实在的存储器中。/定义一个位图对象CBitmap MemBitmap;CDC MemDC;/这时还不能绘图,因为没有位图的设备描述表是不能绘图的/只有选入了位图的设备描述表才有地方绘图,画到指定的位图上MemDC.CreateCompatibleDC(pDC);/下面建立一个与屏幕设备描述表(或者内存设备描述表)兼容的位图MemBitmap.CreateCompatibleBitmap(pDC,rect.right,rect.bottom);CBitmap *pOldBit=MemDC.SelectObject(&MemBitmap);/将位图选入到内存设备描述表MemDC.StretchBlt(0,0,rect.Width(),rect.Height(),&cdc_BackGround,0,0,bimap2.bmWidth,bimap2.bmHeight,SRCCOPY);/绘图完成后的清理pDC-BitBlt(rect.left,rect.top,rect.right,rect.bottom,&MemDC,0,0,SRCCOPY);MemBitmap.DeleteObject();MemDC.DeleteDC();2.8 内存释放技术在此次实训项目中有太多的对象的生成和运用,造成了内存的极度的紧张,当游戏进行到一定的程度的时候就会出现内存溢出现象。解决此问题的技术就是内存释放。内存释放技术的实现主要是通过释放各个满足一定条件的对象和链表来实现的,/爆炸后删除子弹ListBomb1.RemoveAt(bombTemp);delete bomb;/删除敌机ListEnemy1.RemoveAt(enemyTemp);delete enemy;3. 需求分析3.1功能需求分析游戏基本规则飞机对战规则游戏特效界面背景特效游戏对象特效声音特效文字提示3.2数据需求分析 战机数量为1,敌机数量随机随机产生,当战机被击中时生命值减1,战机与敌机相撞生命值减1,战机击中敌机分数加1,战机生命值减到0时,游戏结束,生命值大于0并且分数到达一定要求时进入下一关。上方敌机、下方敌机、上方敌机的炸弹、下方敌机的炸弹、战机的两排导弹均以链表存储。当战机与敌机相撞时敌机从该链表删除,导弹击中敌机时,敌机从该链表删除,导弹从该链表删除。3.3行为需求分析战机上下移动,通过鼠标或键盘控制位置,空格键发射导弹;敌机出现位置随机,从上方出现,或从下方出现,发射子弹攻击战机,敌机可以与战机相撞。当战机生命值为0时,提示游戏结束是否进入下一关,当分数值到达一定要求时提示恭喜过关是否进入下一关。4. 总体设计与详细设计总体设计主要课将其分为两大部分:规则子系统,游戏对象子系统。系统的总体结构图如下:规则子系统主要是实现飞机大战各项游戏规则。实现需求中的游戏规则,组成结构图如下:主要是实现敌机战机的攻击和反攻的游戏规则等来实现计算机方和玩家进行对战。1、主要的攻击规则如下:1)、敌机可在战机的上方或者下方进行将子弹进行射向战机,同时战机也可根据玩家的指示进行向上或者向下进行发射导弹进行反攻。2)、攻击时发出声音。2、主要的碰撞规则如下:1)、导弹或者子弹本身的矩形区域和敌机或者战机的矩形区域相交时,表示其相互发生碰撞表示其相互爆炸。根据实战规则销毁游戏对象。2)、战机生命为0,战机被炸,战机被销毁,游戏结束。3)、敌机或者子弹被炸毁,将其进行销毁同时进行分数的相应的增加,并且出现文字提示。4)、爆炸时发出声音。3、主要时间控制规则如下:1)、当游戏的持续时间超过特定的时间,游戏结束,出现文字提示。2)、当游戏的关卡改变时进行游戏持续时间的一个相应的改变。游戏对象子系统主要包括:应用程序对象和游戏对象4、应用程序对象:1)、游戏程序的加载2)、游戏对象的绘制3)、游戏规则的调用4)、玩家键盘鼠标事件的获取5、游戏对象:1)、各游戏对象的图像加载2)、各游戏对象的贴图3)、各游戏对象的位置存储类图如下:4.1 系统模块划分模块名称功能简述应用程序对象游戏程序的加载、游戏对象的绘制、游戏规则的调用、玩家的键盘事件获取游戏对象各个游戏对象的抽象父类战机对象战机类敌机对象敌机类导弹对象导弹类炸弹对象炸弹类爆炸对象爆炸类4.2 主要功能模块主要功能模块主要就是那些类的功能模块,主要有:1、各个游戏对象的贴图模块2、敌机数量、方向、速度以及子弹的数量、方向和速度控制模块。3、战机的导弹的数目、方向和速度控制模块。4、战机的键盘控制和鼠标控制位置模块。5、敌机、子弹和战机、导弹的碰撞检测以及爆炸模块。6、背景添加模块。7、战机速度控制模块。8、游戏关卡游戏难易度设置和游戏关卡选择。9、游戏得分和生命值控制以及游戏关卡进入控制和游戏结束。10、游戏重新开始和游戏暂停控制模块。11、游戏音效控制模块。4.3 扩展功能设计思路本次实训由于时间问题还有些扩展功能可进行增加,主要有:1给游戏增加敌机类型,丰富画面,增加难度2、给游戏进行增加boss,通过boss的添加进行游戏的关卡和难度的更加进一步的提升。主要思路是:再增加一个类让它继承敌机类,然后再敌机类的基础上进行增加其生命值和被打死后的得分。当战机得分到达一定的值以后boss出现并进行和敌机一个队伍发射另类的子弹进行攻击战机。5. 编码实现void CPLANEGAMEView:OnDraw(CDC* pDC)CPLANEGAMEDoc* pDoc = GetDocument();ASSERT_VALID(pDoc);if (!pDoc)return;/加载图片背景this-GetClientRect(&rect);CBitmap bitmap_BackGround;bitmap_BackGround.LoadBitmap(IDB_BACKGROUND);BITMAP bimap2;/位图图像bitmap_BackGround.GetBitmap(&bimap2);CDC cdc_BackGround;/定义一个兼容的DCcdc_BackGround.CreateCompatibleDC(pDC);/创建DCCBitmap*Old=cdc_BackGround.SelectObject(&bitmap_BackGround);/定义一个位图对象CBitmap MemBitmap;/双缓冲技术CDC MemDC;/这时还不能绘图,因为没有位图的设备描述表是不能绘图的/只有选入了位图的设备描述表才有地方绘图,画到指定的位图上MemDC.CreateCompatibleDC(pDC);/下面建立一个与屏幕设备描述表(或者内存设备描述表)兼容的位图MemBitmap.CreateCompatibleBitmap(pDC,rect.right,rect.bottom);CBitmap *pOldBit=MemDC.SelectObject(&MemBitmap);/将位图选入到内存设备描述表MemDC.StretchBlt(0,0,rect.Width(),rect.Height(),&cdc_BackGround,0,0,bimap2.bmWidth,bimap2.bmHeight,SRCCOPY);/绘图完成后的清理/画飞机myplane.draw(&MemDC); /画向下飞的敌机 CEnemy* enemy1; POSITION pos1; for(pos1=ListEnemy1.GetHeadPosition();pos1!=NULL;) enemy1=(CEnemy*)ListEnemy1.GetNext(pos1); enemy1-draw(&MemDC); /画向下飞的敌机的子弹CBall* ball1;POSITION posball1;for (posball1=ListBall1.GetHeadPosition();posball1!=NULL;)ball1=(CBall*)ListBall1.GetNext(posball1);ball1-draw(&MemDC); /画向上飞的敌机 CEnemy* enemy2; POSITION pos2; for(pos2=ListEnemy2.GetHeadPosition();pos2!=NULL;) enemy2=(CEnemy*)ListEnemy2.GetNext(pos2); enemy2-draw(&MemDC); /画向上飞的敌机的子弹CBall* ball2;POSITION posball2;for (posball2=ListBall2.GetHeadPosition();posball2!=NULL;)ball2=(CBall*)ListBall2.GetNext(posball2);ball2-draw(&MemDC);/画战机的炮弹CBomb* bomb1;/第一排战机炮弹POSITION POS1;for(POS1=ListBomb1.GetHeadPosition();POS1!=NULL;)bomb1=(CBomb*)ListBomb1.GetNext(POS1);bomb1-draw(&MemDC);CBomb* bomb2;/第二排战机炮弹POSITION POS2;for(POS2=ListBomb2.GetHeadPosition();POS2!=NULL;)bomb2=(CBomb*)ListBomb2.GetNext(POS2);bomb2-draw(&MemDC);/画爆炸CExplosion* explosion; POSITION explosionPos1,explosionPos2; for(explosionPos1 = ListExplosion.GetHeadPosition();explosionPos1!=NULL;)explosionPos2=explosionPos1;explosion = (CExplosion *) ListExplosion.GetNext(explosionPos1); if(explosion-draw(&MemDC)=0)ListExplosion.RemoveAt(explosionPos2);/输出当前信息HFONT font;font=CreateFont(20,10,0,0,0,0,0,0,0,0,0,100,10,0);MemDC.SelectObject(font);CString str;MemDC.SetTextColor(RGB(239,7,7);MemDC.SetBkColor(RGB(0,0,0);str.Format(_T(游戏得分:%d),myscore);MemDC.TextOut(10,10,str);str.Format(_T(剩余生命:%d),lifeNum);MemDC.TextOut(10,30,str);str.Format(_T(当前关卡:%d),passnum);MemDC.TextOut(10,50,str);pDC-BitBlt(rect.left,rect.top,rect.right,rect.bottom,&MemDC,0,0,SRCCOPY);MemBitmap.DeleteObject();MemDC.DeleteDC(); / TODO: 在此处为本机数据添加绘制代码 void CPLANEGAMEView:OnInitialUpdate()if(AfxMessageBox(L查看游戏说明请点击“是”,若直接进入游戏请点击“否”!,MB_YESNO)=6)AfxMessageBox(L方向键控制战机方向,空格键射击,鼠标均可控制。初始生命值为,消灭一个敌机加分,分数达到即可进入下一关。随着关卡增多,敌机速度增加!);Sleep(1000);CView:OnInitialUpdate();/加载飞机 myplane.load(); GetClientRect(&rect);myplane.setPoint(rect.right/2,rect.bottom/2);/加载敌机CEnemy:load();/加载飞机炮弹CBomb:load(); /加载战机子弹CBall:load();/加载爆炸CExplosion:load();/设置定时器this-SetTimer(1,100,0);/ TODO: 在此添加专用代码和/或调用基类 void CPLANEGAMEView:OnTimer(UINT_PTR nIDEvent)/ TODO: 在此添加消息处理程序代码和/或调用默认值/上下左右键控制飞机移动 GetClientRect(&rect);if (GetKeyState(VK_LEFT)rect.left)myplane.move(1);if (GetKeyState(VK_RIGHT)0)if(myplane.Pos.xrect.right-50)myplane.move(2);if (GetKeyState(VK_UP)rect.top)myplane.move(3);if (GetKeyState(VK_DOWN)0)if(myplane.Pos.yrect.bottom-50)myplane.move(4);if (GetKeyState(VK_SPACE)0)/空格键代表战机发射子弹CBomb *Bomb1=new CBomb( myplane.getPoint().x, myplane.getPoint().y); ListBomb1.AddHead(Bomb1);CBomb *Bomb2=new CBomb( myplane.getPoint().x+35, myplane.getPoint().y);ListBomb2.AddHead(Bomb2);PlaySound(LPCTSTR)IDR_WAVE4, AfxGetInstanceHandle(), SND_RESOURCE |SND_ASYNC);if (GetKeyState(F)0)KillTimer(1);if(GetKeyState(J)setSpeed(30);if (BombOne-Pos.yrect.top)BombOne-move();elseListBomb1.RemoveAt(p1);/第二排战机炮弹POSITION pos2,p2;CBomb *BombTwo;for(pos2=ListBomb2.GetHeadPosition();pos2!=NULL;)p2=pos2;BombTwo=(CBomb*)ListBomb2.GetNext(pos2);BombTwo-setSpeed(30);if (BombTwo-Pos.yrect.top)BombTwo-move();else ListBomb2.RemoveAt(p2);switch(nIDEvent) case 1:/向下飞的敌机 POSITION pos1,p1; CEnemy *enemy1=new CEnemy(1); if(ListEnemy1.GetCount()setSpeed(enemyspeed);if(enemyone-Pos.ymove(1);elseListEnemy1.RemoveAt(p1);/向下飞的飞机的子弹POSITION posball1,pball1;CBall * ball1=new CBall(enemyone-getPoint().x+12,enemyone-getPoint().y+20,1);if (ListBall1.GetCount()setSpeed(ballspeed);if(ballone-getPoint().ymove(1);elseListBall1.RemoveAt(pball1); /向上飞的敌机this-GetClientRect(&rect);POSITION pos2,p2;CEnemy *enemy2=new CEnemy(-1);enemy2-setPoint(rand()%1000,rect.bottom-35);if(ListEnemy2.GetCount()setSpeed(enemyspeed); if (enemytwo-Pos.yrect.top) enemytwo-move(-1);elseListEnemy2.RemoveAt(p2);/向上飞的敌机的子弹POSITION posball2,pball2;CBall * ball2=new CBall(enemytwo-getPoint().x+12,enemytwo-getPoint().y+20,1);if (ListBall2.GetCount()setSpeed(ballspeed);if(balltwo-getPoint().yrect.top)balltwo-move(-1);elseListBall2.RemoveAt(pball2); this-Invalidate(TRUE);break;/战机炮弹打中敌机/ /声明战机子弹位置,敌机位置POSITION bombPos,bombTemp,enemyPos,enemyTemp;for(bombPos= ListBomb1.GetHeadPosition();(bombTemp=bombPos)!=NULL;)bomb = (CBomb *) ListBomb1.GetNext(bombPos);/获得战机子弹的矩形区域CRect bombRect = bomb-getRect(); /消灭从上往下飞的敌机for(enemyPos= ListEnemy1.GetHeadPosition();(enemyTemp=enemyPos)!=NULL;)enemy = (CEnemy *) ListEnemy1.GetNext(enemyPos);/获得敌机的矩形区域CRect enemyRect = enemy-getRect();/判断两个矩形区域是否有交接CRect tempRect;if(tempRect.IntersectRect(&bombRect,enemyRect)/将爆炸对象添加到爆炸链表中CExplosion *explosion=new CExplosion( enemy-getPoint().x+12),( enemy-getPoint().y+17);ListExplosion.AddTail(explosion);PlaySound(LPCTSTR)IDR_WAVE2, AfxGetInstanceHandle(), SND_RESOURCE |SND_ASYNC);/爆炸后删除子弹ListBomb1.RemoveAt(bombTemp);delete bomb;/删除敌机ListEnemy1.RemoveAt(enemyTemp);delete enemy;myscore+;/消灭从下往上飞的敌机for(enemyPos= ListEnemy2.GetHeadPosition();(enemyTemp=enemyPos)!=NULL;)enemy = (CEnemy *) ListEnemy2.GetNext(enemyPos);/获得敌机的矩形区域CRect enemyRect = enemy-getRect();/判断两个矩形区域是否有交接CRect tempRect;if(tempRect.IntersectRect(&bombRect,enemyRect)/将爆炸对象添加到爆炸链表中CExplosion *explosion=new CExplosion( enemy-getPoint().x+12),( enemy-getPoint().y+17);ListExplosion.AddTail(explosion);PlaySound(LPCTSTR)IDR_WAVE2, AfxGetInstanceHandle(), SND_RESOURCE |SND_ASYNC);/爆炸后删除子弹ListBomb1.RemoveAt(bombTemp);delete bomb;/删除敌机ListEnemy2.RemoveAt(enemyTemp);delete enemy;myscore+; /敌机子弹打中战机/声明敌机炸弹位置坐标,战机位置myPlanePosPOSITION ballPos,ballTemp;/从上往下飞的敌机子弹打中战机for(ballPos= ListBall1.GetHeadPosition();(ballTemp=ballPos)!=NULL;)ball = (CBall *) ListBall1.GetNext(ballPos);/获得敌机炸弹的矩形区域CRect ballRect = ball-getRect();/获得战机的矩形区域CRect myPlaneRect = myplane.getRect(); /判断两个矩形区域是否有交接CRect tempRect;/如果敌机炸弹打中战机,则使战机爆炸if(tempRect.IntersectRect(&ballRect,myPlaneRect) /将爆炸对象加入爆炸链表中CExplosion *explosion = new CExplosion( myplane.getPoint()

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论