宿迁学院Windows程序设计课程考核报告班级: 11计本2班学号:姓名:得分:2013年12月20 日1. 设计目的及要求 ............................................................................. - 3 -1.1设计目的及问题描述 .............................................................. - 3 -1.2设计要求 .................................................................................. - 3 -1.3软件、硬件环境 ...................................................................... - 3 -2. 课程设计步骤 ................................................................................. - 3 -3. 课程设计内容 ................................................................................. - 4 -3.1 概要设计 ................................................................................. - 4 -3.1.1 程序总体框架描述 ....................................................... - 4 -3.1.2程序常用类声明和变量的声明 .................................... - 4 -3.2主要技术 .................................................................................. - 5 -3.3系统设计结果(界面截图、操作流程) ............................ - 5 -4.设计总结.......................................................................................... - 24 -4.1遇到的问题及如何解决 ........................................................ - 24 -4.2体会......................................................................................... - 24 -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 程序总体框架描述3.1.2程序常用类声明和变量的声明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 herethis->m_start=true;SetTimer(1,200/m_speed,NULL);}void CZYTView::OnPause(){// TODO: Add your command handler code herestatic 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_zyt1IDB_BITMAP_zyt2IDB_BITMAP_zyt3 IDB_BITMAP_zyt44、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、画蛇首先插入一个类CGezytclass 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,4 8,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,S RCCOPY);}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,SRC COPY);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 defaultif(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构造函数中初始化豆子//初始化豆子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;//初始化豆子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 heresign=1;}void CZYTView::OnHigh(){// TODO: Add your command handler code heresign=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' : undeclaredidentifier、error C2228: left of '.i' must have class/struct/union type等原因:相关函数的头文件没有定义解决:在相关函数中定义头文件。