




已阅读5页,还剩50页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
。目 录1. 概述32. 相关技术32.1碰撞检测32.2 CObList链表32.3 设置定时器32.4 背景滚动技术32.5 内存释放技术33. 总体设计与详细设计43.1 系统模块划分43.2 主要功能模块44. 编码实现65. 实训中遇到的主要问题及解决方法496. 实训体会501. 概述这次实训,目的以VS 为环境,利用MFC,使用C+语言编写一个简单的飞机大战游戏 。实现的主要功能:1. 有开始游戏界面,上下左右键控制飞机自由移动,空格键发射炮弹。2. 设有关卡,每打完一个boss就会过关,每过一关战机炮弹会升级,敌机随机发射子弹数量增加。3. 战机起始十条命,可以通过过关和吃到道具增加血量。4. 战机子弹打中敌机,敌机就会爆炸,boss血量随关卡升高而增多,打败敌机或者boss会有分数加成。5. 设有无敌模式和普通模式,无敌模式大招无限,生命无限,战机导弹直接升至最高等级。2. 相关技术2.1碰撞检测用CRect类的GetRect()函数可以获得当前对象的矩形区域, IntersectRect()并用此函数判断二者是否碰撞。2.2 CObList链表这个程序使用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 主要功能模块玩家控制模块方向键控制飞机空格键发射导弹F1键开启无敌模式F2关闭无敌模式鼠标单机进入游戏敌机生成模块随机位置生成速度随机每过一关发射子弹增加关卡控制模块敌机过关升级战机过关升级Boss死亡进入下一关游戏逻辑模块战机碰到导弹或者敌机会减一滴血敌机或者战机血量为0时死亡每关只有一个boss如果boss死亡则过关类关系图:4. 编码实现/ PlaneGameView.cpp : CPlaneGameView 类的实现void CPlaneGameView:UpdateFrame(CDC* pMemDC)/绘制天空if(level=0)CPaintDC dc(this);CBitmap bmpBackground; /位图对象bmpBackground.LoadBitmap(IDB_BITMAP1);CDC dcMem; /定义一个工具箱(设备上下文) dcMem.CreateCompatibleDC(&dc);BITMAP bitmap;bmpBackground.GetBitmap(&bitmap); /建立绑定关系 CBitmap *back = dcMem.SelectObject(&bmpBackground); /保存原有CDC对象,并选入新CDC对象入DC static int curr = 1;if (curr 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)CPaintDC dc(this);CBitmap bmpBackground; /位图对象bmpBackground.LoadBitmap(IDB_BITMAP1);CDC dcMem; /定义一个工具箱(设备上下文) dcMem.CreateCompatibleDC(&dc);BITMAP bitmap;bmpBackground.GetBitmap(&bitmap); /建立绑定关系 CBitmap *back = dcMem.SelectObject(&bmpBackground); /保存原有CDC对象,并选入新CDC对象入DC static int curr = 1;if (curr 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)CPaintDC dc(this);CBitmap bmpBackground; /位图对象bmpBackground.LoadBitmap(IDB_MAP2);CDC dcMem; /定义一个工具箱(设备上下文) dcMem.CreateCompatibleDC(&dc);BITMAP bitmap;bmpBackground.GetBitmap(&bitmap); /建立绑定关系 CBitmap *back = dcMem.SelectObject(&bmpBackground); /保存原有CDC对象,并选入新CDC对象入DC static int curr = 1;if (curr 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)CPaintDC dc(this);CBitmap bmpBackground; /位图对象bmpBackground.LoadBitmap(IDB_MAP3);CDC dcMem; /定义一个工具箱(设备上下文) dcMem.CreateCompatibleDC(&dc);BITMAP bitmap;bmpBackground.GetBitmap(&bitmap); /建立绑定关系 CBitmap *back = dcMem.SelectObject(&bmpBackground); /保存原有CDC对象,并选入新CDC对象入DC static int curr = 1;if (curr 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)CPaintDC dc(this);CBitmap bmpBackground; /位图对象bmpBackground.LoadBitmap(IDB_MAP4);CDC dcMem; /定义一个工具箱(设备上下文) dcMem.CreateCompatibleDC(&dc);/兼容BITMAP bitmap;bmpBackground.GetBitmap(&bitmap); /建立绑定关系 CBitmap *back = dcMem.SelectObject(&bmpBackground); /保存原有CDC对象,并选入新CDC对象入DC static int curr = 1;if (curr 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)CPaintDC dc(this);CBitmap bmpBackground; /位图对象bmpBackground.LoadBitmap(IDB_MAP5);CDC dcMem; /定义一个工具箱(设备上下文) dcMem.CreateCompatibleDC(&dc);BITMAP bitmap;bmpBackground.GetBitmap(&bitmap); /建立绑定关系 CBitmap *back = dcMem.SelectObject(&bmpBackground); /保存原有CDC对象,并选入新CDC对象入DC static int curr = 1;if (curr 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(level5 & l != 0 & boss != 0)CPaintDC dc(this);CBitmap bmpBackground; /位图对象bmpBackground.LoadBitmap(IDB_MAP6);CDC dcMem; /定义一个工具箱(设备上下文) dcMem.CreateCompatibleDC(&dc);BITMAP bitmap;bmpBackground.GetBitmap(&bitmap); /建立绑定关系 CBitmap *back = dcMem.SelectObject(&bmpBackground); /保存原有CDC对象,并选入新CDC对象入DC static int curr = 1;if (curr 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_t S81000;wsprintf(S8, L单击鼠标进入游戏);pMemDC-TextOutW(GAME_WIDTH / 2, GAME_HEIGHT / 2, CString(S8);if(level=1&z!=0)wchar_t S91000;wsprintf(S9, L点击进入下一关);pMemDC-TextOutW(GAME_WIDTH / 2, GAME_HEIGHT / 2, CString(S9);if(level=1&z=0)wchar_t S11000;wchar_t S21000;wsprintf(S1, L得分:%d, number);wsprintf(S2, L关卡:%d, level);pMemDC-TextOutW(35, 0, CString(S1); pMemDC-TextOutW(200, 0, CString(S2);wchar_t S31000;wsprintf(S3 , L按下“F1”开启无敌模式);pMemDC-TextOutW(390, 0, CString(S3);wchar_t S41000;wsprintf(S4, L按下“F2”关闭无敌模式);pMemDC-TextOutW(390, 20, CString(S4);wchar_t S51000;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_t S61000;wsprintf(S6, L按下空格发射子弹);pMemDC-TextOutW(60, 50, CString(S6);wchar_t S71000;wsprintf(S7, L按下“Z”大招);pMemDC-TextOutW(56, 70, CString(S7); /绘制我方战机if (m_pMe != NULL)m_pMe-Draw(m_pMemDC, FALSE);else /Game OverCString str = _T(Game Over!);pMemDC-TextOut(GAME_WIDTH / 2, GAME_HEIGHT / 2, str);/绘制血条if (m_pMe != NULL)CString z1;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)CString z2;z2.Format(LBoss HP (%d),boss);pMemDC-TextOut(35, 100, z2);pMemDC-FillSolidRect(80, 108, boss * 2, 10, RGB(0, 255, 0);/绘制 导弹、爆炸、敌机、子弹、boss、boss子弹for (int i = 0;i Draw(pMemDC, FALSE)m_ObjListi.RemoveAt(pos2);delete pObj;/复制内存DC到设备DCm_pDC-BitBlt(0, 0, GAME_WIDTH, GAME_HEIGHT, m_pMemDC, 0, 0, SRCCOPY);void CPlaneGameView:AI()static int nCreator = rand() % 5+20 ;/随机产生敌机if (nCreator =25&count=50&count=75&count=100&count=150&count5&count%200=0&bn=0)m_ObjListenboss.AddTail(new Cboss); bxt = 1;bn+;if (m_pMe = NULL)return;/检测四个方向键,移动战机for (int i = 0;iSetVerMotion(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()CPoint pt = m_pMe-GetPoint();if (level = 1 & wu = 0)m_ObjListenBomb.AddTail(new CBomb(pt.x + 20, pt.y + 10);if (level = 2 & wu = 0)m_ObjListenBomb.AddTail(new CBomb(pt.x + 10, pt.y + 30);m_ObjListenBomb.AddTail(new CBomb(pt.x + 30, pt.y + 30);if (level = 3 & wu = 0) m_ObjListenBomb.AddTail(new CBomb(pt.x + 10, pt.y + 30);m_ObjListenBomb.AddTail(new CBomb(pt.x + 30, pt.y + 30);m_ObjListenBomb.AddTail(new CBomb(pt.x + 20, pt.y + 30);if (level = 4 & wu = 0)m_ObjListenBomb.AddTail(new CBomb(pt.x + 10, pt.y + 30);m_ObjListenBomb.AddTail(new CBomb(pt.x + 30, pt.y + 30);m_ObjListenBomb.AddTail(new CBomb(pt.x + 20, pt.y + 30);m_ObjListenBomb.AddTail(new CBomb(pt.x , pt.y + 30);m_ObjListenBomb.AddTail(new CBomb(pt.x + 40, pt.y + 30);if (wu = 1)m_ObjListenBomb.AddTail(new CBomb(pt.x + 10, pt.y + 30);m_ObjListenBomb.AddTail(new CBomb(pt.x + 30, pt.y + 30);m_ObjListenBomb.AddTail(new CBomb(pt.x + 20, pt.y + 30);m_ObjListenBomb.AddTail(new CBomb(pt.x, pt.y + 30);m_ObjListenBomb.AddTail(new CBomb(pt.x + 40, pt.y + 30);if (GetKey(VK_F1) = 1)/按下了F1if (m_pMe != NULL & m_pMe-Fired()wu = 1;if (GetKey(VK_F2) = 1 & wu = 1)/按下了F2if (m_pMe != NULL & m_pMe-Fired()wu = 0;/boss发射子弹static int num = 100;if (m_pMe != NULL & num GetPoint();CBossball * t;for (int i = -level + 1; i zx = int(4.0*sin(3.14* double(i) / 9);t-zy = int(8.0*cos(3.14* double(i) / 9);m_ObjListenBossball.AddTail(t);num = 100;num-;/敌机发射子弹if (m_pMe)CPoint PlanePt = m_pMe-GetPoint();for (POSITION ePos = m_ObjListenEnemy.GetHeadPosition(); ePos != NULL;)CEnemy* pEnemy = (CEnemy*)m_ObjListenEnemy.GetNext(ePos);if (!pEnemy-Fired()continue;CPoint ePt = pEnemy-GetPoint();BOOL by = FALSE;/敌机在战机前面if (pEnemy-GetMontion() = 1 & ePt.yGetMontion() = -1 & ePt.yPlanePt.y)by = TRUE;if (by & ePt.x = PlanePt.x & ePt.x PlanePt.x + CMyPlane:PLANE_WIDTH)CBall * t;for (int i = -level + 1; i GetMontion();t-xx = int(8.0*sin(3.14* double(i) / 9);t-xy = int(8.0*cos(3.14* double(i) / 9);m_ObjListenBall.AddTail(t);/boss子弹打到战机if (m_pMe != NULL)POSITION nPos3 = NULL, nPos4 = NULL;CRect mRect = m_pMe-GetRect();for (nPos3 = m_ObjListenBossball.GetHeadPosition(); (nPos4 = nPos3) != NULL;)CBall* pBall = (CBall*)m_ObjListenBossball.GetNext(nPos3);CRect bRect = pBall-GetRect();CRect tmpRect;if (tmpRect.IntersectRect(&bRect, mRect)/添加爆炸效果if (wu = 0 )shengming-;/生命减少m_ObjListenExplosion.AddTail(new CExplosion(mRect.left, mRect.top);/删除子弹m_ObjListenBossball.RemoveAt(nPos4);delete pBall;if (shengming GetRect();for (nPos1 = m_ObjListenEnemy.GetHeadPosition(); (nPos2 = nPos1) != NULL;)CBall* pBall = (CBall*)m_ObjListenEnemy.GetNext(nPos1);CRect bRect = pBall-GetRect();CRect tmpRect;if (tmpRect.IntersectRect(&bRect, mnRect)/添加爆炸效果if (wu = 0 )shengming-;/生命减少m_ObjListenExplosion.AddTail(new CExplosion(mnRect.left, mnRect.top);/删除子弹m_ObjListenEnemy.RemoveAt(nPos2);delete pBall;if (shengming GetRect();for (bPos1 = m_ObjListenBall.GetHeadPosition(); (bPos2 = bPos1) != NULL;)CBall* pBall = (CBall*)m_ObjListenBall.GetNext(bPos1);CRect bRect = pBall-GetRect();CRect tmpRect;if (tmpRect.IntersectRect(&bRect, mRect)/添加爆炸效果if (wu = 0 )shengming-;/生命减少m_ObjListenExplosion.AddTail(new CExplosion(mRect.left, mRect.top);/删除子弹m_ObjListenBall.RemoveAt(bPos2);delete pBall;if (shengming GetRect();for (bPos1 = m_ObjListendazhao.GetHeadPosition(); (bPos2 = bPos1) != NULL;)CBall* pBall = (CBall*)m_ObjListendazhao.GetNext(bPos1);CRect mRect = pBall-GetRect();CRect tmpRect;if (tmpRect.IntersectRect(&mRect, bRect)dazhao+;/删除子弹m_ObjListendazhao.RemoveAt(bPos2);delete pBall;/吃生命if (NULL != m_pMe) POSITION bPos1 = NULL, bPos2 = NULL;CRect mRect = m_pMe-GetRect();for (bPos1 = m_ObjListenming.GetHeadPosition(); (bPos2 = bPos1) != NULL;)CBall* pBall = (CBall*)m_ObjListenming.GetNext(bPos1);CRect bRect = pBall-GetRect();CRect tmpRect;if (tmpRect.IntersectRect(&bRect, mRect)shengming+;/删除子弹m_ObjListenming.RemoveAt(bPos2);delete pBall;/战机导弹炸掉敌机POSITION mPos1 = NULL, mPos2 = NULL;for (mPos1 = m_ObjListenBomb.GetHeadPosition();(mPos2 = mPos1) != NULL;)CBomb* pBomb = (CBomb*)m_ObjListenBomb.GetNext(mPos1);CRect bRect = pBomb-GetRect();POSITION ePos1 = NULL, ePos2 = NULL;for (ePos1 = m_ObjListenEnemy.GetHeadPosition();(ePos2 = ePos1) != NULL;)CEnemy* pEnemy = (CEnemy*)m_ObjListenEnemy.GetNext(ePos1);CRect mRect = pEnemy-GetRect();CRect tmpRect;if (tmpRect.IntersectRect(&bRect, mRect)count+;number += 5;/添加爆炸效果m_ObjListenExplosion.AddTail(new CExplosion(mRect.left, mRect.top);/删除导弹if (da = 1)m_ObjListenBomb.RemoveAt(mPos2);delete pBomb;/删除敌机m_ObjListenEnemy.RemoveAt(ePos2);delete pEnemy;break;/战机导弹炸掉子弹POSITION mPos3 = NULL, mPos4 = NULL;for (mPos3 = m_ObjListenBomb.GetHeadPosition(); (mPos4 = mPos3) != NULL;)CBomb* pBomb = (CBomb*)m_ObjListenBomb.GetNext(mPos3);CRect bRect = pBomb-GetRect();POSITION ePos3 = NULL, ePos4 = NULL;for (ePos3 = m_ObjListenBall.GetHeadPosition(); (ePos4 = ePos3) != NULL;)CBall* pBall = (CBall*)m_ObjListenBall.GetNext(ePos3);CRect mRect = pBall-GetRect();CRect tmpRect;if (tmpRect.IntersectRect(&bRect, mRect)/添加爆炸效果/删除导弹m_ObjListenBomb.RemoveAt(mPos4);delete pBomb;/删除敌机m_ObjListenBall.RemoveAt(ePos4);delete pBall;break;/导弹炸掉bossPOSITION mPos5 = NULL, mPos6 =
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
评论
0/150
提交评论