C++实训报告.docx
- 文档编号:29524148
- 上传时间:2023-07-24
- 格式:DOCX
- 页数:33
- 大小:47.72KB
C++实训报告.docx
《C++实训报告.docx》由会员分享,可在线阅读,更多相关《C++实训报告.docx(33页珍藏版)》请在冰豆网上搜索。
C++实训报告
实训报告
飞机大战游戏设计与开发
XXX
专业名称:
班级:
学号:
信息科学与工程学院
二零一三年十一月
目录
1.概述-------------------------------------------------------------------------------------------------------3
2.相关技术-----------------------------------------------------------------------------------------------3
2.1windows定时器---------------------------------------------------------------------------------------3
2.2双缓冲技术-------------------------------------------------------------------------------------------3
2.3CObList链表-------------------------------------------------------------------------------------------3
2.4获取矩形区域-----------------------------------------------------------------------------------------4
2.5CImageList处理爆炸效果--------------------------------------------------------------------------4
3.需求分析-------------------------------------------------------------------------------------------------4
4.总体设计与详细设计---------------------------------------------------------------------------4
4.1系统模块划分-----------------------------------------------------------------------------------------4
4.2主要功能模块-----------------------------------------------------------------------------------------4
5.编码实现----------------------------------------------------------------------------------------------5
6.测试情况说明-------------------------------------------------------------------------------------20
7.实训中遇到的主要问题及解决方法-------------------------------------------------20
8.实训体会---------------------------------------------------------------------------------------------21
1.概述
本次C++实训项目是做一个简单的飞机大战的游戏,应用MFC编程,完成一个界面简洁流畅、游戏方式简单,玩起来易于上手的桌面游戏。
该飞机大战项目运用的主要技术即是MFC编程中的一些函数、链表思想以及贴图技术。
2.相关技术
本次设计主要运用到MFC应用程序中的一些函数和技术。
2.1windows定时器
Windows定时器是一种输入设备,它周期性地在每经过一个指定的时间间隔后就通知应用程序一次。
程序将时间间隔告诉Windows,然后Windows给您的程序发送周期性发生的WM_TIMER消息以表示时间到了。
本程序中使用多个定时器,分别控制不同的功能。
在MFC的API函数中使用SetTimer()函数设置定时器,设置系统间隔时间,在OnTimer()函数中实现响应定时器的程序,用KillTimer()释放定时器
2.2双缓冲技术
双缓冲技术是在实现图片背景的插入时应用的,可以解决游戏界面上背景还有战机,敌机、子弹等图像闪动的问题。
在使用双缓冲技术时,首先创建一个矩形区域插入一张位图图像,定义一个兼容的DC并创建DC,利用双缓冲技术插入位图图像,绘图完成后要清理。
CBitmapMemBitmap;
CDCMemDC;
MemBitmap.CreateCompatibleBitmap(pDC,rect.right,rect.bottom);
pDC->BitBlt(rect.left,rect.top,rect.right,rect.bottom,&MemDC,0,0,SRCCOPY);
MemBitmap.DeleteObject();
MemDC.DeleteDC();
2.3CObList链表
MFC类库中提供了丰富的CObList类的成员函数,此程序主要用到的成员函数如下:
(1)构造函数,为CObject指针构造一个空的列表。
(2)GetHead(),访问链表首部,返回列表中的首元素(列表不能为空)。
(3)AddTail(),在列表尾增加一个元素或另一个列表的所有元素。
(4)RemoveAll(),删除列表中所有的元素。
(5)GetNext(),返回列表中尾元素的位置。
(6)GetHeadPosition(),返回列表中首元素的位置。
(7)RemoveAt(),从列表中删除指定位置的元素。
创建各游戏对象:
CEnemy*enemy1;CEnemy*enemy2;CBomb*bomb1;CBomb*bomb2;CBall*ball1;CBall*ball2;CExplosion*explosion;
创建存储游戏对象的对象链表:
CObListEnemyList1;CObListEnemyList2;CObListBombList1;CObListBombList2;CObListEnemyList1;CObListEnemyList2;CObListBallList1;CObListBallList2CObListExplosionList;
2.4获取矩形区域
首先,使用CRect定义一个对象,然后使用GetClientRect(&对象名)函数,获取界面的矩形区域rect.Width()为矩形区域的宽度,rect.Height()为矩形区域的高度。
使用IntersectRect(&,&))函数来判断两个源矩形是否有重合的部分。
如果有不为空,则返回非零值;否则,返回0。
2.5CImageList处理爆炸效果
爆炸效果是连续的显示一系列的图片。
如果把每一张图片都显示出来的话,占用的时间是非常多的,必然后导致程序的可行性下降。
CImageList是一个“图象列表”是相同大小图象的集合,每个图象都可由其基于零的索引来参考。
可以用来存放爆炸效果的一张图片,使用draw()函数来绘制在某拖拉操作中正被拖动的图象,即可连续绘制出多张图片做成的爆炸效果。
3.需求分析
在本次飞机大战游戏程序设计中,主要的功能包括战机、敌机的功能,其他功能相对的因为游戏规则而产生,具体如下:
1、战机能够通过操作鼠标或键盘上的上下左右键来移动,通过空格键来发射子弹,并且能够攻击敌机;
2、敌机不能够左右移动,但是敌机出现的位置不同,可以通过初始化敌机的位置实现敌机的向下或向上移动;
3、在战机与敌机发生碰撞,战机的子弹攻击到敌机,敌机的子弹攻击到战机,都能够在游戏界面中看到爆炸效果,并能够听到爆炸的声音;
4、游戏中分别设置了键盘“A”键和“Z”键,“A”键可以暂停游戏,“Z”键则是开始游戏;
5、在游戏规则上,战机与敌机发生碰撞或敌机的子弹攻击到战机时,战机的生命值会减1,战机的子弹攻击到敌机时,游戏的得分会加1;
6、当生命值减少到0时,会出现提示窗口,提示是否继续游戏。
4.总体设计与详细设计
4.1系统模块划分
该飞机大战游戏程序分为游戏背景位图绘制模块、各游戏对象绘制模块、游戏对象的碰撞模块、爆炸效果产生模块、游戏界面输出玩家得分生命值信息模块。
其中在游戏对象绘制模块中,战机是唯一对象,在游戏开始时产生该对象,赋予其固定的生命值,当其与敌机对象、敌机炸弹碰撞时使其生命值减一,直至生命值为零,游戏结束。
敌机对象与敌机炸弹对象的绘制中采用定时器技术,定时产生。
爆炸对象初始化为空,当游戏过程中即时发生碰撞时,在碰撞位置产生爆炸对象,添加到爆炸链表中。
4.2主要功能模块
CGameObject是各个游戏对象的抽象父类,继承自CObject类,其他的类:
战机类、敌机类、爆炸类、子弹类、炸弹类都继承了此类。
每个游戏对象类中既继承了来自父类CGameObject的属性,又有自己的特有属性和方法。
类图
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);
//战机的子弹
CBomb*bomb1;//左排战机子弹
POSITIONPos1;
for(Pos1=BombList1.GetHeadPosition();Pos1!
=NULL;)
{
bomb1=(CBomb*)BombList1.GetNext(Pos1);
bomb1->draw(&MemDC);
}
CBomb*bomb2;//右排战机子弹
POSITIONPos2;
for(Pos2=BombList2.GetHeadPosition();Pos2!
=NULL;)
{
bomb2=(CBomb*)BombList2.GetNext(Pos2);
bomb2->draw(&MemDC);
}
//敌机
//向下飞的敌机
CEnemy*enemy1;
POSITIONPosenemy1;
for(Posenemy1=EnemyList1.GetHeadPosition();Posenemy1!
=NULL;)
{
enemy1=(CEnemy*)EnemyList1.GetNext(Posenemy1);
enemy1->draw(&MemDC);
}
//向上飞的敌机
CEnemy*enemy2;
POSITIONPosenemy2;
for(Posenemy2=EnemyList2.GetHeadPosition();Posenemy2!
=NULL;)
{
enemy2=(CEnemy*)EnemyList2.GetNext(Posenemy2);
enemy2->draw(&MemDC);
}
//敌机的子弹
//向下飞的敌机的子弹
CBall*ball1;
POSITIONposball1;
for(posball1=BallList1.GetHeadPosition();posball1!
=NULL;)
{
ball1=(CBall*)BallList1.GetNext(posball1);
ball1->draw(&MemDC);
}
//向上飞的敌机的子弹
CBall*ball2;
POSITIONposball2;
for(posball2=BallList2.GetHeadPosition();posball2!
=NULL;)
{
ball2=(CBall*)BallList2.GetNext(posball2);
ball2->draw(&MemDC);
}
//爆炸
CExplosion*explosion;
POSITIONPosexplosion1,Posexplosion2;
for(Posexplosion1=ExplosionList.GetHeadPosition();Posexplosion1!
=NULL;)
{
Posexplosion2=Posexplosion1;
explosion=(CExplosion*)ExplosionList.GetNext(Posexplosion1);
if(explosion->draw(&MemDC)==0)
ExplosionList.RemoveAt(Posexplosion2);
}
//输出游戏画面上的文字
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"),score);
MemDC.TextOut(10,10,str);
str.Format(_T("剩余生命:
%d"),lifeNum);
MemDC.TextOut(10,30,str);
pDC->BitBlt(rect.left,rect.top,rect.right,rect.bottom,&MemDC,0,0,SRCCOPY);
MemBitmap.DeleteObject();
MemDC.DeleteDC();
}
voidCPlaneGameView:
:
OnInitialUpdate()
{
CView:
:
OnInitialUpdate();
//TODO:
在此添加专用代码和/或调用基类
//加载战机图片
myplane.LoadImages();
GetClientRect(&rect);
myplane.SetPoint(rect.right/2,rect.bottom/2+100);
//加载战机子弹图片
CBomb:
:
LoadImages();
//加载敌机图片
CEnemy:
:
LoadImages();
//加载敌机子弹图片
CBall:
:
LoadImages();
//加载爆炸效果图片
CExplosion:
:
LoadImages();
//设置定时器
this->SetTimer(1,100,0);
}
voidCPlaneGameView:
:
OnTimer(UINT_PTRnIDEvent)
{
//键盘“A”键暂停游戏,“Z”键开始游戏,上下左右键控制战机移动,空格键发子弹
GetClientRect(&rect);
if(GetKeyState('A')<0)
{
isPause=1;
}//if
if(GetKeyState('Z')<0)
{
isPause=0;
}//if
if(isPause==0)
{
if(GetKeyState(VK_LEFT)<0)
if(myplane.pos.x>rect.left)
myplane.move
(1);
if(GetKeyState(VK_RIGHT)<0)
if(myplane.pos.x myplane.move (2); if(GetKeyState(VK_UP)<0) if(myplane.pos.y>rect.top) myplane.move(3); if(GetKeyState(VK_DOWN)<0) if(myplane.pos.y myplane.move(4); if(GetKeyState(VK_SPACE)<0)//空格键代表战机发射子弹 { CBomb*Bomb1=newCBomb(myplane.GetPoint().x+5,myplane.GetPoint().y+20); BombList1.AddHead(Bomb1); CBomb*Bomb2=newCBomb(myplane.GetPoint().x+35,myplane.GetPoint().y+20); BombList2.AddHead(Bomb2); }//if }//if //实现战机子弹 //左排战机子弹 POSITIONPos1,Postion1; CBomb*Bomb1; for(Pos1=BombList1.GetHeadPosition();Pos1! =NULL;) { Postion1=Pos1; Bomb1=(CBomb*)BombList1.GetNext(Pos1); Bomb1->SetSpeed(30); if(Bomb1->pos.y>rect.top) Bomb1->move(); else BombList1.RemoveAt(Postion1); } //右排战机子弹 POSITIONPos2,Postion2; CBomb*Bomb2; for(Pos2=BombList2.GetHeadPosition();Pos2! =NULL;) { Postion2=Pos2; Bomb2=(CBomb*)BombList2.GetNext(Pos2); Bomb2->SetSpeed(30); if(Bomb2->pos.y>rect.top) Bomb2->move(); else BombList2.RemoveAt(Postion2); } //敌机发射子弹 if(isPause==0) { switch(nIDEvent) { case1: //向下飞的敌机 POSITIONposenemy1,PosEnemy1; CEnemy*enemy1=newCEnemy (1); if(EnemyList1.GetCount()<6) { EnemyList1.AddHead(enemy1); } CEnemy*en1; for(posenemy1=EnemyList1.GetHeadPosition();posenemy1! =NULL;) { PosEnemy1=posenemy1; en1=(CEnemy*)EnemyList1.GetNext(posenemy1); en1->SetSpeed(10); if(en1->pos.y en1->move (1); else EnemyList1.RemoveAt(PosEnemy1); //向下飞的飞机的子弹 POSITIONposball1,PosBall1; CBall*ball1=newCBall(en1->GetPoint().x+12,en1->GetPoint().y+20,1); if(BallList1.GetCount()<5) { BallList1.AddHead(ball1); } CBall*ba1; for(posball1=BallList1.GetHeadPosition();posball1! =NULL;) { PosBall1=posball1; ba1=(CBall*)BallList1.GetNext(posball1); ba1->SetSpeed(20); if(ba1->GetPoint().y ba1->move (1); else BallList1.RemoveAt(PosBall1); }//for }//for //向上飞的敌机 POSITIONposenemy2,PosEnemy2; CEnemy*enemy2=newCEnemy(-1); if(EnemyList2.GetCount()<5) { EnemyList2.AddHead(enemy2); } CEnemy*en2; for(posenemy2=EnemyList2.GetHeadPosition();posenemy2! =NULL;) {
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- C+ 报告
![提示](https://static.bdocx.com/images/bang_tan.gif)