飞机大战.doc_第1页
飞机大战.doc_第2页
飞机大战.doc_第3页
飞机大战.doc_第4页
飞机大战.doc_第5页
免费预览已结束,剩余23页可下载查看

下载本文档

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

文档简介

信息科学与工程学院软件实践实训报告实 训 报 告飞机大战游戏设计与开发专业名称:软件工程班 级: 学 号:信息科学与工程学院二零一三年十一月目 录1. 概述031.1 实训项目简介031.2 实训功能说明031.2.1 基本功能032. 相关技术032.1 基类的使用032.2 Windows定时器技术032.3获取矩形区域032.4内存释放043. 总体设计与详细设计043.1 系统模块划分043.2 主要功能模块054. 编码实现315. 实训中遇到的主要问题及解决方法326. 实训体会32281. 概述1.1 实训项目简介本次实训项目是做一个飞机大战的游戏,完成一个界面简洁流畅、游戏方式简单,玩起来易于上手的桌面游戏。该飞机大战项目运用的主要技术即是MFC编程中的一些函数、链表思想以及贴图技术。1.2 实训功能说明1.2.1 基本功能(1)设置一个战机具有一定的速度,通过键盘,鼠标,方向键可控制战机的位置,空格键发射子弹。(2)界面中敌机出现的位置为随机的。(3)对于随机产生的敌机和敌机炸弹,若超过矩形区域,则释放该对象。(4)添加爆炸效果,包括战机子弹打中敌机爆炸、敌机炸弹打中战机爆炸、战机与敌机相撞爆炸以及战机子弹与敌机炸弹相撞爆炸四种爆炸效果。且爆炸发生后敌机、子弹、炸弹均消失。2. 相关技术2.1基类的使用 在飞机大战的游戏中用到了很多基类,例如MyPlane、Bomb等等,这样使得游戏的实现更加规范,有效性。通过主函数的调用,实现了很多功能。2.2 Windows定时器技术Windows定时器是一种输入设备,它周期性地在每经过一个指定的时间间隔后就通知应用程序一次。程序将时间间隔告诉Windows,然后Windows给您的程序发送周期性发生的WM_TIMER消息以表示时间到了。本程序中使用多个定时器,分别控制不同的功能。在MFC的API函数中使用SetTimer()函数设置定时器,设置系统间隔时间,在OnTimer()函数中实现响应定时器的程序。2.3获取矩形区域首先,使用CRect定义一个对象,然后使用GetClientRect(&对象名)函数,获取界面的矩形区域rect.Width() 为矩形区域的宽度,rect.Height()为矩形区域的高度。使用IntersectRect(&,&)函数来判断两个源矩形是否有重合的部分。如果有不为空,则返回非零值;否则,返回0。2.4内存释放在VC/MFC用CDC绘图时,频繁的刷新,屏幕会出现闪烁的现象,CPU时间占用率相当高,绘图效率极低,很容易出现程序崩溃。及时的释放程序所占用的内存资源是非常重要的。在程序中使用到的刷子等占用内存资源的对象都要及时的删除。Delete Brush等。3. 总体设计与详细设计3.1 系统模块划分飞机大战游戏主要模块可以说是有几个重要的类组成的。首先是老师给出的CGameObject类,以及在其派生下的BOMB,BALL,ENEMY,MYPLANE等等。如图:3.2 主要功能模块主要功能是在飞机大战View类中,OnTimer函数中实现,将各个类调用,随机产生敌机,子弹的输出,爆炸的实现等等。它的实现图可以如下实现:游戏进入模块4. 编码实现4.1飞机大战view.cpp#include stdafx.h#include PlaneGame.h#include PlaneGameDoc.h#include PlaneGameView.h#include #pragma comment(lib, WINMM.LIB)#include #ifdef _DEBUG#define new DEBUG_NEW#endifIMPLEMENT_DYNCREATE(CPlaneGameView, CView)/使CObject的派生类的对象能够在运行时被动态创建。框架利用这种能力来动态地创建新对象BEGIN_MESSAGE_MAP(CPlaneGameView, CView)/ 标准打印命令ON_WM_CREATE()ON_WM_TIMER()ON_WM_UPDATEUISTATE()ON_WM_ERASEBKGND()ON_COMMAND(ID_restart, &CPlaneGameView:Onrestart)ON_COMMAND(ID_pause, &CPlaneGameView:Onpause)ON_WM_MOUSEMOVE()ON_WM_LBUTTONDOWN()/ON_COMMAND_RANGE(ID_ONE,ID_THREE, OnDoSomething)ON_COMMAND(ID_SETUP, &CPlaneGameView:OnSetup)END_MESSAGE_MAP()/ CPlaneGameView 构造/析构CPlaneGameView:CPlaneGameView():life(10),score(0),count_Life(1),Num(1),is_Pass(0),is_Pause(0)/战机生命值、战机得分、战机增加生命值数、关卡、是否过关、是否暂停/ TODO: 在此处添加构造代码/默认战机飞行速度speed = 30;/加载游戏对象图片CMyPlane:LoadImageW();CEnemy:LoadImageW();CBall:LoadImageW();CBomb:LoadImageUp();CBomb:LoadImageDown();CExplosion:LoadImageW();CBoss:LoadImageW();CPlaneGameView:CPlaneGameView()BOOL CPlaneGameView:PreCreateWindow(CREATESTRUCT& cs)/ TODO: 在此处通过修改/ CREATESTRUCT cs 来修改窗口类或样式return CView:PreCreateWindow(cs);/ CPlaneGameView 绘制void CPlaneGameView:OnDraw(CDC* pDC)/CDC类定义的是设备上下文对象的类。CPlaneGameDoc* pDoc = GetDocument();ASSERT_VALID(pDoc);/ASSERT_VALID什么也不做。在调试版本中,它检验一个指针是否为NULL,并且调用对象自己的AssertValid成员函数if (!pDoc)/return;/ TODO: 在此处为本机数据添加绘制代码/ CPlaneGameView 打印BOOL CPlaneGameView:OnPreparePrinting(CPrintInfo* pInfo)/ 默认准备return DoPreparePrinting(pInfo);void CPlaneGameView:OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)/ TODO: 添加额外的打印前进行的初始化过程void CPlaneGameView:OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)/ TODO: 添加打印后进行的清理过程/ CPlaneGameView 诊断#ifdef _DEBUGvoid CPlaneGameView:AssertValid() constCView:AssertValid();/是ASSERT_VALID的成员函数用来检查指针是否为空void CPlaneGameView:Dump(CDumpContext& dc) constCView:Dump(dc);CPlaneGameDoc* CPlaneGameView:GetDocument() const / 非调试版本是内联的?ASSERT(m_pDocument-IsKindOf(RUNTIME_CLASS(CPlaneGameDoc);/当m_pDocument不是一个CPlaneGameDoc指针时才结束程序return (CPlaneGameDoc*)m_pDocument;#endif /_DEBUG/ CPlaneGameView 消息处理程序int CPlaneGameView:OnCreate(LPCREATESTRUCT lpCreateStruct)if (CView:OnCreate(lpCreateStruct) = -1)return -1;/ TODO: 在此添加您专用的创建代码myplane = new CMyPlane;if(AfxMessageBox(L查看游戏说明请点击“是”,若直接进入游戏请点击“否”!,MB_YESNO)=6)AfxMessageBox(L方向键控制战机方向,空格键射击,鼠标均可控制。初始生命值为,消灭一个敌机加分,如果分数达到要求即可进入下一关。随着关卡增多,敌机速度和数量均增加,通过3关即可赢得胜利!);Sleep(1000);SetTimer(1,30,NULL);SetTimer(2,300,NULL);SetTimer(3,500,NULL);return 0;int flag=1;/标志那幅图片int is_flag=1;/设置游戏难度void CPlaneGameView:OnTimer(UINT_PTR nIDEvent)/ TODO: 在此添加消息处理程序代码和/或调用默认值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;if(flag=1)bitmap_BackGround.LoadBitmap(IDB_BACKGROUND);else if(flag=2)bitmap_BackGround.LoadBitmap(IDB_BACKGROUND2);else if(flag=3)bitmap_BackGround.LoadBitmap(IDB_BACKGROUND3);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);if(myplane!= NULL)myplane-Draw(&cdc,TRUE);/获得键盘消息if(GetKeyState(VK_UP) 0 | GetKeyState(W) GetPoint().yrect.top)myplane-SetPoint( myplane-GetPoint().x,myplane-GetPoint().y-speed);elsemyplane-SetPoint(myplane-GetPoint().x,rect.top);if(GetKeyState(VK_DOWN) 0| GetKeyState(S) GetPoint().y+60SetPoint( myplane-GetPoint().x,myplane-GetPoint().y+speed);elsemyplane-SetPoint( myplane-GetPoint().x,rect.bottom-55);if(GetKeyState(VK_LEFT) 0| GetKeyState(A) GetPoint().x 0) myplane-SetPoint(0, myplane-GetPoint().y);else myplane-SetPoint( myplane-GetPoint().x - speed) , myplane-GetPoint().y);if(GetKeyState(VK_RIGHT) 0| GetKeyState(D) GetPoint().x +50= rect.right) myplane-SetPoint(rect.right-50, myplane-GetPoint().y);else myplane-SetPoint(myplane-GetPoint().x+speed , myplane-GetPoint().y);if(GetKeyState(VK_SPACE)GetPoint().x, myplane-GetPoint().y,1);ListBomb.AddTail(BombOne);CBomb *BombTwo=new CBomb( myplane-GetPoint().x+35, myplane-GetPoint().y,1);ListBomb.AddTail(BombTwo);PlaySound(LPCTSTR)IDR_WAVE2, AfxGetInstanceHandle(), SND_RESOURCE |SND_ASYNC);if(GetKeyState(P)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=new CBall(enemy-GetPoint().x+17,enemy-GetPoint().y+30,enemy-GetMotion();ListBall.AddTail(ball);break;/判断产生的/Boss敌机是否出界,若已经出界,则删除该boss敌机POSITION bposEn=NULL,bposEn_t=NULL;bposEn=ListBoss.GetHeadPosition();while(bposEn!=NULL)bposEn_t=bposEn;CBoss *boss= (CBoss *)ListBoss.GetNext(bposEn);/判断boss敌机是否出界if(boss-GetPoint().xGetPoint().xrect.right|boss-GetPoint().yGetPoint().yrect.bottom) ListBoss.RemoveAt(bposEn_t);delete boss;/ifelse boss-Draw(&cdc,TRUE);switch(nIDEvent)case 2:/设置定时器产生敌机炸弹CBall * ball=new CBall(boss-GetPoint().x+17,boss-GetPoint().y+30,boss-GetMotion();ListBall.AddTail(ball);CBall * ball1=new CBall(boss-GetPoint().x+77,boss-GetPoint().y+30,boss-GetMotion();ListBall.AddTail(ball1);break;/判断产生的敌机炸弹是否出界,若已经出界,则删除该敌机炸弹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;else ball-Draw(&cdc,1);/战机发射子弹if( myplane!=NULL& is_Pause= 0)/声明战机子弹位置POSITION posBomb=NULL,bombTemp=NULL;posBomb= ListBomb.GetHeadPosition();while(posBomb!=NULL) bombTemp=posBomb; bomb=(CBomb *) ListBomb.GetNext(posBomb); if( bomb-GetPoint().xGetPoint().xrect.right | bomb-GetPoint().yGetPoint().yrect.bottom)/删除越界的子弹 ListBomb.RemoveAt(bombTemp);delete bomb;elsebomb-Draw(&cdc,TRUE);/添加爆炸效果,战机子弹打中敌机if( myplane!=NULL& is_Pause= 0)POSITION explosionPos;explosionPos = ListExplosion.GetHeadPosition();/检索爆炸链表,非空时在所在位置显示while(explosionPos!=NULL)explosion = (CExplosion *) ListExplosion.GetNext(explosionPos); explosion-Draw(&cdc,TRUE);/while/声明战机子弹位置,敌机位置POSITION bombPos,bombTemp,enemyPos,enemyTemp;for(bombPos= ListBomb.GetHeadPosition();(bombTemp=bombPos)!=NULL;)bomb = (CBomb *) ListBomb.GetNext(bombPos);/获得战机子弹的矩形区域CRect bombRect = bomb-GetRect();for(enemyPos= ListEnemy.GetHeadPosition();(enemyTemp=enemyPos)!=NULL;) enemy = (CEnemy *) ListEnemy.GetNext(enemyPos); /获得敌机的矩形区域 CRect enemyRect = enemy-GetRect(); /判断两个矩形区域是否有交接 CRect tempRect; if(tempRect.IntersectRect(&bombRect,enemyRect)/将爆炸对象添加到爆炸链表中CExplosion *explosion=new CExplosion( enemy-GetPoint().x+17),( enemy-GetPoint().y+17);ListExplosion.AddTail(explosion);PlaySound(LPCTSTR)IDR_WAVE, AfxGetInstanceHandle(), SND_RESOURCE |SND_ASYNC);/爆炸后删除子弹ListBomb.RemoveAt(bombTemp);delete bomb;/删除敌机ListEnemy.RemoveAt(enemyTemp);delete enemy;score+=1;break;int s=2;/战机打中boss敌机if( myplane!=NULL& is_Pause= 0)POSITION explosionPos;explosionPos = ListExplosion.GetHeadPosition();/检索爆炸链表,非空时在所在位置显示while(explosionPos!=NULL)explosion = (CExplosion *) ListExplosion.GetNext(explosionPos); explosion-Draw(&cdc,TRUE);/while/声明战机子弹位置,敌机位置POSITION bombPos,bombTemp,bossPos,bossTemp;for(bombPos= ListBomb.GetHeadPosition();(bombTemp=bombPos)!=NULL;)bomb = (CBomb *) ListBomb.GetNext(bombPos);/获得战机子弹的矩形区域CRect bombRect = bomb-GetRect();for(bossPos= ListBoss.GetHeadPosition();(bossTemp=bossPos)!=NULL;) Boss = (CBoss *) ListBoss.GetNext(bossPos); /获得敌机的矩形区域 CRect bossRect = Boss-GetRect(); /判断两个矩形区域是否有交接 CRect tempRect; if(tempRect.IntersectRect(&bombRect,bossRect)/将爆炸对象添加到爆炸链表中CExplosion *explosion=new CExplosion( Boss-GetPoint().x+17),( Boss-GetPoint().y+17);/爆炸后删除子弹ListBomb.RemoveAt(bombTemp);delete bomb;/删除敌机s-;if(s=0)ListExplosion.AddTail(explosion);PlaySound(LPCTSTR)IDR_WAVE, AfxGetInstanceHandle(), SND_RESOURCE |SND_ASYNC);ListBoss.RemoveAt(bossTemp);delete Boss;score+=10; /=添加爆炸效果,敌机炸弹打中战机/if( myplane != NULL& is_Pause= 0)/声明敌机炸弹位置坐标,战机位置myPlanePosPOSITION ballPos,ballTemp;for(ballPos= ListBall.GetHeadPosition();(ballTemp=ballPos)!=NULL;) ball = (CBall *) ListBall.GetNext(ballPos); /获得敌机炸弹的矩形区域 CRect ballRect = ball-GetRect(); /获得战机的矩形区域 CRect myPlaneRect = myplane-GetRect(); /判断两个矩形区域是否有交接 CRect tempRect;/如果敌机炸弹打中战机,则使战机爆炸 if(tempRect.IntersectRect(&ballRect,myPlaneRect) /将爆炸对象加入爆炸链表中CExplosion *explosion = new CExplosion( myplane-GetPoint().x + 25) , ( myplane-GetPoint().y + 30);PlaySound(LPCTSTR)IDR_WAVE2, AfxGetInstanceHandle(), SND_RESOURCE |SND_ASYNC);ListExplosion.AddTail(explosion);/战机生命值减life-;ListBall.RemoveAt(ballTemp);delete ball;if(life = 0)/删除战机对象delete myplane;myplane=NULL;/ifbreak;/if/for/if/敌机与战机相撞/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);/战机生命值减一life-;/删除敌机 ListEnemy.RemoveAt(enemyTemp);delete enemy;if(life = 0)/删除战机对象delete myplane;myplane=NULL;/ifbreak;/if/for/if/boss和敌机相撞if(myplane != NULL& is_Pause= 0)POSITION bossPos,bossTemp;for(bossPos= ListBoss.GetHeadPosition();(bossTemp=bossPos)!=NULL;) Boss =(CBoss *) ListBoss.GetNext(bossPos); /获得敌机的矩形区域 CRect bossRect = Boss-GetRect(); /获得战机的矩形区域 CRect myPlaneRect = myplane-GetRect(); /判断两个矩形区域是否有交接 CRect tempRect; if(tempRect.IntersectRect(&bossRect,myPlaneRect)CExplosion *explosion = new CExplosion( Boss-GetPoint().x+18 , Boss-GetPoint().y + 18);PlaySound(LPCTSTR)IDR_WAVE, AfxGetInstanceHandle(), SND_RESOURCE |SND_ASYNC);ListExplosion.AddTail(explosion);/战机生命值减一life-;/删除敌机 ListBoss.RemoveAt(bossTemp);delete Boss;life=life-4;if(life GetRect();for(ballPos= ListBall.GetHeadPosition();(ballTemp=ballPos)!=NULL;) ball = (CBall *) ListBall.GetNext(ballPos); /获得敌机炸弹的矩形区域 CRect ballRect = ball-GetRect(); /判断两个矩形区域是否有交接 CRect tempRect; if(tempRect.IntersectRect(&bombRect,ballRect)/将爆炸对象添加到爆炸链表中CExplosion *explosion=new CExplosion( ball-GetPoint().x+17),( ball-GetPoint().y+17);ListExplosion.AddTail(explosion);PlaySound(LPCTSTR)IDR_WAVE, AfxGetInstanceHandle(), SND_RESOURCE |SND_ASYNC);/爆炸后删除战机子弹ListBomb.RemoveAt(bombTemp);delete bomb;/删除敌机炸弹ListBall.RemoveAt(ballTemp);delete ball;score+;break;/if/for/for/if/游戏界面输出该游戏当前信息/if(myplane != NULL)HFONT font;CRect rect;GetClientRect(&rect);font=CreateFont(20,10,0,0,0,0,0,0,0,0,0,0,0,0);cdc.SelectObject(font);CString str;cdc.SetTextColor(RGB(255,0,0);str.Format(_T(关卡:%d),Num);cdc.TextOutW(rect.left,0,str);str.Format(_T(得分:%d),score);cdc.TextOutW(rect.left+40,40,str);str.Format(_T(生命:%d),life);cdc.TextOutW(rect.left+40,20,str); /ifif(myplane !=NULL & life 0)if(score 10*count_Life*Num)life+;/生命值加count_Life+;/已增加生命值加/=进入下一关界面/=/*void OnDoSomething( UINT nID )switch(nID)case ID_ONE:is_Pass=1;break;case ID_TWO:is_Pass=2;break;case ID_THREE:is_Pass=3;break;*/if(myplane!=NULL & score = 80 * Num& is_Pause= 0)/过关的标志变量myplane=NULL;delete myplane;is_Pass = 1;if(is_Pass = 1)if(Num=3)KillTimer(1);KillTimer(2);KillTimer(3);if(AfxMessageBox(L哇,恭喜你已通关!是否重新开始?,MB_YESNO)=6)/清空敌机链表ListEnemy.RemoveAll();/清空战机链表ListMe.RemoveAll();/清空战机子弹链表ListBomb.RemoveAll();/清空敌机炸弹链表ListBall.RemoveAll();/清空爆炸链表ListExplosion.RemoveAll();/添加新的战机对象ListBoss.RemoveAll();myplane = new CMyPlane;score=0;count_Life = 1;life = 10;Num = 1;is_Pass = 0;SetTimer(1,30,NULL);SetTimer(2,300,NULL);SetTimer(3,500,NULL);/ifelseexit(1);/ifelseKillTimer(1);KillTimer(2);KillTimer(3);if(AfxMessageBox(L恭喜你成功过关!是否进入下一

温馨提示

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

评论

0/150

提交评论