myplane.move(4);
if(GetKeyState(VK_SPACE)<0)//空格键代表战机发射子弹
{
CBomb*Bomb1=newCBomb(myplane.getPoint().x,myplane.getPoint().y);
ListBomb1.AddHead(Bomb1);
CBomb*Bomb2=newCBomb(myplane.getPoint().x+35,myplane.getPoint().y);
ListBomb2.AddHead(Bomb2);
PlaySound((LPCTSTR)IDR_WAVE4,AfxGetInstanceHandle(),SND_RESOURCE|SND_ASYNC);
}
2.6设置定时器
定时器告诉WINDOWS一个时间间隔,然后WINDOWS以此时间间隔周期性触发程序。
通常有两种方法来实现:
发送WM_TIMER消息和调用应用程序定义的回调函数。
this->SetTimer(1,100,0);//设置每100毫秒刷新一次
2.7双缓冲技术
关于双缓冲技术主要就是利用缓存的原理进行将所有的东西都先存在一个缓冲得虚拟的区域,然后再一次性的将所有的虚拟缓存中的东西都放入实在的存储器中。
//定义一个位图对象
CBitmapMemBitmap;
CDCMemDC;
//这时还不能绘图,因为没有位图的设备描述表是不能绘图的
//只有选入了位图的设备描述表才有地方绘图,画到指定的位图上
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);
deletebomb;
//删除敌机
ListEnemy1.RemoveAt(enemyTemp);
deleteenemy;
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.编码实现
voidCPLANEGAMEView:
:
OnDraw(CDC*pDC)
{
CPLANEGAMEDoc*pDoc=GetDocument();
ASSERT_VALID(pDoc);
if(!
pDoc)
return;
//加载图片背景
this->GetClientRect(&rect);
CBitmapbitmap_BackGround;
bitmap_BackGround.LoadBitmap(IDB_BACKGROUND);
BITMAPbimap2;//位图图像
bitmap_BackGround.GetBitmap(&bimap2);
CDCcdc_BackGround;//定义一个兼容的DC
cdc_BackGround.CreateCompatibleDC(pDC);//创建DC
CBitmap*Old=cdc_BackGround.SelectObject(&bitmap_BackGround);
//定义一个位图对象
CBitmapMemBitmap;
/////////////////////双缓冲技术
CDCMemDC;
//这时还不能绘图,因为没有位图的设备描述表是不能绘图的
//只有选入了位图的设备描述表才有地方绘图,画到指定的位图上
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;
POSITIONpos1;
for(pos1=ListEnemy1.GetHeadPosition();pos1!
=NULL;)
{
enemy1=(CEnemy*)ListEnemy1.GetNext(pos1);
enemy1->draw(&MemDC);
}
//画向下飞的敌机的子弹
CBall*ball1;
POSITIONposball1;
for(posball1=ListBall1.GetHeadPosition();posball1!
=NULL;)
{
ball1=(CBall*)ListBall1.GetNext(posball1);
ball1->draw(&MemDC);
}
//画向上飞的敌机
CEnemy*enemy2;
POSITIONpos2;
for(pos2=ListEnemy2.GetHeadPosition();pos2!
=NULL;)
{
enemy2=(CEnemy*)ListEnemy2.GetNext(pos2);
enemy2->draw(&MemDC);
}
//画向上飞的敌机的子弹
CBall*ball2;
POSITIONposball2;
for(posball2=ListBall2.GetHeadPosition();posball2!
=NULL;)
{
ball2=(CBall*)ListBall2.GetNext(posball2);
ball2->draw(&MemDC);
}
//画战机的炮弹
CBomb*bomb1;//第一排战机炮弹
POSITIONPOS1;
for(POS1=ListBomb1.GetHeadPosition();POS1!
=NULL;)
{
bomb1=(CBomb*)ListBomb1.GetNext(POS1);
bomb1->draw(&MemDC);
}
CBomb*bomb2;//第二排战机炮弹
POSITIONPOS2;
for(POS2=ListBomb2.GetHeadPosition();POS2!
=NULL;)
{
bomb2=(CBomb*)ListBomb2.GetNext(POS2);
bomb2->draw(&MemDC);
}
//画爆炸
CExplosion*explosion;
POSITIONexplosionPos1,explosionPos2;
for(explosionPos1=ListExplosion.GetHeadPosition();explosionPos1!
=NULL;)
{
explosionPos2=explosionPos1;
explosion=(CExplosion*)ListExplosion.GetNext(explosionPos1);
if(explosion->draw(&MemDC)==0)
ListExplosion.RemoveAt(explosionPos2);
}
//////////////输出当前信息
HFONTfont;
font=CreateFont(20,10,0,0,0,0,0,0,0,0,0,100,10,0);
MemDC.SelectObject(font);
CStringstr;
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:
在此处为本机数据添加绘制代码
}
voidCPLANEGAMEView:
:
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:
在此添加专用代码和/或调用基类
}
voidCPLANEGAMEView:
:
OnTimer(UINT_PTRnIDEvent)
{
//TODO:
在此添加消息处理程序代码和/或调用默认值
/