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

下载本文档

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

文档简介

信息科学与工程学院软件实践实训报告实 训 报 告飞机大战游戏设计与开发XXX专业名称: 班 级: 学 号: 信息科学与工程学院二零一三年十一月目 录1.概述-32. 相关技术-32.1 windows定时器-32.2 双缓冲技术 -32.3 CObList链表-32.4获取矩形区域 -42.5 CImageList处理爆炸效果-43.需求分析-44. 总体设计与详细设计-44.1 系统模块划分-44.2 主要功能模块-45. 编码实现-56. 测试情况说明-207. 实训中遇到的主要问题及解决方法-208. 实训体会-211.概述本次C+实训项目是做一个简单的飞机大战的游戏,应用MFC编程,完成一个界面简洁流畅、游戏方式简单,玩起来易于上手的桌面游戏。该飞机大战项目运用的主要技术即是MFC编程中的一些函数、链表思想以及贴图技术。2. 相关技术本次设计主要运用到MFC应用程序中的一些函数和技术。2.1 windows定时器Windows定时器是一种输入设备,它周期性地在每经过一个指定的时间间隔后就通知应用程序一次。程序将时间间隔告诉Windows,然后Windows给您的程序发送周期性发生的WM_TIMER消息以表示时间到了。本程序中使用多个定时器,分别控制不同的功能。在MFC的API函数中使用SetTimer()函数设置定时器,设置系统间隔时间,在OnTimer()函数中实现响应定时器的程序,用KillTimer()释放定时器2.2双缓冲技术双缓冲技术是在实现图片背景的插入时应用的,可以解决游戏界面上背景还有战机,敌机、子弹等图像闪动的问题。在使用双缓冲技术时,首先创建一个矩形区域插入一张位图图像,定义一个兼容的DC并创建DC,利用双缓冲技术插入位图图像,绘图完成后要清理。CBitmap MemBitmap;CDC MemDC;MemBitmap.CreateCompatibleBitmap(pDC,rect.right,rect.bottom);pDC-BitBlt(rect.left,rect.top,rect.right,rect.bottom,&MemDC,0,0,SRCCOPY);MemBitmap.DeleteObject();MemDC.DeleteDC();2.3 CObList链表MFC类库中提供了丰富的CObList类的成员函数,此程序主要用到的成员函数如下:(1) 构造函数,为CObject指针构造一个空的列表。(2) GetHead(),访问链表首部,返回列表中的首元素(列表不能为空)。(3) AddTail(),在列表尾增加一个元素或另一个列表的所有元素。(4) RemoveAll(),删除列表中所有的元素。(5) GetNext(),返回列表中尾元素的位置。(6) GetHeadPosition(),返回列表中首元素的位置。(7) RemoveAt(),从列表中删除指定位置的元素。创建各游戏对象:CEnemy *enemy1; CEnemy *enemy2;CBomb *bomb1; CBomb *bomb2;CBall *ball1; CBall *ball2;CExplosion *explosion;创建存储游戏对象的对象链表:CObList EnemyList1; CObList EnemyList2; CObList BombList1; CObList BombList2; CObList EnemyList1; CObList EnemyList2;CObList BallList1; CObList BallList2CObList ExplosionList;2.4获取矩形区域首先,使用CRect定义一个对象,然后使用GetClientRect(&对象名)函数,获取界面的矩形区域rect.Width() 为矩形区域的宽度,rect.Height()为矩形区域的高度。使用IntersectRect(&,&)函数来判断两个源矩形是否有重合的部分。如果有不为空,则返回非零值;否则,返回0。2.5 CImageList处理爆炸效果爆炸效果是连续的显示一系列的图片。如果把每一张图片都显示出来的话,占用的时间是非常多的,必然后导致程序的可行性下降。CImageList是一个“图象列表”是相同大小图象的集合,每个图象都可由其基于零的索引来参考。可以用来存放爆炸效果的一张图片,使用draw()函数来绘制在某拖拉操作中正被拖动的图象,即可连续绘制出多张图片做成的爆炸效果。3.需求分析在本次飞机大战游戏程序设计中,主要的功能包括战机、敌机的功能,其他功能相对的因为游戏规则而产生,具体如下:1、战机能够通过操作鼠标或键盘上的上下左右键来移动,通过空格键来发射子弹,并且能够攻击敌机;2、敌机不能够左右移动,但是敌机出现的位置不同,可以通过初始化敌机的位置实现敌机的向下或向上移动;3、在战机与敌机发生碰撞,战机的子弹攻击到敌机,敌机的子弹攻击到战机,都能够在游戏界面中看到爆炸效果,并能够听到爆炸的声音;4、游戏中分别设置了键盘“A”键和“Z”键,“A”键可以暂停游戏,“Z”键则是开始游戏;5、在游戏规则上,战机与敌机发生碰撞或敌机的子弹攻击到战机时,战机的生命值会减1,战机的子弹攻击到敌机时,游戏的得分会加1;6、当生命值减少到0时,会出现提示窗口,提示是否继续游戏。4. 总体设计与详细设计4.1 系统模块划分该飞机大战游戏程序分为游戏背景位图绘制模块、各游戏对象绘制模块、游戏对象的碰撞模块、爆炸效果产生模块、游戏界面输出玩家得分生命值信息模块。其中在游戏对象绘制模块中,战机是唯一对象,在游戏开始时产生该对象,赋予其固定的生命值,当其与敌机对象、敌机炸弹碰撞时使其生命值减一,直至生命值为零,游戏结束。敌机对象与敌机炸弹对象的绘制中采用定时器技术,定时产生。爆炸对象初始化为空,当游戏过程中即时发生碰撞时,在碰撞位置产生爆炸对象,添加到爆炸链表中。4.2 主要功能模块CGameObject是各个游戏对象的抽象父类,继承自CObject类,其他的类:战机类、敌机类、爆炸类、子弹类、炸弹类都继承了此类。每个游戏对象类中既继承了来自父类CGameObject的属性,又有自己的特有属性和方法。类图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);/战机的子弹CBomb* bomb1;/左排战机子弹POSITION Pos1;for(Pos1=BombList1.GetHeadPosition();Pos1!=NULL;)bomb1=(CBomb*)BombList1.GetNext(Pos1);bomb1-draw(&MemDC);CBomb* bomb2;/右排战机子弹POSITION Pos2;for(Pos2=BombList2.GetHeadPosition();Pos2!=NULL;)bomb2=(CBomb*)BombList2.GetNext(Pos2);bomb2-draw(&MemDC);/敌机/向下飞的敌机CEnemy* enemy1;POSITION Posenemy1;for(Posenemy1=EnemyList1.GetHeadPosition();Posenemy1!=NULL;)enemy1=(CEnemy*)EnemyList1.GetNext(Posenemy1);enemy1-draw(&MemDC);/向上飞的敌机CEnemy* enemy2;POSITION Posenemy2;for(Posenemy2=EnemyList2.GetHeadPosition();Posenemy2!=NULL;)enemy2=(CEnemy*)EnemyList2.GetNext(Posenemy2);enemy2-draw(&MemDC);/敌机的子弹/向下飞的敌机的子弹CBall* ball1;POSITION posball1;for (posball1=BallList1.GetHeadPosition();posball1!=NULL;)ball1=(CBall*)BallList1.GetNext(posball1);ball1-draw(&MemDC);/向上飞的敌机的子弹CBall* ball2;POSITION posball2;for (posball2=BallList2.GetHeadPosition();posball2!=NULL;)ball2=(CBall*)BallList2.GetNext(posball2);ball2-draw(&MemDC);/爆炸CExplosion* explosion;POSITION Posexplosion1,Posexplosion2;for(Posexplosion1 = ExplosionList.GetHeadPosition();Posexplosion1!=NULL;)Posexplosion2=Posexplosion1;explosion = (CExplosion *) ExplosionList.GetNext(Posexplosion1);if(explosion-draw(&MemDC)=0)ExplosionList.RemoveAt(Posexplosion2);/输出游戏画面上的文字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),score);MemDC.TextOut(10,10,str);str.Format(_T(剩余生命:%d),lifeNum);MemDC.TextOut(10,30,str);pDC-BitBlt(rect.left,rect.top,rect.right,rect.bottom,&MemDC,0,0,SRCCOPY);MemBitmap.DeleteObject();MemDC.DeleteDC();void CPlaneGameView:OnInitialUpdate()CView:OnInitialUpdate();/ TODO: 在此添加专用代码和/或调用基类/加载战机图片 myplane.LoadImages(); GetClientRect(&rect);myplane.SetPoint(rect.right/2,rect.bottom/2+100);/加载战机子弹图片CBomb:LoadImages(); /加载敌机图片CEnemy:LoadImages();/加载敌机子弹图片CBall:LoadImages();/加载爆炸效果图片CExplosion:LoadImages();/设置定时器this-SetTimer(1,100,0);void CPlaneGameView:OnTimer(UINT_PTR nIDEvent) /键盘“A”键暂停游戏,“Z”键开始游戏,上下左右键控制战机移动,空格键发子弹GetClientRect(&rect);if(GetKeyState(A)0)isPause = 1;/ifif(GetKeyState(Z)0)isPause = 0;/ifif(isPause=0)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-60)myplane.move(4);if (GetKeyState(VK_SPACE)SetSpeed(30);if (Bomb1-pos.yrect.top)Bomb1-move();elseBombList1.RemoveAt(Postion1);/右排战机子弹POSITION Pos2,Postion2;CBomb *Bomb2;for(Pos2=BombList2.GetHeadPosition();Pos2!=NULL;)Postion2=Pos2;Bomb2=(CBomb*)BombList2.GetNext(Pos2);Bomb2-SetSpeed(30);if (Bomb2-pos.yrect.top)Bomb2-move();elseBombList2.RemoveAt(Postion2);/敌机发射子弹if(isPause = 0)switch(nIDEvent)case 1:/向下飞的敌机POSITION posenemy1,PosEnemy1;CEnemy *enemy1=new CEnemy(1);if(EnemyList1.GetCount()SetSpeed(10);if(en1-pos.ymove(1);elseEnemyList1.RemoveAt(PosEnemy1);/向下飞的飞机的子弹POSITION posball1,PosBall1;CBall * ball1=new CBall(en1-GetPoint().x+12,en1-GetPoint().y+20,1);if (BallList1.GetCount()SetSpeed(20);if(ba1-GetPoint().ymove(1);elseBallList1.RemoveAt(PosBall1);/for/for/向上飞的敌机POSITION posenemy2,PosEnemy2;CEnemy *enemy2=new CEnemy(-1);if(EnemyList2.GetCount()SetSpeed(30);if (en2-pos.yrect.top)en2-move(-1);elseEnemyList2.RemoveAt(PosEnemy2);/向上飞的敌机的子弹POSITION posball2,PosBall2;CBall * ball2=new CBall(en2-GetPoint().x+12,en2-GetPoint().y-20,1);if (BallList2.GetCount()SetSpeed(20);if(ba2-GetPoint().yrect.top)ba2-move(-1);elseBallList2.RemoveAt(PosBall2);/for/forthis-Invalidate(TRUE);break;/switch/if/实现爆炸CRect tempRect;POSITION pointPos,pointTemp,pointPos1,pointTemp2;/战机左排子弹打中向下走的敌机for(pointPos=EnemyList1.GetHeadPosition();pointPos!=NULL;)pointTemp=pointPos;enemy1=(CEnemy*)EnemyList1.GetNext(pointPos);CRect enemyRect = enemy1-GetRect();for(pointPos1=BombList1.GetHeadPosition();pointPos1!=NULL;)pointTemp2=pointPos1;bomb1=(CBomb*)BombList1.GetNext(pointPos1);CRect bombRect = bomb1-GetRect();/判断两个矩形区域是否有交接if(tempRect.IntersectRect(&bombRect,enemyRect)/将爆炸对象添加到爆炸链表中CExplosion *explosion=new CExplosion(enemy1-GetPoint().x+17),(enemy1-GetPoint().y+17);ExplosionList.AddHead(explosion);PlaySound(LPCTSTR)IDR_WAVE4, AfxGetInstanceHandle(), SND_RESOURCE |SND_ASYNC);/删除子弹if(BombList1.GetHeadPosition()=pointTemp)BombList1.RemoveHead();delete bomb1;else if(BombList1.GetTailPosition()=pointTemp)BombList1.RemoveTail();delete bomb1;else if(BombList1.GetAt(pointTemp2)!=NULL)BombList1.RemoveAt(pointTemp2);delete bomb1;/删除敌机if(EnemyList1.GetHeadPosition()=pointTemp2)EnemyList1.RemoveHead();delete enemy1;else if(EnemyList1.GetTailPosition()=pointTemp2)EnemyList1.RemoveTail();delete enemy1;else if(EnemyList1.GetAt(pointTemp)!=NULL)EnemyList1.RemoveAt(pointTemp);delete enemy1;score+;break;/if/for/for/战机左排子弹打中向上走的敌机for(pointPos=EnemyList2.GetHeadPosition();pointPos!=NULL;)pointTemp=pointPos;enemy2=(CEnemy*)EnemyList2.GetNext(pointPos);CRect enemyRect = enemy2-GetRect();for(pointPos1=BombList1.GetHeadPosition();pointPos1!=NULL;)pointTemp2=pointPos1;bomb1=(CBomb*)BombList1.GetNext(pointPos1);CRect bombRect = bomb1-GetRect();/判断两个矩形区域是否有交接if(tempRect.IntersectRect(&bombRect,enemyRect)/将爆炸对象添加到爆炸链表中CExplosion *explosion=new CExplosion(enemy2-GetPoint().x+17),(enemy2-GetPoint().y+17);ExplosionList.AddHead(explosion);PlaySound(LPCTSTR)IDR_WAVE4, AfxGetInstanceHandle(), SND_RESOURCE |SND_ASYNC);/删除子弹if(BombList1.GetHeadPosition()=pointTemp)BombList1.RemoveHead();delete bomb1;else if(BombList1.GetTailPosition()=pointTemp)BombList1.RemoveTail();delete bomb1;else if(BombList1.GetAt(pointTemp2)!=NULL)BombList1.RemoveAt(pointTemp2);delete bomb1;/删除敌机if(EnemyList2.GetHeadPosition()=pointTemp2)EnemyList2.RemoveHead();delete enemy2;else if(EnemyList2.GetTailPosition()=pointTemp2)EnemyList2.RemoveTail();delete enemy2;else if(EnemyList2.GetAt(pointTemp)!=NULL)EnemyList2.RemoveAt(pointTemp);delete enemy2;score+;break;/if/for/for/战机左排子弹打中向下走的敌机for(pointPos=EnemyList1.GetHeadPosition();pointPos!=NULL;)pointTemp=pointPos;enemy1=(CEnemy*)EnemyList1.GetNext(pointPos);CRect enemyRect = enemy1-GetRect();for(pointPos1=BombList2.GetHeadPosition();pointPos1!=NULL;)pointTemp2=pointPos1;bomb2=(CBomb*)BombList2.GetNext(pointPos1);CRect bombRect = bomb2-GetRect();/判断两个矩形区域是否有交接if(tempRect.IntersectRect(&bombRect,enemyRect)/将爆炸对象添加到爆炸链表中CExplosion *explosion=new CExplosion(enemy1-GetPoint().x+17),(enemy1-GetPoint().y+17);ExplosionList.AddHead(explosion);PlaySound(LPCTSTR)IDR_WAVE4, AfxGetInstanceHandle(), SND_RESOURCE |SND_ASYNC);/删除子弹if(BombList2.GetHeadPosition()=pointTemp)BombList2.RemoveHead();delete bomb2;else if(BombList2.GetTailPosition()=pointTemp)BombList2.RemoveTail();delete bomb2;else if(BombList2.GetAt(pointTemp2)!=NULL)BombList2.RemoveAt(pointTemp2);delete bomb2;/删除敌机if(EnemyList1.GetHeadPosition()=pointTemp2)EnemyList1.RemoveHead();delete enemy1;else if(EnemyList1.GetTailPosition()=pointTemp2)EnemyList1.RemoveTail();delete enemy1;else if(EnemyList1.GetAt(pointTemp)!=NULL)EnemyList1.RemoveAt(pointTemp);delete enemy1;score+;break;/if/for/for/战机右排子弹打中向下走的敌机for(pointPos=EnemyList2.GetHeadPosition();pointPos!=NULL;)pointTemp=pointPos;enemy2=(CEnemy*)EnemyList2.GetNext(pointPos);CRect enemyRect = enemy2-GetRect();for(pointPos1=BombList2.GetHeadPosition();pointPos1!=NULL;)pointTemp2=pointPos1;bomb2=(CBomb*)BombList2.GetNext(pointPos1);CRect bombRect = bomb2-GetRect();/判断两个矩形区域是否有交接if(tempRect.IntersectRect(&bombRect,enemyRect)/将爆炸对象添加到爆炸链表中CExplosion *explosion=new CExplosion(enemy2-GetPoint().x+17),(enemy2-GetPoint().y+17);ExplosionList.AddHead(explosion);PlaySound(LPCTSTR)IDR_WAVE4, AfxGetInstanceHandle(), SND_RESOURCE |SND_ASYNC);/删除子弹if(BombList2.GetHeadPosition()=pointTemp)BombList2.RemoveHead();delete bomb2;else if(BombList2.GetTailPosition()=pointTemp)BombList2.RemoveTail();delete bomb2;else if(BombList2.GetAt(pointTemp2)!=NULL)BombList2.RemoveAt(pointTemp2);delete bomb2;/删除敌机if(EnemyList2.GetHeadPosition()=pointTemp2)EnemyList2.RemoveHead();delete enemy2;else if(EnemyList2.GetTailPosition()=pointTemp2)EnemyList2.RemoveTail();delete enemy2;else if(EnemyList2.GetAt(pointTemp)!=NULL)EnemyList2.RemoveAt(pointTemp);delete enemy2;score+;break;/if/for/for /敌机向下的子弹打中战机for(pointPos=BallList1.GetHeadPosition();pointPos!=NULL;)pointTemp=pointPos;ball1=(CBall*)BallList1.GetNext(pointPos);CRect ballRect = ball1-GetRect();CRect planeRect = myplane.GetRect();/判断两个矩形区域是否有交接if(tempRect.IntersectRect(&ballRect,planeRect)if(pointTemp=BallList1.GetHeadPosition()BallList1.RemoveHead();delete ball1;else if(pointTemp=BallList1.GetTailPosition()BallList1.RemoveTail();delete ball1;else if(BallList1.GetAt(pointTemp)!=NULL)BallList1.RemoveAt(pointTemp);delete ball1;lifeNum-;/if/for/敌机向上的子弹打中战机for(pointPos=BallList2.GetHeadPosition();pointPos!=NULL;)pointTemp=pointPos;ball2=(CBall*)BallList2.GetNext(pointPos);CRect ballRect = ball2-GetRect();CRect planeRect = myplane.GetRect();/判断两个矩形区域是否有交接if(tempRect.IntersectRect(&ballRect,planeRect)if(pointTemp=BallList2.GetHeadPosition()BallList2.RemoveHead();delete ball2;else if(pointTemp=BallList2.GetTailPosition()BallList2.RemoveTail();delete ball2;else if(BallList2.GetAt(pointTemp)!=NULL)BallList2.RemoveAt(pointTemp);delete ball2;lifeNum-;/if/for/战机与向下走的敌机相撞for(poi

温馨提示

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

评论

0/150

提交评论