飞机大战程序设计报告.docx
- 文档编号:28245913
- 上传时间:2023-07-09
- 格式:DOCX
- 页数:28
- 大小:632.37KB
飞机大战程序设计报告.docx
《飞机大战程序设计报告.docx》由会员分享,可在线阅读,更多相关《飞机大战程序设计报告.docx(28页珍藏版)》请在冰豆网上搜索。
飞机大战程序设计报告
程序设计综合实践
实习报告
一、实习题目:
飞机大战游戏
二、实习时间:
2014.9.20-2014.9.30实习地点:
J13-132、232
三、实习任务:
通过项目实战,掌握C++面向对象编程的基础技术和Windows应用程序的编程方法,能够运用MFC技术及其开发环境进行小项目的开发。
四、小组分工说明:
五、实习成绩
六、指导教师对实习的评语:
指导教师(签章):
年月日
飞机大战游戏
1.实习目的
1.1使学生全面了解软件项目实施的过程,理解软件企业对于程序员的基本素质和技术能力要求。
1.2使学生掌握C++及Window程序设计的基本技术,能够运用MFC技术及其开发环境进行小型项目的开发。
1.3重点培养学生的独立创新精神和查阅资料能力,提高其口头和书面的沟通能力。
1.4使学生掌握快速学习新知识、新技术方法,培养良好的分析问题和解决问题的能力
1.5重点提高学生的编程能力,使学生建立正确的编程理念,养成规范的编程习惯。
2.实习计划
1、9.20—9.21先建立CGameObject类,利用继承机制,根据此类进行依次的派生。
2、9.22—9.25再建立派生类:
Bomb,Ball,Enemy,MyPlane,Explosion等,并实现各自功能。
3、9.26—9.29在xxView.cpp中的OnTimer中实现背景的设置,对敌机,导弹,敌机子弹,爆炸效果的绘制,以及敌机子弹和战机,导弹和敌机的碰撞检验,并添加爆炸效果
4、9.29—9.30最后释放pDC以及定时器
3.实习过程
3.1技术准备
透明贴图技术
绘制透明位图的关键就是创建一个“掩码”位图(maskbitmap),这个“掩码”位图是一个单色位图,它是位图中图像的一个单色剪影。
在详细介绍实现过程之前先介绍下所使用的画图函数以及函数参数所代表的功能;整个绘制过程需要使用到BitBlt()函数。
整个功能的实现过程如下:
(1)创建一张大小与需要绘制图像相同的位图作为“掩码”位图;
(2)将新创建的“掩码”位图存储至掩码位图的设备描述表中;
(3)把位图设备描述表的背景设置成“透明色”,不需要显示的颜色;
(4)复制粘贴位图到“掩码”位图的设备描述表中,这个时候“掩码”位图设备描述表中存放的位图与位图设备描述表中的位图一样;
(5)把需要透明绘制的位图与对话框绘图相应区域的背景进行逻辑异或操作绘制到对话框上;
(6)把“掩码”位图与这个时候对话框相应区域的背景进行逻辑与的操作;
(7)重复步骤5的操作,把需要透明绘制的位图与对话框绘图相应区域的背景进行逻辑异或操作绘制到对话框上;
(8)最后把系统的画笔还给系统,删除使用过的GDIObject,释放非空的指针,最后把新建的设备描述表也删除。
BOOLCGameObject:
:
LoadImage(CImageList&imgList,UINTbmpID,COLORREFcrMask,intcx,intcy,intnInitial)
{
CBitmapbmp;
if(!
bmp.LoadBitmap(bmpID))
returnFALSE;
if(!
imgList.Create(cx,cy,ILC_COLOR24|ILC_MASK,nInitial,0))//图像的长、宽、显示样式、图像可控数
returnFALSE;
imgList.Add(&bmp,crMask);//滤掉底色
returnTRUE;
}
CObList链表
在本程序中使用了CObList链表来分别存储敌机,炸弹,导弹,爆炸效果。
CObList链表类似于一个双向链表,POSITION类型的变量为链表的键。
使用POSITION变量,既可以作为链表循环中的循环变量,也可以作为标记某个位置的标签。
我们可以通过获得莫元素的POSITION()来访问它。
本程序中主要用到的函数有:
GetHeadPosition()——获取链表首元素的POSITION
AddTail()——向链表尾部添加新的元素
GetNext(POSITION&rPosition)——返回当前rPosition指向的元素,并使rPosition指向下一个元素
碰撞检验相关函数
用CRect类中的GetRect()函数可以获得当前对象的矩形区域,IntersectRect()函数判断战机与敌机、子弹与战机,导弹与敌机,导弹与子弹是否相撞。
设置定时器、销毁定时器
Windows定时器是一种输入设备,它周期性地在每经过一个指定的时间间隔后就通知应用程序一次。
程序将时间间隔告诉Windows,然后Windows给您的程序发送周期性发生的WM_TIMER消息,以表示时间到了。
SetTimer()函数来设置定时器,控制每隔多少毫秒执行一次什么任务。
用KillTime函数来销毁定时器。
键盘控制
添加OnKeyDown()和OnKeyUp()函数,通过修改战机的相应参数来实现对战机的控制,如上下左右运动,发射子弹等等。
双缓冲技术
关于双缓冲技术主要就是利用缓存的原理进行将所有的东西都先存在一个缓冲的虚拟的区域,然后再一次性的将所有的虚拟缓存中的东西都放入实在的存储器中。
CDC*pDC=GetDC();
CDCcdc;
cdc.CreateCompatibleDC(pDC);//依附窗口DC创建兼容内存DC
所有的图像文字均存入cdc中,然后一次性的通过
cdc.BitBlt(0,0,rc.Width(),rc.Height(),&cdc,0,0,SRCCOPY);//双缓冲BitBlt()函数,防止窗口刷新而闪烁
将内存DC上的图像拷贝到前台
cdc.DeleteDC();
bitmap1.DeleteObject();
ReleaseDC(pDC);
添加爆炸效果函数
PlaySound("H:
\\xx1\\Explode",NULL,SND_FILENAME|SND_ASYNC);
弹出对话框函数
if(life==0)
{
AfxMessageBox("GameOver!
",0,0);
break;
}
3.2项目实施
3.2.1功能需求
战机数量为1
由玩家通过键盘控制(方向控制位置、默认开启炸弹,空格键发射清屏导弹)战机
导弹遇到敌机发生爆炸,敌机被炸毁,导弹消失,玩家得分
有计算机控制敌机自动向战机发动攻击,战机有10条生命
敌机数量随机,计算机生成敌机时随机选择类别
敌机行驶期间,不左右移动,不反向移动
在游戏界面输出当前游戏进行信息,包括当前得分、击中敌机数量
游戏过程中添加了声效
3.2.2总体设计
系统模块划分
有两个主要的部分组成,分别是规则子系统、游戏规则子系统。
游戏规则子系统
模块名称
功能简述
人工智能
人机对战规则的实现
游戏子系统
模块名称
功能简述
应用程序对象
游戏程序的加载、游戏对象的绘制、游戏规则的调用、玩家的键盘事件获取
游戏对象
各个游戏对象的抽象父类
战机对象
战机类
敌机对象
敌机类
导弹对象
导弹类
炸弹对象
炸弹类
爆炸对象
爆炸类
文字对象
文字类
物品对象
物品类
类体系
系统对象类图
UML
产生敌机并绘制敌机流程图
3.2.3详细设计与编码
BOOLCXxView:
:
PreCreateWindow(CREATESTRUCT&cs)
{
//TODO:
ModifytheWindowclassorstylesherebymodifying
//theCREATESTRUCTcs
returnCView:
:
PreCreateWindow(cs);
}
/////////////////////////////////////////////////////////////////////////////
//CXxViewdrawing
voidCXxView:
:
OnDraw(CDC*pDC)
{
CXxDoc*pDoc=GetDocument();
ASSERT_VALID(pDoc);
/*//CDC*pDC=GetDC();
staticintx=0;
RECTrc;
GetClientRect(&rc);//获得窗体的尺寸
CBitmapbmp1;
bmp1.LoadBitmap(IDB_BITMAP9);//创建位图
CBrushbrush;
brush.CreatePatternBrush(&bmp1);
CBrush*pbrush=pDC->SelectObject(&brush);//将刷子选入pDC
pDC->Rectangle(&rc);
pDC->SelectObject(pbrush);//回复原来的刷子,规则
/*CDC*m_pMemDC1;//为绘图提供成员函数
m_pMemDC1=newCDC;//为绘图申请内存空间
m_pMemDC1->CreateCompatibleDC(pDC);
CBitmapbmp1;
/*bmp1.LoadBitmap(IDB_BITMAP11);//创建位图
m_pMemDC1->SelectObject(&bmp1);
pDC->BitBlt(0,0,480,644,m_pMemDC1,0,0,SRCCOPY);
DeleteObject(bmp1);
deletem_pMemDC1;//释放内存*/
/*myplane.Draw(pDC,0);
enemy.Draw(pDC,0);
ball.Draw(pDC,0);
bomb.Draw(pDC,0);
explosion.Draw(pDC,0);*/
//TODO:
adddrawcodefornativedatahere
}
/////////////////////////////////////////////////////////////////
//CXxViewprinting
BOOLCXxView:
:
OnPreparePrinting(CPrintInfo*pInfo)
{
//defaultpreparation
returnDoPreparePrinting(pInfo);
}
voidCXxView:
:
OnBeginPrinting(CDC*/*pDC*/,CPrintInfo*/*pInfo*/)
{
//TODO:
addextrainitializationbeforeprinting
}
voidCXxView:
:
OnEndPrinting(CDC*/*pDC*/,CPrintInfo*/*pInfo*/)
{
//TODO:
addcleanupafterprinting
}
/////////////////////////////////////////////////////////////////
//CXxViewdiagnostics
#ifdef_DEBUG
voidCXxView:
:
AssertValid()const
{
CView:
:
AssertValid();
}
voidCXxView:
:
Dump(CDumpContext&dc)const
{
CView:
:
Dump(dc);
}
CXxDoc*CXxView:
:
GetDocument()//non-debugversionisinline
{
ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CXxDoc)));
return(CXxDoc*)m_pDocument;
}
#endif//_DEBUG
/////////////////////////////////////////////////////////////////
//CXxViewmessagehandlers
intfireflag=0;
voidCXxView:
:
OnKeyDown(UINTnChar,UINTnRepCnt,UINTnFlags)
{
//TODO:
Addyourmessagehandlercodehereand/orcalldefault
if(nChar==VK_RIGHT)//VK_LEFT、VK_DOWN、VK_UP
{
myplane.SetHorMotion
(1);
}
if(nChar==VK_LEFT)//VK_LEFT、VK_DOWN、VK_UP
{
myplane.SetHorMotion(-1);
}
if(nChar==VK_UP)//VK_LEFT、VK_DOWN、VK_UP
{
myplane.SetVerMotion
(1);
}
if(nChar==VK_DOWN)//VK_LEFT、VK_DOWN、VK_UP
{
myplane.SetVerMotion(-1);
}
if(nChar==VK_SPACE)
{
fireflag=1;
}
CView:
:
OnKeyDown(nChar,nRepCnt,nFlags);
}
voidCXxView:
:
OnKeyUp(UINTnChar,UINTnRepCnt,UINTnFlags)
{
//TODO:
Addyourmessagehandlercodehereand/orcalldefault
if(nChar==VK_RIGHT||nChar==VK_LEFT||nChar==VK_UP||nChar==VK_DOWN)//VK_LEFT、VK_DOWN、VK_UP
{
if(nChar==VK_RIGHT)//VK_LEFT、VK_DOWN、VK_UP
{
myplane.SetHorMotion(0);
}
if(nChar==VK_LEFT)//VK_LEFT、VK_DOWN、VK_UP
{
myplane.SetHorMotion(0);
}
if(nChar==VK_UP)//VK_LEFT、VK_DOWN、VK_UP
{
myplane.SetVerMotion(0);
}
if(nChar==VK_DOWN)//VK_LEFT、VK_DOWN、VK_UP
{
myplane.SetVerMotion(0);
}
}
//TODO:
Addyourmessagehandlercodehereand/orcalldefault
if(nChar==VK_SPACE)
{
fireflag=0;
}
CView:
:
OnKeyUp(nChar,nRepCnt,nFlags);
}
intCXxView:
:
OnCreate(LPCREATESTRUCTlpCreateStruct)
{
if(CView:
:
OnCreate(lpCreateStruct)==-1)
return-1;
//TODO:
Addyourspecializedcreationcodehere
//安装定时器
SetTimer(2,45,NULL);
/*MyPlane:
:
LoadImage();
Enemy:
:
LoadImage();
Bomb:
:
LoadImage();
Ball:
:
LoadImage();
Explosion:
:
LoadImage();*/
//1是定时器的标示符,30ms的间隔,NULL表示让窗体接受消息,而不是函数
return0;
}
voidCXxView:
:
OnTimer(UINTnIDEvent)
{
//TODO:
Addyourmessagehandlercodehereand/orcalldefault
CXxDoc*pDoc=GetDocument();
ASSERT_VALID(pDoc);
CDC*pDC=GetDC();
staticintx=0;
CRectrc;//定义客户区
GetClientRect(&rc);//获得窗体的尺寸
CDCcdc;//设备环境对象
CBitmapbitmap1;//内存位图
cdc.CreateCompatibleDC(pDC);//建立与位图相应的内存设备上下文
bitmap1.CreateCompatibleBitmap(pDC,rc.Width(),rc.Height());
CBitmap*pOldBit=cdc.SelectObject(&bitmap1);
cdc.FillSolidRect(rc,RGB(51,255,255));
//绘制蓝天
//创建一个蓝色的刷子
/*CBrushbrush;
brush.CreateSolidBrush(RGB(84,142,239));
CBrush*pbrush=pDC->SelectObject(&brush);//将刷子选入pDC
pDC->Rectangle(&rc);
pDC->SelectObject(pbrush);//回复原来的刷子,规则*/
CBitmapbmp1;
bmp1.LoadBitmap(IDB_BITMAP8);//创建位图
CBrushbrush;
brush.CreatePatternBrush(&bmp1);
CBrush*pbrush=pDC->SelectObject(&brush);//将刷子选入pDC
pDC->Rectangle(&rc);
pDC->SelectObject(pbrush);//回复原来的刷子,规则
/*if(life!
=0)
{
myplane.Draw(pDC,0);
}*/
staticintlife=10;
staticintscore=0;
//-----------------------------------------------绘制战机---------------------------------------------------//
if(life!
=0)
{
myplane.Draw(pDC,0);
}
/*enemy.Draw(pDC,0);
bomb.Draw(pDC,0);
ball.Draw(pDC,0);
explosion.Draw(pDC,0);*/
//--------------------------------------------------绘制敌机---------------------------------------------------//
if(life!
=0)
{
staticintm=0;
if(m<=0)
{
m=rand()%40;
listenemy.AddTail(newEnemy);
}
m--;
POSITIONpenemy1=NULL,penemy2=NULL;//POSITION是一个空结构体的指针POSITION类型的变量为链表的键。
使用POSITION变量,既可以作为链表循环中的循环变量,也可以作为标记某个位置的标签。
我们可以通过获得某元素的POSITION来访问它。
penemy1=listenemy.GetHeadPosition();
while((penemy2=penemy1)!
=NULL)//GetHeadPosition返回列表中首元素的位置
{
enemy=(Enemy*)listenemy.GetNext(penemy1);//遍历链表
if(!
enemy->Draw(pDC,0))
{
listenemy.RemoveAt(penemy2);
deleteenemy;
}
intx=rand()%40;//子弹距离
if(x==1)
{
listball.AddTail(newBall(enemy->GetPoint().x+12,enemy->GetPoint().y,enemy->GetMontion()));
}
}
}
//--------------------------------------------------添加战机导弹--------------------------------------------//
if(fireflag==1)
{
PlaySound("H:
\\xx1\\FIRE",NULL,SND_FILENAME|SND_ASYNC);
listbomb.AddTail(newBomb(myplane.GetPoint().x+10,myplane.GetPoint().y));
listbomb.AddTail(newBomb(myplane.GetPoint().x+30,myplane.GetPoint().y));
}
POSITIONpbomb1=NULL,pbomb2=NULL;
pbomb1=listbomb.GetHeadPosition();
while((pbomb2=pbomb1)!
=NULL)
{
bomb=(Bomb*)listbomb.GetNext(pbomb1);
if(!
bomb->Draw(pDC,0))
{
listbomb.RemoveAt(pbomb2);
deletebomb;
}
}
//-------------------------------------------------添加敌机子弹----------------------------------------------//
if(li
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 飞机 大战 程序设计 报告