mfc贪吃蛇.doc
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- mfc 贪吃
- 资源描述:
-
宿 迁 学 院 Windows程序设计 课程考核报告 班 级: 11计本2班 学 号: 姓 名: 得 分: 2013年12月 20 日 目 录 1. 设计目的及要求 - 3 - 1.1设计目的及问题描述 - 3 - 1.2设计要求 - 3 - 1.3软件、硬件环境 - 3 - 2. 课程设计步骤 - 4 - 3. 课程设计内容 - 4 - 3.1 概要设计 - 4 - 3.1.1 程序总体框架描述 - 4 - 3.1.2程序常用类声明和变量的声明 - 5 - 3.2主要技术 - 5 - 3.3系统设计结果 (界面截图、操作流程) - 5 - 4.设计总结 - 26 - 4.1遇到的问题及如何解决 - 26 - 4.2体会 - 27 - 贪吃蛇 1. 设计目的及要求 1.1设计目的及问题描述 贪吃蛇游戏经典,版本多样,娱乐性高,适合在闲暇时放松心神。并且可在多个平台上实现,程序简单易懂,非常适合MFC初学者学习制作。玩家通过按键上的上下左右四个键来控制蛇的方向移动,蛇头碰撞到食物则表示食物被蛇吃掉,这时蛇的身长长一节,接着出现食物,等待被蛇吃掉。在吃食物的过程中,蛇的运行速度会越来越快,从而增加了游戏难度,具有挑战性。如果蛇在移动过程中,撞到墙壁或者身体交叉蛇头撞到自己的身体游戏结束。 在贪吃蛇这款游戏设置和开发中,一方面考察了我们大一时候所学的C语言编程的算法运用,另一方面更是考察了我们大三这学期所学的在windows应用程序中编程的基础知识和MFC应用程序的基本知识,同时考察了我们面向对象程序设计的基本思路和方法的掌握情况。 1.2设计要求 设计要求使用MFC基础类库,完成题目任选可以是小游戏、管理系统、通信软件等。(题目需有一定规模) 1、必须用到所学的控件、对话框、菜单、消息处理、视图框架、图形等大部分知识 2、创建的项目名“姓名(拼音的首字母)”,需严格遵守,否则一定不及格。 3、若该程序涉及多个窗口则每个窗口对应的类名必须“姓名(拼音的首字母)”,需严格遵守,否则一定不及格。 1.3软件、硬件环境 软件环境:Visual C++ 6.0、Microsoft Windows 7; 硬件环境:笔记本电脑。 2. 课程设计步骤 1、 系统用户需求 贪吃蛇游戏以深入人心,版本多样,娱乐性高,适合大部分人在闲暇时放松心神。 2、 需求分析 我设计的贪吃蛇游戏是基于单文档设置的,所以在我创立ZYT这个工程之后会由软件自动生产五个大类(CAboutDlg、CMainFrame、CZYTApp、CZYTDoc、CZYTView). 另外我在这款游戏设置中,我自己添加了如下几个十分重要的类: CBeanzyt:这个类是用来对贪吃蛇游戏中食物的出现和消失以及再出现进行设置; CGezyt:这个类是用来对贪吃蛇这款游戏中界面以及食物和蛇的设置进行编辑; CSnakezyt:这个类是用来对蛇的绘制以及运动进行编辑 3、 游戏设置功能设计 首先绘制所选课题详细的流程图,根据游戏所要实现的过程把每一个过程的动作进行解析,并将其变成相应的变量; 4、 游戏功能的实现 这个过程是在编程环境下实现的,通过我自己对整个程序的解析,一步一步的将各个过程实现的代码输入编程软件,通过反复的调试和运行进行程序的检验和最终功能的实现。 5、 编写实验报告 3. 课程设计内容 3.1 概要设计 3.1.1 程序总体框架描述 开始进入游戏界面 选择游戏难度 游戏结束 蛇死了? Y N 点击游戏开始按钮 蛇运动速度加快一倍 蛇开始运动吃豆子 是否吃到5个豆子 蛇身变长,新的豆子出现,分数加100 是否吃到豆子? N Y Y Y N 蛇继续吃豆子 3.1.2程序常用类声明和变量的声明 CBeanzyt类 用来实现有关豆子的所有功能 CGezyt类 用来实现游戏界面的设置以及蛇的运动环境 CSnakezyt类 用来实现蛇的所有功能 类型 变量名 CString m_string CSnakezyt snake CBeanzyt bean bool m_start bool m_pause int m_speed int m_marks int sign 3.2主要技术 1、 对于单文档设置界面大小功能的实现; 2、 对于单文档中Menu的菜单删除、添加功能的实现; 3、 对设置快捷键功能的实现; 4、 对于Bitmap制做功能的实现; 5、 代码的熟练运用。 3.3系统设计结果 (界面截图、操作流程) 1、打开VC++6.0,选中MFCAppWizard(exe),选路径如图: 然后选择单文档,在高级选项中,将窗口样式厚边框和最大化边框的勾勾去掉。 2、在Menu中设置游戏快捷键,并在Accelerator中实现快捷功能,最后对快捷键建立类向导 在OnStart()和OnPause()函数中添加如下代码: void CZYTView::OnStart() { // TODO: Add your command handler code here this->m_start=true; SetTimer(1,200/m_speed,NULL); } void CZYTView::OnPause() { // TODO: Add your command handler code here static t=1; if(t%2==1) { this->m_pause=true; } else { this->m_pause=false; } t++; } 3、接下来新建4个位图BIPMAP, 第一个IDB_BITMAP_zyt1用来设置游戏背景; 第二个IDB_BITMAP_zyt2用来设置蛇的头; 第三个IDB_BITMAP_zyt3用来设置蛇的身子; 第四个IDB_BITMAP_zyt4用来设置豆。 IDB_BITMAP_zyt1 IDB_BITMAP_zyt2 IDB_BITMAP_zyt3 IDB_BITMAP_zyt4 4、OnDraw函数中将背景设置成一个个小方框,代码如下: //画背景 CDC dcMemory; dcMemory.CreateCompatibleDC(pDC); CBitmap bitmap; bitmap.LoadBitmap(IDB_BITMAP_zyt1); dcMemory.SelectObject(&bitmap); int i,j; for(i=0;i<=38;i++) { for(j=0;j<=38;j++) { pDC->StretchBlt(0+10*i,0+10*j,10,10,&dcMemory,0,0,48,48,SRCCOPY); } //边界线 bitmap.Detach(); CPen pen(PS_SOLID,1,RGB(0,0,0)); CPen *pOldPen=pDC->SelectObject(&pen); pDC->MoveTo(0,390); pDC->LineTo(390,390); pDC->SelectObject(pOldPen); 调整游戏界面窗口,并改名字 cs.style = WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX; cs.cx=400; cs.cy=480; cs.lpszName="周玉亭版贪吃蛇。。。一定吃到豆噢!"; 5、画蛇 首先插入一个类CGezyt class CGezyt { public: CGezyt(); virtual ~CGezyt(); public: int i;//小格所在的行数; int j;//小格所在的列数; }; 6、再插入一个CSnakezyt类,其代码如下: class CSnakezyt { public: CSnakezyt(); virtual ~CSnakezyt(); public: int n;//蛇身长度 CGezyt body[200];//蛇身数组 int direction;//蛇前进的方向,1代表向上,2代表向右,3代表向下,4代表向左 public: CGezyt forwardUp(); //向上前进 CGezyt forwardRight();//向右前进 CGezyt forwardDown(); //向下前进 CGezyt forwardLeft(); //向左前进 }; 7、在CSnakezyt类CSnakezyt()构造函数中写出蛇上下左右四个运动是body数组是怎么变化的 CGezyt CSnakezyt::forwardUp() { CGezyt ret=body[n-1]; for(int i=n-1;i>=1;i--) { body[i].i=body[i-1].i,body[i].j=body[i-1].j; } body[0].i--; return ret; } CGezyt CSnakezyt::forwardRight() { CGezyt ret=body[n-1]; for(int i=n-1;i>=1;i--) { body[i].i=body[i-1].i,body[i].j=body[i-1].j; } body[0].j++; return ret; } CGezyt CSnakezyt::forwardDown() { CGezyt ret=body[n-1]; for(int i=n-1;i>=1;i--) { body[i].i=body[i-1].i,body[i].j=body[i-1].j; } body[0].i++; return ret; } CGezyt CSnakezyt::forwardLeft() { CGezyt ret=body[n-1]; for(int i=n-1;i>=1;i--) { body[i].i=body[i-1].i,body[i].j=body[i-1].j; } body[0].j--; return ret; } 8、在构造函数CViewZYT中初始化蛇 this->m_start=false; this->m_pause=false; snake.n=4,snake.direction=2; snake.body[0].i=2,snake.body[0].j=5; snake.body[1].i=2,snake.body[1].j=4; snake.body[2].i=2,snake.body[2].j=3; snake.body[3].i=2,snake.body[3].j=2; 9、在OnDraw函数中画蛇头和蛇身 //画蛇头 bitmap.LoadBitmap(IDB_BITMAP_zyt2); dcMemory.SelectObject(&bitmap); pDC->StretchBlt(0+10*snake.body[0].j,0+10*snake.body[0].i,10,10,&dcMemory,0,0,48,48,SRCCOPY); bitmap.Detach(); //画蛇身 bitmap.LoadBitmap(IDB_BITMAP_zyt3); dcMemory.SelectObject(&bitmap); for(i=1;i<snake.n;i++) { pDC->StretchBlt(0+10*snake.body[i].j,0+10*snake.body[i].i,10,10,&dcMemory,0,0,48,48,SRCCOPY); } bitmap.Detach(); 10、在Onstart函数中设立一个计时器并在CylcView中添加计时函数OnTimer,其中的代码如下: if(this->m_start==true && this->m_pause==false) { CGezyt tmp; CClientDC dc(this); CDC dcMemory; dcMemory.CreateCompatibleDC(&dc); CBitmap bitmap; switch(snake.direction) { case 1:tmp=snake.forwardUp(); break; case 2:tmp=snake.forwardRight(); break; case 3:tmp=snake.forwardDown(); break; case 4:tmp=snake.forwardLeft(); break; } if(ZytGameLose()==true) { m_marks=0; m_speed=1; m_start=false; MessageBox("亲,你怎么撞上了呢?!\n要再接再厉哟!"); zytrestart(); } if(ZytEatBean()==true) { snake.n++; snake.body[snake.n-1].i=tmp.i; snake.body[snake.n-1].j=tmp.j; //初始化豆子 unsigned seed=time(NULL); srand(seed); do { bean.i=rand()%24; bean.j=rand()%24; }while(ZytBeanInSnake()==true); bitmap.LoadBitmap(IDB_BITMAP_zyt4); dcMemory.SelectObject(&bitmap); dc.StretchBlt(0+10*bean.j,0+10*bean.i,10,10,&dcMemory,0,0,48,48,SRCCOPY); bitmap.Detach(); //显示的得分 COLORREF clr=dc.SetTextColor(dc.GetBkColor()); dc.TextOut(100,400,m_string); m_marks+=100; CString m; m.Format("%d",m_marks); m_string="亲,您的得分是:"+m; dc.SetTextColor(clr); dc.TextOut(100,400,m_string); } bitmap.LoadBitmap(IDB_BITMAP_zyt1); dcMemory.SelectObject(&bitmap); dc.StretchBlt(0+10*tmp.j,0+10*tmp.i,10,10,&dcMemory,0,0,48,48,SRCCOPY); bitmap.Detach(); //画蛇头 bitmap.LoadBitmap(IDB_BITMAP_zyt2); dcMemory.SelectObject(&bitmap); dc.StretchBlt(0+10*snake.body[0].j,0+10*snake.body[0].i,10,10,&dcMemory,0,0,48,48,SRCCOPY); bitmap.Detach(); //画蛇身 bitmap.LoadBitmap(IDB_BITMAP_zyt3); dcMemory.SelectObject(&bitmap); for(int i=1;i<snake.n;i++) { dc.StretchBlt(0+10*snake.body[i].j,0+10*snake.body[i].i,10,10,&dcMemory,0,0,48,48,SRCCOPY); } bitmap.Detach(); } CView::OnTimer(nIDEvent); } 对上面代码中加粗的添加成员函数: 添加ZytGameLose成员函数,其代码如下(撞上边框或撞上自己本身): bool CZYTView::ZytGameLose() { if(snake.body[0].i==-1 || snake.body[0].i==39 || snake.body[0].j==-1 || snake.body[0].j==39 || ZytHeadStrike()==true) { return true; } else { return false; } } 添加ZytHeadStrike成员函数,其代码如下: bool CZYTView::ZytHeadStrike() { bool flag=false; for(int i=1;i<snake.n;i++) { if(snake.body[0].i==snake.body[i].i && snake.body[0].j==snake.body[i].j) { flag=true; break; } } return flag; } 添加ZytEatBean成员函数,其代码如下: bool CZYTView::ZytEatBean() { if(snake.body[0].i==bean.i && snake.body[0].j==bean.j) { //this->m_marks+=100; return true; } else { return false; } } 11、为了蛇会转弯移动,先添加KEYDOWN函数 其代码如下: void CZYTView::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) { // TODO: Add your message handler code here and/or call default if(nChar==VK_UP && snake.direction!=3) { snake.direction=1; } if(nChar==VK_RIGHT && snake.direction!=4) { snake.direction=2; } if(nChar==VK_DOWN && snake.direction!=1) { snake.direction=3; } if(nChar==VK_LEFT && snake.direction!=2) { snake.direction=4; } CView::OnKeyDown(nChar, nRepCnt, nFlags); } 12、下面对豆建立一个类 其代码如下: class CBeanzyt { public: CBeanzyt(); virtual ~CBeanzyt(); public: int i;//豆子所在行 int j;//豆子所在列 }; 13、在CylcView构造函数中初始化豆子 //初始化豆子 unsigned seed=time(NULL); srand(seed); do { bean.i=rand()%24; bean.j=rand()%24; }while(ZytBeanInSnake()==true); 对上段代码中ZytBeanInSnake构造成员函数,其代码如下: bool CZYTView::ZytBeanInSnake() { bool flag=false; for(int i=0;i<snake.n;i++) { if(bean.i==snake.body[i].i && bean.j==snake.body[i].j) { flag=true; break; } } return flag; } 14、在OnDraw函数中 //画豆子 bitmap.LoadBitmap(IDB_BITMAP_zyt4); dcMemory.SelectObject(&bitmap); pDC->StretchBlt(0+10*bean.j,0+10*bean.i,10,10,&dcMemory,0,0,48,48,SRCCOPY); bitmap.Detach(); 15、对游戏失败之后的游戏重启zytrestart进行设置,代码如下: void CZYTView::zytrestart() { //初始化蛇 snake.n=4,snake.direction=2; snake.body[0].i=2,snake.body[0].j=5; snake.body[1].i=2,snake.body[1].j=4; snake.body[2].i=2,snake.body[2].j=3; snake.body[3].i=2,snake.body[3].j=2; //初始化豆子 unsigned seed=time(NULL); srand(seed); do { bean.i=rand()%24; bean.j=rand()%24; }while(ZytBeanInSnake()==true); Invalidate(); } 16、在界面上显示游戏分数代码如下(吃到一个豆就加100): 在CZYTView()函数中添加如下代码: this->m_start=false; this->m_pause=false; this->m_speed=1; this->m_marks=0; CString m; m.Format("%d",m_marks); this->m_string="亲,您的得分是:"+m; 在OnDraw函数中添加: //显示分数 pDC->TextOut(100,400,this->m_string); 在OnTimer函数中添加: //显示的得分 COLORREF clr=dc.SetTextColor(dc.GetBkColor()); dc.TextOut(100,400,m_string); m_marks+=100; CString m; m.Format("%d",m_marks); m_string="亲,您的得分是:"+m; dc.SetTextColor(clr); dc.TextOut(100,400,m_string); 17、当游戏结束时分数变为0,在 zytrestart函数添加如下代码: this->m_marks=0; CString m; m.Format("%d",m_marks); this->m_string="您的得分是:"+m; 当吃到5个豆以后速度加快: 在OnTimer函数中添加如下代码: if(m_marks%500==0 && m_marks!=0)//如果分数是500的则速度加快 { m_speed++; KillTimer(1); SetTimer(1,200/m_speed,NULL); } 18、最后设置一下游戏的模式: 在Menu中添加: 建立成员函数: 定义一个成员变量sign 在CZYTView()函数中给sign赋初值sign=0; void CZYTView::OnLow() { // TODO: Add your command handler code here sign=1; } void CZYTView::OnHigh() { // TODO: Add your command handler code here sign=2; } 在OnStart函数中添加如下代码: if(sign==1) { this->m_start=true; SetTimer(1,200/m_speed,NULL); } if(sign==2) { this->m_start=true; SetTimer(2,100/m_speed,NULL); } 再将OnTimer函数中原来的速度加快模式改为如下: if(m_marks%500==0 && m_marks!=0)//如果分数是500的则速度加快 { m_speed++; KillTimer(1); SetTimer(1,200/m_speed,NULL); KillTimer(2); SetTimer(2,100/m_speed,NULL); } 运行结果: 4.设计总结 4.1遇到的问题及如何解决 1、 问题:有时候出现一些变量没有定义,例如error C2065: 'bean' : undeclared identifier、error C2228: left of '.i' must have class/struct/union type等 原因:相关函数的头文件没有定义 解决:在相关函数中定义头文件。 2、 问题:蛇运动区域与边框不匹配,造成蛇运动出边框或未到达边框而游戏结束。 原因:数据没有匹配好。 解决:重新对程序中的矩形框绘制函数数据进行修改,并修改蛇运动边界的判断条件。 3、 问题:食物出现在边框外,造成游戏无法进行。 原因:控制事物出现的随机函数出现问题,随机坐标超出蛇运动区域。 解决:重新计算边界条件,修改随机函数rand()%x中的x值。 4、 问题:在最后在设置模式时,对于蛇的速度快慢的设置不是很顺利,速度变化有点大 原因:对相关函数和代码掌握的不是很好 解决:查找相关资料 4.2体会 这次MFC的课程考核,我选择了通过运用MFC程序设计来编写一个贪食蛇的程序。在编写程序之前,我信心满满,因为课上讲的还都挺好实现的,不过等到我自己去设置一个小程序时,我发现,我根本不知道从哪里下手,也突然觉得自己对MFC的知识也不够深入。因此,首先我查阅许多关于贪食蛇的资料,也在网上看了许多关于贪食蛇的算法。做好了准备之后,才开始写我的贪食蛇。但是,在写的过程中还是遇到了许多问题。首先我遇到的第一个问题是我怎么画出贪吃蛇的格子,后来找到相关资料,这个需要代码来实现。还有的问题是如何将存储贪食蛇节点的数组与显示相结合起来。在开始的两天,我一直没有能够解决这个问题,最后呢,我在网上查资料才找到一个比较好的解决方法。另外我还在程序设计的过程中碰到了如何让蛇身隔在每个给定的时间间隔内移动一个的问题,这也是通过和同学讨论解决的。以及这次课程考核通过完成贪食蛇游戏的程序设计,锻炼了我的动手能力,增加了我的实际编程经验,提高了我独立思考和解决问题的能力。这次考核收获颇丰啊! - 27 -展开阅读全文
咨信网温馨提示:1、咨信平台为文档C2C交易模式,即用户上传的文档直接被用户下载,收益归上传人(含作者)所有;本站仅是提供信息存储空间和展示预览,仅对用户上传内容的表现方式做保护处理,对上载内容不做任何修改或编辑。所展示的作品文档包括内容和图片全部来源于网络用户和作者上传投稿,我们不确定上传用户享有完全著作权,根据《信息网络传播权保护条例》,如果侵犯了您的版权、权益或隐私,请联系我们,核实后会尽快下架及时删除,并可随时和客服了解处理情况,尊重保护知识产权我们共同努力。
2、文档的总页数、文档格式和文档大小以系统显示为准(内容中显示的页数不一定正确),网站客服只以系统显示的页数、文件格式、文档大小作为仲裁依据,个别因单元格分列造成显示页码不一将协商解决,平台无法对文档的真实性、完整性、权威性、准确性、专业性及其观点立场做任何保证或承诺,下载前须认真查看,确认无误后再购买,务必慎重购买;若有违法违纪将进行移交司法处理,若涉侵权平台将进行基本处罚并下架。
3、本站所有内容均由用户上传,付费前请自行鉴别,如您付费,意味着您已接受本站规则且自行承担风险,本站不进行额外附加服务,虚拟产品一经售出概不退款(未进行购买下载可退充值款),文档一经付费(服务费)、不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
4、如你看到网页展示的文档有www.zixin.com.cn水印,是因预览和防盗链等技术需要对页面进行转换压缩成图而已,我们并不对上传的文档进行任何编辑或修改,文档下载后都不会有水印标识(原文档上传前个别存留的除外),下载后原文更清晰;试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓;PPT和DOC文档可被视为“模板”,允许上传人保留章节、目录结构的情况下删减部份的内容;PDF文档不管是原文档转换或图片扫描而得,本站不作要求视为允许,下载前可先查看【教您几个在下载文档中可以更好的避免被坑】。
5、本文档所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用;网站提供的党政主题相关内容(国旗、国徽、党徽--等)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。
6、文档遇到问题,请及时联系平台进行协调解决,联系【微信客服】、【QQ客服】,若有其他问题请点击或扫码反馈【服务填表】;文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“【版权申诉】”,意见反馈和侵权处理邮箱:1219186828@qq.com;也可以拔打客服电话:0574-28810668;投诉电话:18658249818。




mfc贪吃蛇.doc



实名认证













自信AI助手
















微信客服
客服QQ
发送邮件
意见反馈



链接地址:https://www.zixin.com.cn/doc/11423546.html