资源描述
游戏软件设计课程报告(贪吃蛇游戏的实现)院系:数学与计算机科学系专业: 07数字媒体学号:20070861203姓名: 李建光指导教师:胥楚贵2010年10月23日目录一、应用程序的最终界面- 1 -1.1选题背景- 1 -1.2关于编译软件- 1 -1.3关于兼容性- 1 -第二章 概要设计- 2 -2.1软件主要功能设计- 2 -2.1.1程序结构- 2 -2.1.2程序流程- 2 -第三章 游戏实现- 4 -3.1变量函数及资源的声明- 4 -3.1.1函数声明- 4 -3.1.2变量声明- 4 -3.1.3资源- 5 -3.2主要功能的实现- 5 -3.2.1游戏界面控制- 5 -3.2.2初始化食物- 6 -3.2.3游戏控制- 7 -3.2.4英雄榜- 9 -3.2.5游戏设置- 9 -第四章 结果与讨论- 10 -4.1程序运行- 10 -4.2错误调试与分析- 12 -一、应用程序的最终界面本游戏是通过键盘的方向键来控制贪吃蛇的运动的,最终运行所产生的界面效果如下:1.1.选题背景贪吃蛇是家喻户晓的益智类小游戏,选择这个题目一是为了将自己的所学知识加以运用,二是一直以来贪吃蛇这个游戏就深深地吸引着我,它的制作方法对于以前的我而言都是很神秘的。我希望通过自己的所学知识把它剖析开来,真真正正的了解它的本质和精髓。虽然我的编程能力不是很强,但是我有信心,在这次学习中我将从实践和实际的项目中提高自己的编程能力。因此我选定了这个题目。1.2关于编译软件本程序采用Microsoft Visual C+6.0的英文版本进行编译。VisualC+6.0是Microsoft公司推出的基于Windows操作系统的可视化C+编程工具,尽管Microsoft公司推出了.NET平台的集成开发环境,但由于其良好的界面和可操作性,加上支持标准C/C+规范,但仍有相当多的编程人员使用VisualC+6.0进行应用系统的开发。1.3关于兼容性本程序经过调试,可以在XP系统下编译运行,也可以在Vista下运行,界面稍有不同,但不影响运行结果。第二章 概要设计2.1软件主要功能设计2.1.1程序结构根据分析,贪吃蛇这个程序一共要实现如下几个功能,包括游戏方面开始游戏、暂停游戏以及停止游戏,音乐音效的添加与控制,游戏帮助提示与英雄榜的显示等等。具体的程序结构如下面的图1-1所示。图2-1 贪吃蛇结构图2.1.2程序流程根据分析后的贪吃蛇结构设计出相应的贪吃蛇流程。贪吃蛇的内容主要包括: 游戏开始,随机出现食物;按下ToolBar中的暂停按钮或Space键可以实现暂停功能;按下帮助键或ToolBar中的“?”键可获得游戏帮助说明;可播放背景音乐和音效并可通过菜单以及ToolBar控制其播放或停止等等。图2-2 贪吃蛇流程图第三章 游戏实现3.1变量函数及资源的声明根据程序的结构,将贪吃蛇需要实现的功能细化成为相应的函数。3.1.1函数声明void CYuShuoView:OnDraw(CDC* pDC) /在OnDraw函数中绘制游戏背景、游戏文字以及控制蛇的样式颜色。void CYuShuoView:YsInitFood() /初始化贪吃蛇的食物,使其随机生成void CYuShuoView:YsInitGame() /初始化贪吃蛇游戏参数void CYuShuoView:YsReDisplay(CPoint ysPoint) /重绘游戏窗口void CYuShuoView:OnYsBegin() /开始游戏(菜单响应消息)void CYuShuoView:OnYsPause() /暂停游戏(菜单响应消息)void CYuShuoView:OnYsStop() /停止游戏(菜单响应消息)void CYuShuoView:OnYsExit() /退出游戏(菜单响应消息)void CYuShuoView:OnYsEffect() /控制游戏音效void CYuShuoView:OnYsMusicbkg() /控制游戏背景音乐void CYuShuoView:OnYsLevel1() /控制游戏等级为初级void CYuShuoView:OnYsLevel2() /控制游戏等级为中级void CYuShuoView:OnYsLevel3() /控制游戏等级为高级void CYuShuoView:OnYsHelpgame() /游戏帮助void CYuShuoView:OnYsBest() /英雄榜的显示3.1.2变量声明CArray m_ysBody; /定义点数组作为蛇的身体CPoint m_ysFood; /食物出现的点int m_ysTime; /显示时间int m_ysTime1; /满10则进一位使时间增加1秒int m_ysDirect; /方向控制变量int m_ysScore; /玩家成绩变量int m_yspausectrl; /暂停控制变量int m_yslevelctrl; /等级控制变量CString m_ysPlayer; /玩家姓名int m_yseffectctrl; /音效控制变量int m_ysmusicctrl; /背景音乐控制变量3.1.3资源1、对话框IDD_YS_HELPGAME /游戏帮助说明IDD_YS_BEST /英雄榜IDD_YS_RETRY /停止游戏确认IDD_ABOUTBOX /关于游戏版本2、音乐IDR_YS_BKGMUSIC /游戏背景音乐IDR_YS_EAT /贪吃蛇吃到食物的音乐IDR_YS_LOWSCORE /游戏结束后得低分音乐IDR_YS_HIGHSCORE /游戏结束后得高分音乐3、位图IDB_YS_BITMAP /游戏背景图4、菜单/工具栏 IDR_MAINFRAME /系统自带菜单IDR_YS_TOOLBAR /自己创建的工具条5、 头文件mmsystem.h /播放音乐的相应文件 fstream.h /文件流文件 3.2主要功能的实现3.2.1游戏界面控制贪吃蛇游戏的游戏界面包括背景图片、蛇身体的绘制、蛇移动范围的绘制等等。其中贪吃蛇的身体用什么方法绘制,才可以使得其在游戏过程中可以实现“吃”的功能是很重要的。因此在游戏界面的初始绘制时就必须考虑到游戏时可能遇到的问题。本程序采用点数组CArray m_ysBody来存储贪吃蛇,点数组的功能很强大,可以添加点,同时可以获得蛇的长度,对于而后进行游戏中控制蛇的颜色以及音效的播放等都有很大的帮助。3.2.2初始化食物确定用点数组存储贪吃蛇以后,贪吃蛇的食物如何达到随机出现,并且能够按照网格式与蛇头无偏差相接就是一个亟待解决的问题。随机出现应采用rand()函数来实现,而食物与蛇头无偏差相接则利用坐标来解决。设置两个整型变量m_ysX,m_ysY作为食物出现的点的坐标,令m_ysX= rand()%30, ,m_ysY= rand()%40即可。使随机出现的点能够整除最小网格,也就是使食物与蛇头无偏差相接。再由食物坐标(m_ysX,m_ysY)与蛇头坐标是否相同判断蛇是否“吃”到了食物,设置判断标签ysTag,如果吃到了,ysTag为1,则再出现下一个食物,反之,如果没吃到,则不出现食物直到标签为1为止。最后,再将(m_ysX,m_ysY)赋给m_ysFood作为食物坐标,以便在其他函数中调用。在下面的图3-2中,我们可以看到,蛇的身体是与出现的食物在一条直线上的,完全可以达到相接的目的。图3-2 蛇与食物的相接/初始化贪吃蛇的食物void CYuShuoView:YsInitFood()int m_ysX,m_ysY;while(1)m_ysX=rand()%30; /随机生成横坐标使其与贪吃蛇的身体可以接上m_ysY=rand()%40; /随机生成纵坐标使其与贪吃蛇的身体可以接上int ysTag=0; /设置标签for(int i=0;i=40) /如果纵坐标多于最下端边框ysTag1=1; /变量为1,判断死亡break;如果ysTag1为1,则说明蛇已经死亡,应当弹出对话框提示死亡,输出得分(如图3-4),同时还可以根据玩家的得分数相应的改变对话框中的话语(XP系统下)。图3-4 贪吃蛇的死亡我们看到图3-4的蛇身体的颜色发生了变化,不再是初始状态的绿色,而是变为了蓝色,这是在OnDraw(CDC* pDC)函数中设置的,设置变量获取蛇身长度,随着长度的增加,蛇的颜色发生相应改变,最终会变为表示危险的红色。并且伴随着贪吃蛇挂掉,播放不同的音乐,如果高于70分,则放带有掌声鼓励的高分音乐的IDR_YS_HIGHSCORE,反之,则播放蛇被撞死的电子音乐IDR_YS_LOWSCORE。播放音乐的函数用包含在头文件mmsystem.h中的PlaySound函数。此外,游戏开始还需要计时、计分以及暂停等功能。这些功能都比较简单,游戏时间和分数分别用两个变量m_ysTime和m_ysScore来记录,应用pDC-TextOut函数来输出即可。至于暂停和继续的功能实现,只需要暂停和恢复计时器就可以了,实现暂停功能即KillTimer(1)并同时令控制暂停变量为m_yspausectrl为0即可。代码实现:void CYuShuoView:OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) / TODO: Add your message handler code here and/or call defaultswitch(nChar)case VK_UP: /按向上键m_ysDirect=4; /控制方向变量为4break;case VK_DOWN: /按向下键m_ysDirect=3; /控制方向变量为3break;case VK_LEFT: /按向左键m_ysDirect=2; /控制方向变量为2break;case VK_RIGHT: /按向右键m_ysDirect=1; /控制方向变量为1break;case VK_SPACE: /按下空格键if(m_yspausectrl=1) /如果控制暂停变量为1KillTimer(1); /暂停游戏m_yspausectrl=0; /令控制暂停变量为0break;if(m_yspausectrl=0) /如果控制暂停变量为0SetTimer(1,100,NULL); /继续游戏m_yspausectrl=1; /令控制暂停变量为1break;CView:OnKeyDown(nChar, nRepCnt, nFlags);void CYuShuoView:OnYsBegin() / TODO: Add your command handler code hereYsInitGame(); /初始化游戏switch(m_ysmusicctrl) /根据音乐控制变量决定是否放音乐case 1: /如果音乐选择开/放导入的音乐:PlaySound(MAKEINTRESOURCE(IDR_YS_BKGMUSIC),AfxGetResourceHandle(),SND_ASYNC|SND_RESOURCE|SND_LOOP); break;case 0: /如果音乐选择关break;SetTimer(1,100,NULL); /设置时间 Invalidate(); /重绘窗口void CYuShuoView:OnTimer(UINT nIDEvent) / TODO: Add your message handler code here and/or call defaultm_ysTime1+; /开始计时if(m_ysTime1=10) /小单位时间满10m_ysTime+; /时间增加一秒m_ysTime1=0; /小单位时间清零重新计算Invalidate(); /刷新CPoint ysPoint2=m_ysBody.GetAt(0); /获取蛇身的第一个点坐标int ysTag1=0; /定义判断死亡的变量 switch(m_yslevelctrl) /根据不同的等级选择case 1: /选择初级KillTimer(1); /暂停计时器SetTimer(1,100,NULL); /设置计时器break;case 2: /选择中级KillTimer(1); /暂停计时器SetTimer(1,60,NULL); /设置计时器break;case 3: /选择高级KillTimer(1); /暂停计时器SetTimer(1,20,NULL); /设置计时器break;switch(m_ysDirect) /根据键盘按下键来选择蛇移动的方向case 1: /方向变量向下ysPoint2.y+; /点纵坐标自加if(ysPoint2.y=40) /如果纵坐标多于最下端边框ysTag1=1; /变量为1,判断死亡break;case 2: /方向变量向上ysPoint2.y-; /点纵坐标自减if(ysPoint2.y=30) /横坐标多于最右端边框ysTag1=1; /变量为1,判断死亡break;case 4: /方向变量向左ysPoint2.x-; /点横坐标自减if(ysPoint2.x0) /横坐标少于最左端边框ysTag1=1; /变量为1,判断死亡if(ysTag1=0) /如果标签为0for(int i=0;i=m_ysBody.GetUpperBound();i+)CPoint ysPoint3=m_ysBody.GetAt(i); /将蛇身体的坐标传递给新定义的点if(ysPoint2.x=ysPoint3.x&ysPoint2.y=ysPoint3.y) /如果两点完全相同,标签为1ysTag1=1;break;if(ysTag1=0)m_ysBody.InsertAt(0,ysPoint2); /将点添加到蛇的身体中YsReDisplay(ysPoint2); /重绘蛇的身体if(ysPoint2.x=m_ysFood.x&ysPoint2.y=m_ysFood.y) /如果蛇的身体与食物坐标重合switch(m_yseffectctrl) /根据音效控制变量决定是否放音效case 1: /如果音效选择开/放导入的音乐:PlaySound(MAKEINTRESOURCE(IDR_YS_EAT),AfxGetResourceHandle(),SND_ASYNC|SND_RESOURCE|SND_NODEFAULT);break;case 0: /如果音效选择关break;int k=m_ysBody.GetUpperBound();/获取蛇身体的长度if(k10&k20&k=30) /如果身体长度在20与30之间m_ysScore+=5; /分数增加5else /其余情况 m_ysScore+=8; /分数增加8YsInitFood(); /再出现下一个食物Invalidate(); /窗口重绘elseCPoint ysPoint3=m_ysBody.GetAt(m_ysBody.GetUpperBound();/将最后一个点赋给ysPoint3这点m_ysBody.RemoveAt(m_ysBody.GetUpperBound(); /将该点移开YsReDisplay(ysPoint3); /重新绘制ysPoint3这点elseKillTimer(1); /暂停时间CString ysscore; /定义显示分数的字符串if(m_ysScore=10) /如果分数少于10switch(m_yseffectctrl) /根据音效控制变量决定是否放音效case 1: /如果音效选择开/放导入的音乐:PlaySound(MAKEINTRESOURCE(IDR_YS_LOWSCORE),AfxGetResourceHandle(),SND_ASYNC|SND_RESOURCE|SND_NODEFAULT);break;case 0: /如果音效选择关break;ysscore.Format(你挂了!哈哈!%d分!你才得了这么两分!,m_ysScore);AfxMessageBox(ysscore);/弹出消息框显示得分else if(10m_ysScore&m_ysScore=25)switch(m_yseffectctrl) /根据音效控制变量决定是否放音效case 1: /如果音效选择开/放导入的音乐:PlaySound(MAKEINTRESOURCE(IDR_YS_LOWSCORE),AfxGetResourceHandle(),SND_ASYNC|SND_RESOURCE|SND_NODEFAULT);break;case 0: /如果音效选择关break;ysscore.Format(你挂了!哈哈!%d分!凑合事吧!,m_ysScore);AfxMessageBox(ysscore);/弹出消息框显示得分else if(25m_ysScore&m_ysScore=45)switch(m_yseffectctrl) /根据音效控制变量决定是否放音效case 1: /如果音效选择开/放导入的音乐:PlaySound(MAKEINTRESOURCE(IDR_YS_LOWSCORE),AfxGetResourceHandle(),SND_ASYNC|SND_RESOURCE|SND_NODEFAULT);break;case 0: /如果音效选择关break;ysscore.Format(你挂了!哈哈!%d分!还行呀!,m_ysScore);AfxMessageBox(ysscore);/弹出消息框显示得分else if(45m_ysScore&m_ysScore=70)switch(m_yseffectctrl) /根据音效控制变量决定是否放音效case 1: /如果音效选择开/放导入的音乐:PlaySound(MAKEINTRESOURCE(IDR_YS_HIGHSCORE),AfxGetResourceHandle(),SND_ASYNC|SND_RESOURCE|SND_NODEFAULT);break;case 0: /如果音效选择关break;ysscore.Format(你挂了!哈哈!%d分!不错哈!,m_ysScore);AfxMessageBox(ysscore);/弹出消息框显示得分else if(70m_ysScore&m_ysScorem_1bestscore|m_ysScore=m_1bestscore&m_ysTimem_1besttime)&m_yslevelctrl=1 本程序默认游戏结束即显示英雄榜,但玩家如果想在没有游戏时查看也可以点击菜单“帮助英雄榜”查看。3.2.5游戏设置这里的游戏设置主要是指游戏的等级以及音效音乐的播放控制。关于这三个量,我们已经予以了定义,只需要在按下相应键盘或鼠标消息的时候,将变量值进行改变,再利用这些值控制相应功能的运行。游戏的等级设置, 在按下菜单中的“游戏设置等级初级,中级,高级” 。代码如下:/如果选择初级void CYuShuoView:OnYsLevel1() / TODO: Add your command handler code herem_yslevelctrl=1; /等级控制变量为1/如果选择中级void CYuShuoView:OnYsLevel2() / TODO: Add your command handler code herem_yslevelctrl=2; /等级控制变量为2/如果选择高级void CYuShuoView:OnYsLevel3() / TODO: Add your command handler code herem_yslevelctrl=3; /等级控制变量为3游戏音效,在按下菜单中的“游戏设置音乐音效开/关” 后(即菜单消息void CYuShuoView:OnYsEffect()),代码如下:switch(m_yseffectctrl) /根据音效控制变量选择case 1: /音效选择开m_yseffectctrl=0; /将音效控制变量改为0break;case 0: /音效选择关m_yseffectctrl=1; /将音效控制变量改为1 break;其中在构造函数CYuShuoView:CYuShuoView()中已经将m_yseffectctrl的初值设置为1。第四章 结果与讨论4.1程序运行程序开始运行后会进入游戏界面,但是不会立即进行游戏,单击菜单的“开始”才会开始游戏。在游戏开始前,玩家可以根据自己的喜好,通过菜单或者工具栏设置游戏等级等。在游戏过程中,按下Space键就会暂停游戏,再按下Space键则会继续游戏。图4-1所显示的是XP系统下菜单的样式,以及单击菜单开始。(1)带有子菜单的菜单样式(2)单击开始菜单图4-1 菜单样式及单击开始游戏开始游戏了,小蛇越来越长,颜色也有所不同了。颜色的改变预示着游戏的难度加大了,并且,不同的最终得分会产生不同的死亡评语。在前面的图3-4中显示了贪吃蛇死亡的样子,其中因为该局游戏得分比较低,因此得到的评语是“你才得了这么两分!”,而如果得分较高,就会得到更好的评语,最好的评语是“牛!”。图4-2所显示的是游戏开始后随着蛇长度的增加而变的颜色。 (1) 黄色 (2)红色图4-2 蛇变颜色如果不太会玩贪吃蛇这款游戏,那么可以单击菜单“帮助游戏说明”,或者单击工具条上的,寻求帮助。如图4-2所示。图4-3 游戏说明如果你觉得自己实力很强想看看别人的成绩,那么可以单击英雄榜看看什么样。图4-4 英雄榜样式4.2错误调试与分析本程序由于经常调用Invalidate()函数重绘窗口,因此在游戏过程中频闪的非常严重。查阅了很多资料,双缓冲技术可以解决这个问题,但是如果采用双缓冲技术,暂时还不能克服背景的问题,因为在双缓冲技术的应用中,背景是被强制默认为颜色,而不是图片。我尝试改变了一下,但是没有成功,所以这个问题还没有解决。希望大家多多给予意见。
展开阅读全文