飞机大战实训报告.docx
《飞机大战实训报告.docx》由会员分享,可在线阅读,更多相关《飞机大战实训报告.docx(33页珍藏版)》请在冰豆网上搜索。
飞机大战实训报告
1.概述
这次实训,目的以VS为环境,利用MFC,使用C++语言编写一个简单的飞机大战游戏。
实现的主要功能:
1.有开始游戏界面,上下左右键控制飞机自由移动,空格键发射炮弹。
2.设有关卡,每打完一个boss就会过关,每过一关战机炮弹会升级,敌机随机发射子弹数量增加。
3.战机起始十条命,可以通过过关和吃到道具增加血量。
4.战机子弹打中敌机,敌机就会爆炸,boss血量随关卡升高而增多,打败敌机或者boss会有分数加成。
5.设有无敌模式和普通模式,无敌模式大招无限,生命无限,战机导弹直接升至最高等级。
2.相关技术
2.1碰撞检测
用CRect类的GetRect()函数可以获得当前对象的矩形区域,IntersectRect()并用此函数判断二者是否碰撞。
2.2CObList链表
这个程序使用CObList链表来存储各效果。
CobList类似于一个双向链表,POSITION类型的变量为链表的键。
使用POSITION变量,既可以作为链表循环中的循环变量,也可以作为标记某个位置的标签。
我们可以通过获得某元素的POSITION来访问它。
本程序中主要用到的函数有:
GetHeadPosition():
获取链表首元素的POSITION;
AddTail():
将新的元素添加到链表最后;
GetNext(POSITION&rPosition):
使rPosition指向下一个元素。
2.3设置定时器
SetTimer()函数来设置定时器。
2.4背景滚动
为了让游戏场景更加逼真,游戏节奏更加合理,可以通过让背景滚动来提高游戏的场景效应,实现这一技术时,可以将一张背景图片复制为2张,从上到下连续的拼接在一起,使其不会出现图片的卡顿和瞬移现象。
2.5内存释放技术
这个程序中有大量的地方需要使用内存,如果不及时删除会出现闪图等情况,容易导致程序崩溃,要及时释放内存资源。
3.总体设计与详细设计
3.1系统模块划分
3.2主要功能模块
类关系图:
4.编码实现
//PlaneGameView.cpp:
CPlaneGameView类的实现
voidCPlaneGameView:
:
UpdateFrame(CDC*pMemDC)
{
//绘制天空
if(level==0)
{
CPaintDCdc(this);
CBitmapbmpBackground;//位图对象
bmpBackground.LoadBitmap(IDB_BITMAP1);
CDCdcMem;//定义一个工具箱(设备上下文)
dcMem.CreateCompatibleDC(&dc);
BITMAPbitmap;
bmpBackground.GetBitmap(&bitmap);//建立绑定关系
CBitmap*back=dcMem.SelectObject(&bmpBackground);//保存原有CDC对象,并选入新CDC对象入DC
staticintcurr=1;
if(curr<=1)
curr=GAME_HEIGHT-1;
curr-=1;
pMemDC->BitBlt(0,0,GAME_WIDTH,GAME_HEIGHT-curr,&dcMem,0,curr,SRCCOPY);
pMemDC->BitBlt(0,GAME_HEIGHT-curr,GAME_WIDTH,curr,&dcMem,0,0,SRCCOPY);
}
if(level>=1&&l==0&&boss==0)
{
pMemDC->FillSolidRect(0,0,GAME_WIDTH,GAME_HEIGHT,RGB(0,0,0));
l++;z=1;
}
if(level==1&&l!
=0&&boss!
=0)
{
CPaintDCdc(this);
CBitmapbmpBackground;//位图对象
bmpBackground.LoadBitmap(IDB_BITMAP1);
CDCdcMem;//定义一个工具箱(设备上下文)
dcMem.CreateCompatibleDC(&dc);
BITMAPbitmap;
bmpBackground.GetBitmap(&bitmap);//建立绑定关系
CBitmap*back=dcMem.SelectObject(&bmpBackground);//保存原有CDC对象,并选入新CDC对象入DC
staticintcurr=1;
if(curr<=1)
curr=GAME_HEIGHT-1;
curr-=1;
pMemDC->BitBlt(0,0,GAME_WIDTH,GAME_HEIGHT-curr,&dcMem,0,curr,SRCCOPY);
pMemDC->BitBlt(0,GAME_HEIGHT-curr,GAME_WIDTH,curr,&dcMem,0,0,SRCCOPY);
}
if(level==2&&l!
=0&&boss!
=0)
{
CPaintDCdc(this);
CBitmapbmpBackground;//位图对象
bmpBackground.LoadBitmap(IDB_MAP2);
CDCdcMem;//定义一个工具箱(设备上下文)
dcMem.CreateCompatibleDC(&dc);
BITMAPbitmap;
bmpBackground.GetBitmap(&bitmap);//建立绑定关系
CBitmap*back=dcMem.SelectObject(&bmpBackground);//保存原有CDC对象,并选入新CDC对象入DC
staticintcurr=1;
if(curr<=1)
curr=GAME_HEIGHT-1;
curr-=1;
pMemDC->BitBlt(0,0,GAME_WIDTH,GAME_HEIGHT-curr,&dcMem,0,curr,SRCCOPY);
pMemDC->BitBlt(0,GAME_HEIGHT-curr,GAME_WIDTH,curr,&dcMem,0,0,SRCCOPY);
}
if(level==3&&l!
=0&&boss!
=0)
{
CPaintDCdc(this);
CBitmapbmpBackground;//位图对象
bmpBackground.LoadBitmap(IDB_MAP3);
CDCdcMem;//定义一个工具箱(设备上下文)
dcMem.CreateCompatibleDC(&dc);
BITMAPbitmap;
bmpBackground.GetBitmap(&bitmap);//建立绑定关系
CBitmap*back=dcMem.SelectObject(&bmpBackground);//保存原有CDC对象,并选入新CDC对象入DC
staticintcurr=1;
if(curr<=1)
curr=GAME_HEIGHT-1;
curr-=1;
pMemDC->BitBlt(0,0,GAME_WIDTH,GAME_HEIGHT-curr,&dcMem,0,curr,SRCCOPY);
pMemDC->BitBlt(0,GAME_HEIGHT-curr,GAME_WIDTH,curr,&dcMem,0,0,SRCCOPY);
}
if(level==4&&l!
=0&&boss!
=0)
{
CPaintDCdc(this);
CBitmapbmpBackground;//位图对象
bmpBackground.LoadBitmap(IDB_MAP4);
CDCdcMem;//定义一个工具箱(设备上下文)
dcMem.CreateCompatibleDC(&dc);//兼容
BITMAPbitmap;
bmpBackground.GetBitmap(&bitmap);//建立绑定关系
CBitmap*back=dcMem.SelectObject(&bmpBackground);//保存原有CDC对象,并选入新CDC对象入DC
staticintcurr=1;
if(curr<=1)
curr=GAME_HEIGHT-1;
curr-=1;
pMemDC->BitBlt(0,0,GAME_WIDTH,GAME_HEIGHT-curr,&dcMem,0,curr,SRCCOPY);
pMemDC->BitBlt(0,GAME_HEIGHT-curr,GAME_WIDTH,curr,&dcMem,0,0,SRCCOPY);
}
if(level==5&&l!
=0&&boss!
=0)
{
CPaintDCdc(this);
CBitmapbmpBackground;//位图对象
bmpBackground.LoadBitmap(IDB_MAP5);
CDCdcMem;//定义一个工具箱(设备上下文)
dcMem.CreateCompatibleDC(&dc);
BITMAPbitmap;
bmpBackground.GetBitmap(&bitmap);//建立绑定关系
CBitmap*back=dcMem.SelectObject(&bmpBackground);//保存原有CDC对象,并选入新CDC对象入DC
staticintcurr=1;
if(curr<=1)
curr=GAME_HEIGHT-1;
curr-=1;
pMemDC->BitBlt(0,0,GAME_WIDTH,GAME_HEIGHT-curr,&dcMem,0,curr,SRCCOPY);
pMemDC->BitBlt(0,GAME_HEIGHT-curr,GAME_WIDTH,curr,&dcMem,0,0,SRCCOPY);
}
if(level>5&&l!
=0&&boss!
=0)
{
CPaintDCdc(this);
CBitmapbmpBackground;//位图对象
bmpBackground.LoadBitmap(IDB_MAP6);
CDCdcMem;//定义一个工具箱(设备上下文)
dcMem.CreateCompatibleDC(&dc);
BITMAPbitmap;
bmpBackground.GetBitmap(&bitmap);//建立绑定关系
CBitmap*back=dcMem.SelectObject(&bmpBackground);//保存原有CDC对象,并选入新CDC对象入DC
staticintcurr=1;
if(curr<=1)
curr=GAME_HEIGHT-1;
curr-=1;
pMemDC->BitBlt(0,0,GAME_WIDTH,GAME_HEIGHT-curr,&dcMem,0,curr,SRCCOPY);
pMemDC->BitBlt(0,GAME_HEIGHT-curr,GAME_WIDTH,curr,&dcMem,0,0,SRCCOPY);
}
pMemDC->SetBkMode(TRANSPARENT);
pMemDC->SetTextAlign(TA_CENTER);
pMemDC->SetTextColor(RGB(255,255,255));
if(level==0)
{
wchar_tS8[1000];
wsprintf(S8,L"单击鼠标进入游戏");
pMemDC->TextOutW(GAME_WIDTH/2,GAME_HEIGHT/2,CString(S8));
}
if(level>=1&&z!
=0)
{
wchar_tS9[1000];
wsprintf(S9,L"点击进入下一关");
pMemDC->TextOutW(GAME_WIDTH/2,GAME_HEIGHT/2,CString(S9));
}
if(level>=1&&z==0)
{wchar_tS1[1000];
wchar_tS2[1000];
wsprintf(S1,L"得分:
%d",number);
wsprintf(S2,L"关卡:
%d",level);
pMemDC->TextOutW(35,0,CString(S1));
pMemDC->TextOutW(200,0,CString(S2));
wchar_tS3[1000];
wsprintf(S3,L"按下“F1”开启无敌模式");
pMemDC->TextOutW(390,0,CString(S3));
wchar_tS4[1000];
wsprintf(S4,L"按下“F2”关闭无敌模式");
pMemDC->TextOutW(390,20,CString(S4));
wchar_tS5[1000];
if(wu==0)
{wsprintf(S5,L"大招数量:
%d",dazhao);
pMemDC->TextOutW(430,40,CString(S5));}
if(wu==1)
{
wsprintf(S5,L"大招数量:
无限");
pMemDC->TextOutW(430,40,CString(S5));
}
wchar_tS6[1000];
wsprintf(S6,L"按下空格发射子弹");
pMemDC->TextOutW(60,50,CString(S6));
wchar_tS7[1000];
wsprintf(S7,L"按下“Z”大招");
pMemDC->TextOutW(56,70,CString(S7));
//绘制我方战机
if(m_pMe!
=NULL)
{
m_pMe->Draw(m_pMemDC,FALSE);
}
else
{//GameOver
CStringstr=_T("GameOver!
");
pMemDC->TextOut(GAME_WIDTH/2,GAME_HEIGHT/2,str);
}
//绘制血条
if(m_pMe!
=NULL)
{
CStringz1;
z1.Format(L"战机HP(%d)",shengming);
pMemDC->TextOut(47,30,z1);
pMemDC->FillSolidRect(90,33,shengming*10,10,RGB(255,0,0));
if(bxt==1)
{
CStringz2;
z2.Format(L"BossHP(%d)",boss);
pMemDC->TextOut(35,100,z2);
pMemDC->FillSolidRect(80,108,boss*2,10,RGB(0,255,0));
}
}
//绘制导弹、爆炸、敌机、子弹、boss、boss子弹
for(inti=0;i<=8;i++)
{
POSITIONpos1,pos2;
for(pos1=m_ObjList[i].GetHeadPosition();(pos2=pos1)!
=NULL;)
{
CGameObject*pObj=(CGameObject*)m_ObjList[i].GetNext(pos1);
if(pObj&&!
pObj->Draw(pMemDC,FALSE))
{
m_ObjList[i].RemoveAt(pos2);
deletepObj;
}
}
}}
//复制内存DC到设备DC
m_pDC->BitBlt(0,0,GAME_WIDTH,GAME_HEIGHT,m_pMemDC,0,0,SRCCOPY);
}
voidCPlaneGameView:
:
AI()
{
staticintnCreator=rand()%5+20;
//随机产生敌机
if(nCreator<=0)
{
nCreator=rand()%5+20;
m_ObjList[enEnemy].AddTail(newCEnemy);
}
nCreator--;
//随机产生大招
if(count%30==0)
{
m_ObjList[endazhao].AddTail(newCda);
count++;
}
//随机产生生命
if(count%40==0)
{
m_ObjList[enming].AddTail(newCshengming);
count++;
}
//产生boss
if(level==1&&bn==0&&count>=25&&count<=27)
{
m_ObjList[enboss].AddTail(newCboss);
bxt=1;bn++;
}
if(level==2&&bn==0&&count>=50&&count<=52)
{
m_ObjList[enboss].AddTail(newCboss);
bxt=1;bn++;
}
if(level==3&&bn==0&&count>=75&&count<=77)
{
m_ObjList[enboss].AddTail(newCboss);
bxt=1;bn++;
}
if(level==4&&bn==0&&count>=100&&count<=102)
{
m_ObjList[enboss].AddTail(newCboss);
bxt=1;bn++;
}
if(level==5&&bn==0&&count>=150&&count<=152)
{
m_ObjList[enboss].AddTail(newCboss);
bxt=1;
bn++;
}
if(level>5&&count%200==0&&bn==0)
{
m_ObjList[enboss].AddTail(newCboss);
bxt=1;bn++;
}
if(m_pMe==NULL)
return;
//检测四个方向键,移动战机
for(inti=0;i<4;i++)
{
intnMeMotion=0;
m_pMe->SetVerMotion(0);
m_pMe->SetHorMotion(0);
nMeMotion=GetKey(VK_UP);
if(nMeMotion==1)
m_pMe->SetVerMotion
(1);
nMeMotion=GetKey(VK_DOWN);
if(nMeMotion==1)
m_pMe->SetVerMotion(-1);
nMeMotion=GetKey(VK_RIGHT);
if(nMeMotion==1)
m_pMe->SetHorMotion
(1);
nMeMotion=GetKey(VK_LEFT);
if(nMeMotion==1)
m_pMe->SetHorMotion(-1);
}
//产生战机导弹
if(GetKey(VK_SPACE)==1)//按下了空格键
{
if(m_pMe!
=NULL&&m_pMe->Fired())
{
CPointpt=m_pMe->GetPoint();
if(level==1&&wu==0)
{
m_ObjList[enBomb].AddTail(newCBomb(pt.x+20,pt.y+10));
}
if(level==2&&wu==0)
{
m_ObjList[enBomb].AddTail(newCBomb(pt.x+10,pt.y+30));
m_ObjList[enBomb].AddTail(newCBomb(pt.x+30,pt.y+30));
}
if(level==3&&wu==0)
{
m_ObjList[enBomb].AddTail(newCBomb(pt.x+10,pt.y+30));
m_ObjList[enBomb].AddTail(newCBomb(pt.x+30,pt.y+30));
m_ObjList[enBomb].AddTail(newCBomb(pt.x+20,pt.y+30));
}
if(level>=4&&wu==0)
{
m_ObjList[enBomb].AddTail(newCBomb(pt.x+10,pt.y+30));
m_ObjList[enBomb].AddTail(newCBomb(pt.x+30,pt.y+30));
m_ObjList[enBomb].AddTail(newCBomb(pt.x+20,pt.y+30));
m_ObjList[e