c++飞机大战实训报告word文档良心出品.docx
- 文档编号:11568791
- 上传时间:2023-03-19
- 格式:DOCX
- 页数:17
- 大小:45.33KB
c++飞机大战实训报告word文档良心出品.docx
《c++飞机大战实训报告word文档良心出品.docx》由会员分享,可在线阅读,更多相关《c++飞机大战实训报告word文档良心出品.docx(17页珍藏版)》请在冰豆网上搜索。
c++飞机大战实训报告word文档良心出品
实训报告
飞机大战游戏设计与开发
姓名:
陆再旺
专业名称:
___数字媒体技术___________
班级:
______2011级__________________
学号:
___201101051114____________
信息科学与工程学院
二零一三年十二月
1.项目概述
此次实训主要是做一个飞机大战的游戏,其需要实现的功能为:
实现游戏对象的爆炸特效,文字提示功能和界面背景特效,遵循游戏规则进行游戏;。
游戏中的重要角色可分为如下几个部分:
战机,敌机,战机的导弹,敌机的子弹,游戏规则为:
玩家通过键盘控制用一个战机去击毁从上下两端进入的尽可能多的敌机从而获得分数。
敌机数量随机,进入画面对战机进行攻击,两者或战机导弹与敌机相遇是发生爆炸,战机生命结束即游戏结束。
2.相关技术
2.1透明贴图函数
函数原型:
LoadImage(CImageList&imageList,UNITbmpID,COLORcrMask,intcx,intcy,intnInitial)
//此函数主要就是用于将图片放入图像链表imageList中。
(以画敌机为例)
CGameObject:
:
LoadImage(m_Images,IDB_Enemy,RGB(0,0,0),ENEMY_HEIGHT,ENEMY_HEIGHT,0);
m_Images.Draw(pDC,0,m_ptPos,ILD_TRANSPARENT);
//此函数主要就是将m_Images链表中的图像显示在pDC这个句柄中。
ILD_TRANSPARENT表示是透明贴图。
它是相同大小图像的一个集合,每个集合中均以图像的索引序号基数,图像列表通常由大图标或位图构成,其中包含透明位图模式。
可用WINDOWS32位应用程序接口函数API来绘制、建立和删除图像,并能实现增加、删除、替换和拖动图像等操作。
2.2CObList链表
函数原型:
CobListm_ObjListball;//主要就是定义一个CObList类的一个链表对象用于存储所有的与此种相关的对象,易于后续的添加删除和提取数据。
(以画敌机为例)
CObListlistEnemy;
POSITIONpos=listEnemy.GetHeadPosition();pos!
=NULL;//读取头指针
CEnemy*pEnemy=(CEnemy*)listEnemy.GetNext(pos);//GetNext获取循环遍历中的下一个元素
2.3获取矩形区域函数
CRectrect;//定义
GetClientRect(&rect);//获取其矩形区域
rect.IntersectRect(pEnemy->GetRect(),plane.GetRect());//判断两个矩形是否有交接
2.4键盘控制战机位置函数
//用于键盘控制其位置
OnKeyDown(UINTnChar,UINTnRepCnt,UINTnFlags)
if(nChar==VK_LEFT)
plane.SetHorMotion(-1);
elseif(nChar==VK_RIGHT)
plane.SetHorMotion
(1);
elseif(nChar==VK_UP)
plane.SetVerMotion(-1);
elseif(nChar==VK_DOWN)
plane.SetVerMotion
(1);
OnKeyUp(UINTnChar,UINTnRepCnt,UINTnFlags)
if(nChar==VK_LEFT)
plane.SetHorMotion(0);
elseif(nChar==VK_RIGHT)
plane.SetHorMotion(0);
elseif(nChar==VK_UP)
plane.SetVerMotion(0);
elseif(nChar==VK_DOWN)
plane.SetVerMotion(0);
2.5设置定时器
SetTimer(1,20,NULL);//设置每20毫秒刷新一次
定时器告诉WINDOWS一个时间间隔,然后WINDOWS以此时间间隔周期性出发程序。
通常由两种方法来实现:
发送WM_TIMER消息和调用应用程序定义的回调函数。
2.6双缓冲技术
双缓冲技术主要就是利用缓存的原理进行将所有的东西都先存在一个缓冲的虚拟的区域,然后再一次性的将所有的虚拟缓存中的东西都放入实在的存储器中。
CDCdc;//定义新的设置上下文对象,下一步绘图就在这里
CBitmapbitmap;//定义新的位置,实际是一块缓冲区
dc.CreateCompatibleDC(NULL);//创建新的DC
bitmap.CreateCompatibleBitmap(pDC,rect.Width(),rect.Height());//创建与当前设备匹配的位图,分配缓冲区空间
CBitmap*pOldBit=dc.SelectObject(&bitmap);
………………
pDC->BitBlt(0,0,rect.Width(),rect.Height(),&dc,0,0,SRCCOPY);//调用原系统DC的BitBlt方法,将新缓冲区的内容以SRCCOPY(原拷贝)模式复制给原系统DC,此时,图形将出现在屏幕上
bitmap.DeleteObject();//删除位图,释放空间
dc.DeleteDC();//删除dc,释放空间
ReleaseDC(pDC);
2.7内存释放技术
此项目中有太多的对象生成和运用,造成了内存的极度紧张,但游戏进行到一定的程度的时候就会出现内存溢出现象。
解决此问题的技术就是内存释放。
例:
(以敌机为例)
pDC->listEnemy.RemoveAt(lastpos);//用于删除指针
deletepDC;//删除对象
3.总体设计与详细设计
有三个主要的部分组成,分别是规则子系统、游戏对象子系统。
系统的总体结构图如下:
3.1规则子系统
该子系统主要是实现飞机大战各项游戏规则。
实现了需求中的游戏规则。
组成结构如下图所示:
这个系统包含1个重要的模块,人工智能,它实现了敌机对战机的攻击以及游戏对象碰撞监测规则,其实实现的是代表计算机方玉玩家进行对战。
✧攻击规则
⏹敌机在战机上方或下方时发射炸弹,炸弹从下至上或从上至下射向战机
⏹攻击时发出声音
✧碰撞规则
⏹导弹或炸弹本身的矩形区域和敌机或战机的矩形区域相交时,表示导弹或炸弹射中了战机或敌机
⏹战机被炸毁,游戏结束。
⏹敌机被炸毁,战机10分,出现文字提示。
⏹爆炸时产生声音
3.2游戏对象子系统
该子系统包含了各个游戏对象的实现,它实现了需求中的部分规则以及游戏特效。
本子系统的组织结构图如下:
本子系统的组织结构图如下:
应用程序对象
●游戏程序的加载
●游戏对象的绘制
●游戏规则的调用
●玩家的键盘事件获取
游戏对象
●敌机图像加载
●敌机贴图
●位置存储
3.3系统模块划分
游戏规则子系统
模块名称
功能简述
人工智能
人机对战规则的实现
游戏子系统
模块名称
功能简述
应用程序对象
游戏对象的绘制、游戏规则的调用、玩家的键盘事件获取
游戏对象
各个游戏对象的抽象父类
战机对象
战机类
敌机对象
敌机类
导弹对象
导弹类
炸弹对象
炸弹类
爆炸对象
爆炸类
文字对象
文字类
3.4主要功能模块
主要功能模块主要就是那些类的功能模块,主要有:
1.各个游戏对象的贴图模块
2.敌机数量、方向、速度、及子弹的数量、方向、和速度控制模块
3.战机的导弹数目,方向和速度控制模块
4.战机的键盘控制
5.敌机、子弹、和战机、导弹的碰撞检测及爆炸模块
6.背景添加模块
7.游戏得分和生命值及游戏结束控制
4.编码实现
4.1创建各种游戏对象类(以敌机对象为例):
文件名:
Enemy.h
#pragmaonce
#include
#include"gameobject.h"
#include"resource.h"
classCEnemy:
publicCGameObject
{public:
CEnemy(void);
~CEnemy(void);
BOOLDraw(CDC*pDC,BOOLbPause);
staticBOOLLoadImage();
CRectGetRect()
{returnCRect(m_ptPos,CPoint(m_ptPos.x+ENEMY_HEIGHT,m_ptPos.y+ENEMY_HEIGHT));}
intGetMontion()const
{returnm_nMotion;}
//是否可以开火发射子弹
BOOLFired();
private:
staticconstintENEMY_HEIGHT=35;
staticCImageListm_Images;
intm_nMotion;//方向1->向下0->停止-1->向上
//图像索引
intm_nImgIndex;
//速度
intm_V;
intm_nWait;//发射延时
};
文件名:
Enemy.cpp
#include"StdAfx.h"
#include"Enemy.h"
CImageListCEnemy:
:
m_Images;//类外声明
CEnemy:
:
CEnemy(void)
{//rand();需先产生一个随机数种子
srand(GetTickCount());
m_ptPos.x=rand()%1100;
m_nImgIndex=rand()%2;//=1向下飞,=0向上飞
if(m_nImgIndex==1)
{m_ptPos.y=-rand()%500;
m_nMotion=1;//方向向下}
if(m_nImgIndex==0)
{m_ptPos.y=rand()%900+600;
m_nMotion=-1;
}
m_V=3;
}
CEnemy:
:
~CEnemy(void)
{}
BOOLCEnemy:
:
Draw(CDC*pDC,BOOLbPause)
{m_ptPos.y+=m_V*m_nMotion;
if(m_nMotion==1)
m_Images.Draw(pDC,0,m_ptPos,ILD_TRANSPARENT);
else
m_Images.Draw(pDC,1,m_ptPos,ILD_TRANSPARENT);
returnTRUE;//m_Images.Draw(pDC,0,m_ptPos,ILD_TRANSPARENT);
}
BOOLCEnemy:
:
LoadImage()
{returnCGameObject:
:
LoadImage(m_Images,IDB_Enemy,RGB(0,0,0),ENEMY_HEIGHT,ENEMY_HEIGHT,0);}
4.2键盘控制函数
if(GetKeyState(VK_LEFT)&0x80)
{
if(plane.GetPoint().x<=0)
plane.SetHorMotion(0);
else
plane.SetHorMotion(-1);
}
if(GetKeyState(VK_RIGHT)&0x80)
{
if(plane.GetPoint().x+50>=rect.Width())
plane.SetHorMotion(0);
else
plane.SetHorMotion
(1);
}
if(GetKeyState(VK_UP)&0x80)
{
if(plane.GetPoint().y<=0)
plane.SetVerMotion(0);
else
plane.SetVerMotion(-1);
}
if(GetKeyState(VK_DOWN)&0x80)
{
if(plane.GetPoint().y+60>=rect.Height())
plane.SetVerMotion(0);
else
plane.SetVerMotion
(1);
}
if(GetKeyState(VK_SPACE)&0x80)
{
listBomb.AddTail(newCBomb(plane.GetPoint().x,plane.GetPoint().y+20));
listBomb.AddTail(newCBomb(plane.GetPoint().x+20,plane.GetPoint().y));
listBomb.AddTail(newCBomb(plane.GetPoint().x+40,plane.GetPoint().y+20));
}
4.3文字显示函数
staticintLife=25;//该变量的赋值操作只执行一次局部变量
staticintScore=0;
dc.SetBkMode(TRANSPARENT);//设置文字背景为透明
dc.SetTextColor(RGB(255,0,0));
CStringLIFE;
LIFE.Format(L"剩余生命:
%d",Life);//转化成字符串
dc.TextOut(10,10,LIFE);
dc.SetBkMode(TRANSPARENT);//设置文字背景为透明
dc.SetTextColor(RGB(0,0,255));
CStringSCORE;
SCORE.Format(L"目前得分:
%d",Score);//转化成字符串
dc.TextOut(10,30,SCORE);
dc.SetBkMode(TRANSPARENT);//设置文字背景为透明
dc.SetTextColor(RGB(255,255,255));
if(Life<=0)
{if(Score<=1000)
{SCORE.Format(L"最终得分:
%d!
!
!
继续努力哟!
!
",Score);//转化成字符串
dc.TextOut(400,300,SCORE);}
else
{SCORE.Format(L"最终得分:
%d!
!
!
你很棒哦!
!
",Score);//转化成字符串
dc.TextOut(400,300,SCORE);}
KillTimer
(1);
}
4.4相撞产生爆炸效果(以我方导弹和敌机相撞为例)
for(pos=listBall.GetHeadPosition();pos!
=NULL;)//敌机子弹
{
lastpos=pos;
CBall*pBall=(CBall*)listBall.GetNext(pos);
CRectrect2;//求矩形交集,即是否相撞
if(rect2.IntersectRect(pBall->GetRect(),plane.GetRect()))
{Life-=1;
//敌机子弹击中我机,添加爆炸效果
listExplosion.AddTail(newCExplosion(plane.GetRect().left,plane.GetRect().top));//爆炸效果
listBall.RemoveAt(lastpos);
deletepBall;
}
elseif(pBall->GetPoint().y<-9||pBall->GetPoint().y>rect.Height())
{
listBall.RemoveAt(lastpos);
deletepBall;
}
else
{
pBall->Draw(&dc,TRUE);
}
}
boolflag=false;//标记导弹是否击中敌机,true为击中
for(pos=listBomb.GetHeadPosition();pos!
=NULL;)//我方导弹
{
flag=false;
lastpos=pos;
CBomb*pBomb=(CBomb*)listBomb.GetNext(pos);
POSITIONpos1,lastpos1;
for(pos1=listEnemy.GetHeadPosition();pos1!
=NULL;)
{
lastpos1=pos1;
CEnemy*penemy=(CEnemy*)listEnemy.GetNext(pos1);
CRectrect3;//求矩形交集,即是否相撞
if(rect3.IntersectRect(pBomb->GetRect(),penemy->GetRect()))
{Score+=10;
//我方导弹与敌机相撞了,添加爆炸效果
listExplosion.AddTail(newCExplosion(pBomb->GetRect().left,pBomb->GetRect().top));//爆炸效果
listEnemy.RemoveAt(lastpos1);
deletepenemy;//删除敌机
listBomb.RemoveAt(lastpos);
deletepBomb;//删除导弹
break;
flag=true;
}
elseif(pBomb->GetPoint().y<-21||pBomb->GetPoint().y>rect.Height())
{
listBomb.RemoveAt(lastpos);
deletepBomb;
break;
}
else
{
pBomb->Draw(&dc,TRUE);
}
}
if(flag)break;
}
5.实训中遇到的主要问题及解决方法
5.1问题:
闪屏
解决方案:
双缓冲技术
CDC*pDC=GetDC();
CRectrect;
GetClientRect(&rect);
CDCdc;//定义新的设置上下文对象,下一步绘图就在这里
CBitmapbitmap;//定义新的位置,实际是一块缓冲区
dc.CreateCompatibleDC(NULL);//创建新的DC
bitmap.CreateCompatibleBitmap(pDC,rect.Width(),rect.Height());//创建与当前设备匹配的位图,分配缓冲区空间
CBitmap*pOldBit=dc.SelectObject(&bitmap);
…………….
pDC->BitBlt(0,0,rect.Width(),rect.Height(),&dc,0,0,SRCCOPY);//调用原系统DC的BitBlt方法,将新缓冲区的内容以SRCCOPY(原拷贝)模式复制给原系统DC,此时,图形将出现在屏幕上
bitmap.DeleteObject();//删除位图,释放空间
dc.DeleteDC();//删除dc,释放空间
ReleaseDC(pDC);
5.2问题:
键盘控制时出现阴影
解决方案:
键盘控制时消除虚影,及实现刷屏
GetClientRect(rect);
dc.Rectangle(rect);
5.3问题:
键盘控制时按键一下一直移动
解决方案:
使用OnKeyUp函数
voidCtext3View:
:
OnKeyUp(UINTnChar,UINTnRepCnt,UINTnFlags)
{
//TODO:
在此添加消息处理程序代码和/或调用默认值
switch(nChar)
{
caseVK_LEFT:
plane.SetHorMotion(0);
break;
caseVK_RIGHT:
plane.SetHorMotion(0);
break;
caseVK_UP:
plane.SetVerMotion(0);
break;
caseVK_DOWN:
plane.SetVerMotion(0);
break;
}
5.4问题:
按键停顿
解决方案:
将按键控制放在OnTimer函数里
voidCtext3View:
:
OnTimer(UINT_PTRnIDEvent)
{
if(GetKeyState(VK_LEFT)&0x80)
{if(plane.GetPoint().x<=0)
plane.SetHorMotion(0);
else
plane.SetHorMotion(-1);
}
if(GetKeyState(VK_RIGHT)&0x80)
{if(plane.GetPoint().x+50>=rect.Width())
plane.SetHorMotion(0);
else
plane.SetHorMotion
(1);
}
if(GetKeyState(VK_UP)&0x80)
{if(plane.GetPoint().y<=0)
plane.SetVerMotion(0);
else
plane.SetVerMotion(-1);
}
if(GetKeyState(VK_DOWN)&0x80)
{if(plane.GetPoint().y+60>=rect.Height())
plane.SetVerMotion(0);
else
plane.SetVerMotion
(1);
}
if(GetKeyState(VK_SPACE)&0x80)
{
listBomb.AddTail(newCBomb(plane.GetPoint().x,plane.GetPoint().y+20));
listBomb.AddTail(newCBomb(plane.GetPoint().x+20,plane.GetPoint().y));
listBomb.AddTail(newCBomb(plane.GetPoint().x+40,plane.GetPoint().y+20));
}
}
5.5问题:
程序中断问题
解决方案:
在我机导弹与敌机相撞代码中加入标识符,防止指针悬空。
boolflag=false;//标记导弹是否击中敌机,true为击中
for(p
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- c+ 飞机 大战 报告 word 文档 良心 出品