




已阅读5页,还剩25页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
VC+项目开发实验报告课题名称:基于MFC的俄罗斯方块游戏设计 姓 名: 学 号: 系 别: 计算机学院 班 级: 专 业: 指导教师: 1 俄罗斯方块的游戏概述1.1 游戏简介俄罗斯方块游戏由莫斯科科学学院程序员AlexeiPajitnov设计,发行于1985年。他在玩过一个拼图游戏之后受到启发,从而制作了一个以Electronica60为平台的俄罗斯方块的游戏。后来经瓦丁格拉西莫夫移植到PC上,并且在莫斯科的电脑界传播。帕基特诺夫因此开始小有名气。随后几年,俄罗斯方块开始登陆各大游戏主机。也曾因为版权问题引起过许多纠纷。但是拜亚洲盗版商人所赐,俄罗斯方块被引进到国内,如今已成为家喻户晓的著名游戏了。如今电子游戏业如此繁荣,作为电子游戏鼻祖的俄罗斯方块起到了决定性的作用。如今俄罗斯方块已有多种版本,有的加了几种特殊形状,有的可以使用道具,还有连机的俄罗斯方块等等。但万变不离其宗,不管怎么变,游戏的基本规则是没有变化的。游戏玩法十分简单,如今已经成为一种公认的规则:屏幕顶部以随机顺序落下形状各异的方块,你要试图用它们拼成没有空隙的行列。坚持得时间越长,游戏速度也就变得越来越快,而游戏的吸引力就在于使你顶住碎块的进攻,支撑的时间比上一次更长。由于玩法简单,容易上手,如今仍是风靡全球,老少皆宜的一款游戏1.2 游戏功能描述最原始的俄罗斯方块由七个不同形状的碎块组成,而每个碎块又是由四个大小相同的方块构成。游戏开始后方块会根据难度的不同而以不同的速度开始下降。在落地之前,玩家需要通过旋转方块使方块以最合适的形态下落,用它们拼成没有空隙的行列。如此便完成消行,使得游戏有更大的空间可以继续下去。如果方块累积达到游戏空间的顶层,游戏便失败而无法继续。2 需求分析与概要设计2.1 游戏开发基本策略游戏区域由许多等面积的小方块构成,这些区域状态只有满或空两种。将空间以静态二维数组实现,并预先定义其状态值。满为1,空为0,以此来完成游戏地图区域的空间分配。小方块的实现是由一个4*2的小数组表示,用四个存储单位空间存储当前下坠物的每一个子块的位置来对整个下坠物件的位置进行标识,每个存储空间的大小就是一个点的坐标。每个方块都有其对应的编号,编号按由上到下,由左到右的顺序编排。有了这些编号,方块的变换实现起来就方便多了。再由一个宏去标识下坠物的位置。 游戏进程需要定时器的驱动,所以很有必要在程序当中加入一个定时器机制。如此对游戏的开始,暂停,结束控制便能够得到实现。游戏开始后便开始掉落方块,并且会在游戏区域上方出现下一个下坠物的形态,因此有随机物件产生这个操作。此时用户可根据需要来变换方块,向左或向右移动来调整方块位置,然后通过按下使方块加速下落。这就涉及到了四个主要操作。当方块向左或向右移动时,需要判定方块是否达到了游戏区域的边界;当方块下落时需要判定方块是否到了游戏区域的底部,或是碰到了别的方块。这样游戏内部便引入众多相关函数。对这些函数进行实现和细化之前,需要对整个游戏运行期间的概要流程有所了解。游戏流程图如下: 开始消行操作生成新的下坠物将新的下坠物代替旧的下坠物将旧的下坠物作为当前下坠物到达底部消行操作到达顶部游戏结束游戏结束处理下降一个单位否是否是到达底部结束图21 系统流程图2.2 俄罗斯方块的功能需求程序的工作原理主要是在一个MFC工程中建立出各种函数并相互关联以及一些程序算法,并在一台PC机上实现俄罗斯方块游戏的运行。游戏功能结构图如下所示:主界面游戏选项设置游戏控制设置背景颜色游戏级别游戏退出游戏结束游戏暂停游戏开始红色绿色灰色第六级第五级第四级第三级第二级第一级方块颜色红色方块蓝色方块黄色方块紫色方块绿色方块图22 游戏功能结构图 由图中所示可以看出此方块游戏除了基本的开始、暂停、结束、退出功能外,还具有选择游戏级别、方块颜色、背景颜色的功能。具体这些功能的实现将会在后面做出详细的解说。3 开发工具介绍3.1 VC+的优点VC+是由Microsoft公司制作,基于WINDOWS环境的一款编程软件。由于WINDOWS操作系统比起MS-DOS操作系统优越了许多。作为与之相搭配的编程软件自然也是功能非常强大,其最大的特点也就是可视化。不过在提供可视化的编程方式的同时,它采用了面向对象的程序设计方法,同传统的结构化程序设计方法相比,缩短了软件开发的周期,提高了软件的开发效率,使程序员可以更好地理解和管理庞大且复杂的程序。VC中还集成了大量的最新技术,如ActiveX,COM等技术适合开发大型工程,这是相对于VB的一个优势。它的兼容性较好,还为用户提供了极为丰富的文档和范例。关于VC的参考资料也非常多,程序开发人员可以紧紧地把握住软件开发技术发展的方向,开发出功能强大的应用程序。3.2 WINDOWS编程机制WINDOWS是一个多进程的图形窗口操作系统。WINDOWS应用程序与DOS应用程序有很大的区别。DOS应用程序采用顺序执行过程,而WINDOWS是一个基于事件的消息(Message)驱动系统。消息驱动是WINDOWS应用程序的核心,消息不仅可由WINDOWS发出,它也可由应用程序本身或其它程序产生。所有的外部响应(如改变窗口大小或移动、单击鼠标等),该动作就会触发一个相应的“事件”而被Windows先拦截,转换成消息后再发送到指定应用程序的消息队列。从而使程序可以处理该事件。处理完以后,再等待下一个事件的发生。3.3 面向对象软件开发过程及思想面向对象方法是一种把面向对象的理念应用于软件开发过程中,指导开发活动的系统方法,是建立在“对象”概念基础上的方法学。对象是由数据和容许的操作组成的封装体,与客观实体有直接对应关系,一个对象类定义了具有相似性质的一组对象。而继承性是对具有层次关系的类的属性和操作进行共享的一种方式。所谓面向对象就是基于对象概念,以对象为中心,以类和继承为构造机制,来认识、理解、刻画客观世界和设计、构建相应的软件系统。 面向对象方法的具体实施步骤如下: 第一,面向对象分析:从问题陈述入手,分析和构造所关心的显示世界问题域的模型,并用相应的符号系统表示。模型必须是简洁、明确地抽象目标系统必须做的事,而不是如何做。分析步骤为: a.确定问题域,包括定义论域,选择论域,根据需要细化和增加论域; b.区分类和对象,包括定义对象,定义类、命名; c.区分整体对象以及组成部分,确定类的关系以及结构; d.定义属性,包括确定属性,安排属性; e.定义服务,包括确定对象状态,确定所需服务,确定消息联结; f.确定附加的系统约束。 第二,面向对象设计:面向对象的设计与传统的以功能分解为主的设计有所不同。具体设计步骤为: a.应用面向对象分析,对用其他方法得到的系统分析的结果进行改进和完善; b.设计交互过程和用户接口; c.设计任务管理,根据前一步骤确定是否需要多重任务,确定并发性,确定以何种方式驱动任务,设计子系统以及任务之间的协调与通信方式,确定优先级; d.设计全局资源,确定边界条件,确定任务或子系统的软、硬件分配; e.对象设计。 第三,面向对象实现:使用面向对象语言实现面向对象的设计相对比较容易。如果用非面向对象语言实现面向对象的设计时,特别需要注意和规定保留程序的面向对象结构。传统的面向功能的方法学中,强调的是确定和分解系统功能,这种做法虽然是目标的最直接的实现方式,但是由于功能是软件系统中最不稳定、最容易变化的方面,因而使系统难以维护和扩展。面向对象设计首先强调来自域的对象,然后围绕对象设置属性和操作。用面向对象设计,其结构源于客观世界稳定的对象结构。因而与传统软件设计方法相比,明显提高了软件的生产率,可靠性,易重用性、易维护性等方面的效果。3.4 MFC简介MFC是对WindowsAPI的封装,它可以大大简化我们的工作。使用 MFC 和 C+ 的优点是 MFC 已经包含和压缩了所有标准的“样板文件”代码,这些代码是所有用 C 编写的 WINDOWS 程序所必需的。当你使用 MFC 时,你编写的代码是用来建立必要的用户界面控制并定制其外观。同时你还要编写用来响应用户操作这些控制的代码。例如,如果用户单击一个按钮时,你应该有代码来响应。这就是事件驱动代码,它构成了所有应用程序。一旦应用程序正确的响应了所有允许的控制,它的任务也就完成了。此外,MFC 是在整个 Windows 家族中都是兼容的,也就是说,无论是 Windows3.x、Windows95 还是 Windows NT,所使用的 MFC 是兼容的。每当新的 Windows 版本出现时,MFC 也会得到修改以便使旧的编译器和代码能在新的系统中工作。MFC 也回得到扩展,添加新的特性、变得更加容易建立应用程序。MFC做了所有最难做的事,给程序员带来很大的方便。因此用 MFC 编写的程序要比用C语言编写的程序简单得多。另外,MFC 所编写的程序的性能也毫无损失。必要时,你也可以直接调用标准 C 函数,因为 MFC 不修改也不隐藏 WINDOWS 程序的基本结构。MFC包括大约100多个类,但常用的也就二三十个。就前面已经介绍到的App类、文档类、视图类、框架类等等,都是编程经常要用到的。4 游戏具体实现4.1 游戏总体设计本游戏界面简洁明了,没有什么花哨的东西。菜单栏功能并不复杂,仅有游戏控制和选项设置两项。进入游戏后的窗口背景是黑色调,游戏区域是灰色调,这些都可以通过选项进行调整。游戏区域有20列,10行,这样设计是为了让方框有足够的高度,可以让玩家有充足的反应时间来处理掉落的方块。游戏开始后默认的方块是具有立体感的红色方块,其颜色和质感都是经过精心设计的。而在上方会显示将要落下的方块,让玩家做好迎接挑战的心理准备,下方则显示分数。游戏的操作主要由鼠标和键盘来完成。鼠标点击开始后便可用键盘上的“上下左右”来对方块进行操作。游戏中所用到的类如下图所示:图41 游戏中的类由构架类视图中可以看到我们要实现此游戏需要六个类,这些类都是我们所熟悉的MFC基本架构组合,下面分别来介绍这六个类及其相关作用:(1) App为应用程序类,代表程序的核心。它封装了Windows-based应用程序的初始化、运行、Message映射和终止等功能。简单的说,它起到了程序中main()函数的作用,是程序所不可缺少的一个类。(2) Doc为文档类,包含应用程序的数据集。它作用于关于数据处理和序列化存取等功能的承载。它并不是独立存在于程序中的,如果要运行程序文档、视图、框架三个类有密不可分的联系。文档类对视图类也起到了管理作用。(3) View为视图类,用于显示数据并与文档类对象交互。它拥有视图显示方面的功能。由于用VC+编写的游戏是可视化的,因此视图类中的函数也是最多的。方块的实现,游戏界面的实现,甚至一系列的操作都是由视图类实现的。它也是六个类中最庞大最复杂的一个类。(4) CmainFrame为框架类,它由文档类创建而成,用于应用程序的主要WINDOWS框架。(5) CAboutDlg为对话框类,用于俄罗斯方块参数选择的对话框类对象。View类中有众多函数,其主要函数的功能概括如下:(6) COptionDlg 为用作俄罗斯方块参数选择的对话框类对象。下面是游戏中重要函数的简单介绍:(1) OnDraw()函数,作用是承担游戏内所有绘制屏幕的工作。(2) OnTimer()函数,作用是承担游戏内所有驱动工作。(3) Random()函数,作用是布下一个随机种子使之产生随机数。(4) ActiveStatusToGameStatus()函数,作用是将当前下坠物的位置映射到游戏区域地图数组中去。(5) RectArrow()函数,作用是管理方块向左、向右或者加速下降。(6) IsBottom()函数,作用是判断当前方块是否已到底,并且销行等相关的工作。(7) OnKeyDown()函数,作用是处理用户的输入,方块的左,右移,加速及变形。(8) RectChange()函数,作用是管理方块的变形,并判断方块是否有足够的空间变形。4.2 游戏中运行窗口绘制 主窗口主要由标题栏,菜单栏和游戏区域构成。标题栏和菜单栏比较容易实现,可以直接在“IDR_MAINFRAM”弹出菜单编辑窗口中进行添加。游戏区域的实现较为困难一些。需要了解文档-视图-框架三者之间的联系,懂得一些相关方面的知识。视图View类主要用于视图的打印显示,而类中用的最多的还是OnDraw()函数,它负责真正的绘图工作。它也是和主窗口实现息息相关的一个函数。 首先要定下游戏区域的长宽。大小为20行,10列:m_iRow = 20;m_iCol = 10;然后是游戏区域与游戏背景的位置。由于游戏区域上方将要显示下一个将要下落的方块,所以游戏区域左上角X,Y坐标如下定义:m_iStartX = 100; m_iStartY = 10;m_iStartX坐标定义的比较大,是为了给下一个下落方块区域腾出空间。当基本数值都定义好了,还需要使用DcEnvInitial()函数来对绘图设备环境进行初始化。首先用默认的参数,获取当前屏幕设备环境CDC *pWindowDC = GetDC()。由于方块的绘制并不是在程序中实现的,而是通过外界位图的载入来实现,因此内存设备环境、内存位图、屏幕三者之间要通过语句来进行关联,要将外部位图rect.bmp动态载入m_hMemRectBmp中。位图是由PHOTOSHOP软件绘制而成的,图如下:图42 方块的BMP图 游戏中要求可以选择方块颜色,因此初步绘制了五种不同颜色的方块。五种方块要求能够通过菜单栏的选项进行调试,因此需要如下语句来完成:m_hMemRectBmp=(HBITMAP)LoadImage(NULL,rect.bmp,IMAGE_BITMAP,100,20,LR_LOADFROMFILE);游戏背景是可以选择的,有灰、绿、红三种颜色背景,再加上游戏区域底色是黑色,因此需要定义四种颜色的画刷:m_pGrayBrush = new CBrush(RGB(66,66,66);m_pGREENBrush = new CBrush(RGB(0,255,0);m_pREDBrush = new CBrush(RGB(255,0,0);m_pBlackBrush = new CBrush(BLACK); 画刷定义好后,就要开始填充背景。由于背景是可供选择的,因此需要使用一个条件选择语句SWITCH来完成这项功能。这些绘制功能是用DrawGame()函数来实现的。 小方块为边长为二十象素的方块,其绘制如下所示:x = m_iStartY+j*m_iLarge +2;y = m_iStartX+i*m_iLarge +2;nW = m_iLarge-1;nH = m_iLarge-1;pDC-BitBlt(x,y,nW,nH,&m_memRectDC,m_iBlockStyle*20,0,SRCCOPY);得分由白色字显示在游戏区域下方,pDC - TextOut(m_iStartY+60, m_iStartX+402,lsStr);画下一次将要出现的方块,用于提示玩家。其绘制方法与绘制其他小方块的方法相同,只是位置上产生了一些变化:x = m_iStartY+j*20+65;y = m_iStartX+i*20-90;nW = m_iLarge-1;nH = m_iLarge-1;pDC-BitBlt(x,y,nW,nH,&m_memRectDC,m_iBlockStyle*20,0,SRCCOPY);当绘图设备环境的初始化都完成后,便可用OnDraw()函数进行绘制了。void CSkyblue_RectView:OnDraw(CDC* pDC) DcEnvInitial(); DrawGame(&m_memDC); pDC-BitBlt(0,0,m_nWidth,m_nHeight,&m_memDC,0,0,SRCCOPY); 此函数本身并不长,但是它却做了最重要的绘图工作。当这些都做完后,游戏中运行窗口的绘制也完成了。4.3 方块设计4.3.1 方块的实现七种下坠物都有一个共同点,就是它们占据的空间一样,都是由四个等面积的小方块构成,因此用一个整型的二维数组ActiveStatus来存储每个下坠物的四个小方块的坐标位置。每个下坠物中的方块都有编号,编号按从左到右,从上到下的顺序排列。ActiveStatus00和ActiveStatus01则是第0号方块的横坐标X和纵坐标Y。图43 方块的编号除了当前用户正在操作的的下坠物之外,游戏界面上方还需要显示出下一个下坠物的形状。因此还需要用一个NextStatus数组来存储下坠物的形态。可以先根据当前的物件形状来初始化其具体形状,在视图类对象增加了一个成员函数RectStatusToNextStatus()来实现。举一个下坠物的例子来具体说明实现过程: ActiveStatus00 = 0; ActiveStatus01 = 1;ActiveStatus10 = 1; ActiveStatus11 = 1;ActiveStatus20 = 2; ActiveStatus21 = 1;ActiveStatus30 = 3; ActiveStatus31 = 1;这段程序中描述的便是第一个下坠物的形态。其对应坐标分别是:(x0,y0)=(0,1);(x1,y1)=(1,1);(x2,y2)=(2,1);(x3,y3)=(3,1);可以看出这个下坠物是一条直线的下坠物。对于新的下坠物的使用,可以先用RectStatusToActiveStatus()函数并根据初始化当前新的下坠物状态来映射出当前下坠物的四个小方块的初始位置,然后再用函数ActiveStatusToGameStatus()将当前的下坠物位置映射到地图区域中。4.3.2 方块的移动方块的移动是由键盘输入来完成的,因此首先需要添加对运动方向趋势的定义:#define LEFT 0 #define RIGHT 1 #define UP 2 #define DOWN 3 关于按键命令消息的响应,可以通过对WM_KEYDOWN消息的处理函数进行截获并重写来实现。该函数只对某些按键功能进行截获和响应,对应不同的功能模块。向左移动的左键VK_LEFT,向右移动的右键VK_RIGHT,向下加速的下键VK_DOWN,变形的向上键VK_UP。把向左,向右,向下整和成一个功能模块RectArrow()。来看看向左的命令是如何具体实现的:case LEFT: if ( (ActiveStatus010) & IsLeftLimit() & !m_isBottom) GameStatusx1y1=MAP_STATE_EMPTY; GameStatusx2y2=MAP_STATE_EMPTY; GameStatusx3y3=MAP_STATE_EMPTY; GameStatusx4y4=MAP_STATE_EMPTY;InvalidateCurrent();ActiveStatus01 -= 1; ActiveStatus11 -= 1; ActiveStatus21 -= 1; ActiveStatus31 -= 1;GameStatusx1y1-1=MAP_STATE_NOT_EMPTY; GameStatusx2y2-1=MAP_STATE_NOT_EMPTY; GameStatusx3y3-1=MAP_STATE_NOT_EMPTY; GameStatusx4y4-1=MAP_STATE_NOT_EMPTY;InvalidateCurrent(); break;从代码中可以看出程序首先获取了当前下坠物的四个小方块坐标,然后所有纵坐标递减一格,由InvalidateCurrent()函数计算出改变数据的视图区域,并通知重绘。这样便可完成左移命令。右移和下移的道理也是一样。但是这里涉及到一个问题,就是要对移动是否到达游戏区域的边界做出判断。左、右移的限制原理是一样的,只是方向和坐标数据有点区别,分别用IsLeftLimit(),IsRightLimit()函数来实现。根据各种不同形态的下坠物最左边的小方块的正左(右)方区域是否为非被占用状态来判断它是否可以移动。而下移的限制涉及到消行判断,这些将在后面做具体分析。4.3.3 方块的旋转方块的旋转操作需要考虑到两个问题,一个是如何实现旋转,另一个是判断能否旋转。为了实现旋转,首先获取当前下坠物的四个小方块的坐标位置。由于每种方块变形后的状态都不同,因此需要对下坠物的不同形态进行编号。编号情况如下:图44 方块变换后的编号编号完成后,根据当前下坠物的形态特征计算出变形后的各个小方块坐标,并计算出下一状态应该显示的状态值。这样方块的旋转便实现了。要判断方块能否变形,需要先进行虚拟变形,如果变形后所在区域内无其他方块,则表示有足够的空间可以变形且不能超出边界,这样才能实现真正的变形,并且修改变形后的当前下坠物形态记录。否则将原数据恢复,取消变形。此外还需判断下坠物是否变形后到达底部。4.3.4 方块的随机性产生新的下坠物前,需要先将当前状态物的记录和旧的下一个下坠物保存下来,然后用随机函数Random()产生一个最大值不大于指定值的随即正整数,将这个新生成的正整数用作新的“下一个下坠物”的状态值。此函数并不大,代码如下:int CSkyblue_RectView:Random(int MaxNumber)/部下随机种子srand( (unsigned)time( NULL ) );/产生随机数int random = rand() % MaxNumber;/保证非0if(random = 0 ) random+;return random;4.4 游戏控制设计4.4.1 消行判断首先需要建立一个IsBottom()的函数,此函数只要用于判断方块是否到达底部。关于底部有两个概念,一个是游戏区域的底部,另一个是由下坠物组成的底部。由于下坠物的形态不一,所以判定是否到达底部要根据其形状判断。可以预先对七种类型的下坠物各种形态的接触面做定义,然后判断是否已经到达底部的时候通过访问当前下坠物的当前形态的接触面,并结合其当前位置进行判断就可以知道是否已经到达底部了。接触面由一个二维数组来实现。记录的是一到七种下坠物的一到四种不同形态的接触面。Int InterFace 744;这个数组中的数字分别表示不同的含义。7表示一到七种下坠物,第一个4表示下坠物的四种形态,第二个4表示构成接触面的几个方块,接触面最多只有四个。用一个方块来举例子:InterFace410=0;InterFace411=2;InterFace412=3;图45 方块的接触面编号从图中可以很清楚的看到,此种形态的方块有三个接触面,分别是0,2,3。对于这三个构成接触面的坐标,可以利用ActiveStatus数组查出相应方块号的位置,然后通过其正下方的方块位置是否空闲就可以判断出是否到达底部了。判断底部比较困难,但是消行操作还是比较简单的。先检测游戏区域中的所有行,并对每行的所有纵列状态进行检测。如果其中有一列是空闲状态则不可消行。反之则可以。消行后会增加单位分数,并将其清空。再将上面所有物件下降一个单位,填充空缺。4.4.2 游戏关卡选择游戏可选择六种难度,选项如图所示:图46 游戏级别的选择首先定义目标功能,将目标功能通过资源编辑器在主菜单条进行添加,再用ClassWizard添加对应的响应处理函数。每个功能键对应一个资源ID,同时还要在它们的处理函数中对相应的参数进行适当的修改。通常对于功能的完善,多是将原来设定的固定值拓展成可修改的成员变量,而对这些成员变量的修改则通过函数接口去实现。这些函数主要作用是接受外部传来的信息,并对这些信息进行相对应的响应,来达到实现功能的作用。关于游戏等级的资源ID与其相应功能键图表如下:表41 游戏等级的ID及响应函数菜单选项名称快捷键资源ID响应处理函数游戏等级选择&I-第一级:毫不费力&1ID_OPTION_LEVEL1OnOptionLevel1第二级:轻轻松松&2ID_OPTION_LEVEL2OnOptionLevel2第三级:花点力气&3ID_OPTION_LEVEL3OnOptionLevel3第四级:有点困难&4ID_OPTION_LEVEL4OnOptionLevel4第五级:超出负荷&5ID_OPTION_LEVEL5OnOptionLevel5第六级:不可能&6ID_OPTION_LEVEL6OnOptionLevel6方块掉落的速度会随着游戏难度的增大而加快,其快慢的实现由如下语句来实现:SetTimer(1,1200-230*m_iLevel,NULL);随着难度数的增加m_iLevel值由0到5递增,则方块到达底部的时间越来越短,这样也就实现了难度的加大。4.4.3 方块颜色的转换前面已经说过方块颜色是可以变化的,共有五种不同颜色。选项如图所示:图47 方块颜色的选择关于方块颜色的资源ID与其相应功能键图表如下:表42 方块颜色的ID及响应函数菜单选项名称快捷键资源ID响应处理函数方块颜色选择&C-红色方块&1ID_COLOR1OnOptionCOLOR1蓝色方块&2ID_COLOR2OnOptionCOLOR2黄色方块&3ID_COLOR3OnOptionCOLOR3紫色方块&4ID_COLOR4OnOptionCOLOR4绿色方块&5ID_COLOR5OnOptionCOLOR5方块颜色变换后的游戏演示图如下:图48 变换方块颜色后的游戏 首先,前面已经讲过方块的样式是通过外界的BMP图载入进来的。但是如何通过选项来选择方块颜色需要与之相对应的函数来实现。前5个函数分别是用菜单设置方块的5种不同颜色,函数实现如下:void CSkyblue_RectView:OnUpdateCOLOR1(CCmdUI* pCmdUI) if (m_bGameEnd) pCmdUI - Enable(TRUE); else pCmdUI - Enable(FALSE); if (m_iBlockStyle = 0) pCmdUI - SetCheck(TRUE); else pCmdUI - SetCheck(FALSE);这是5个函数的其中一个,另外4个和它大同小异,只是函数名及调用的ID不同罢了。从函数中可以看出定义了两个按扭指针。一旦游戏为结束状态,则按扭为黑色,是可以按下的状态。否则就为灰色,为不可按状态。一旦第一个按扭被按下,则游戏便开始调用ID_COLOR1,于是游戏便以第一种颜色的方块进行游戏,其调用ID的函数如下:void CSkyblue_RectView:OnOptionCOLOR1() m_iBlockStyle = 0; 如此以来,方块颜色的改变便完成了。4.4.4 游戏背景的转换背景有三种颜色可选,选项如图所示:图49 背景颜色的选择关于背景颜色的资源ID与其相应功能键图表如下:表43 背景颜色的ID及响应函数菜单选项名称快捷键资源ID响应处理函数背景颜色选择&B-灰色&1ID_BACKSPACE1OnOptionBACKSPACE1绿色&2ID_BACKSPACE2OnOptionBACKSPACE2红色&3ID_BACKSPACE3OnOptionBACKSPACE3背景颜色变换后的游戏演示图如下:图410 变换背景颜色后的游戏 背景的变换由一个条件选择语句来完成。由于有三种不同的背景可选,因此也需要三个CASE,这里只介绍CASE 0。 case 0: pDC - SelectObject(m_pBlackBrush);GetClientRect(&rect);pDC - Rectangle(rect);pDC - SelectObject(m_pGrayBrush);pDC - Rectangle(m_iStartY ,m_iStartX, m_iStartY + 203, m_iStartX + 403); pDC-SelectObject(m_pBlackPen);break;游戏背景的填充是用前面所定义的画刷来完成的,首先就定义了黑、灰、绿、红四种颜色的画刷。从语句可以看出黑色画刷填充了游戏底色,灰色画刷填充了游戏区域。根据CASE的不同,灰色是可以转变为绿色或是红色。选项中颜色背景的转化还需要调用ID。其中之一的函数如下:void CSkyblue_RectView:OnUpdateBACKSPACE1(CCmdUI* pCmdUI) if (m_bGameEnd) pCmdUI - Enable(TRUE);else pCmdUI - Enable(FALSE);if (m_iBACKSPACE = 0) pCmdUI - SetCheck(TRUE);else pCmdUI - SetCheck(FALSE);void CSkyblue_RectView:OnOptionBACKSPACE1() m_iBACKSPACE = 0; 这个函数功能的实现和前面方块颜色的实现原理相同,只是调用的ID不同罢了。4.4.5 游戏加分规则游戏区域的下方显示分数,其算分规则为:一次销掉一行,加100分;一次销掉两行,加400分;一次销掉三行,加900分;一次销掉四行,加1600分。游戏内部的实现为:假如销掉X行,则分数为:X*(X*100)。X值的大小为1到4。4.4.6 游戏结束判断在方块下落时不仅要判断其是否到达底部,同时还要判断是否也到达了游戏顶部,从而判定游戏是否因违规而结束。一旦游戏结束,OnGameEnd()函数便立即中断所有操作,提示“游戏已结束”的对话框。游戏到达顶部的判断函数如下所示:if (m_isBottom)for (i=0;im_iCol;i+)if (GameStatus0i) KillTimer(1);AfxMessageBox(游戏已结束!);for (j=0;jm_iRow;j+)for (k=0;km_iCol;k+)GameStatusjk=0;Invalidate(FALSE);m_bGameEnd = TRUE;break;游戏结束后便要刷新游戏区域,以便下一次继续游戏时保证游戏区域内没有别的方块。游戏结束画面如图所示:图411 游戏结束画面结 论通过这几个月的毕业论文设计及对专业知识的学习,我的收获很大。刚开始做毕业设计自然是不知从何下手,但在指导老师彭文艺的指引下,我按部就班的完成了每个星期所布置的任务,从而慢慢走上了正轨,现在论文也接近尾声。这些都让我感到无比的欣慰。从课题选择、方案论证到具体设计,每一步对我来说无疑是巨大的尝试和挑战,也成就了我在大学期间独立完成的最大的项目。在开始做这个游戏之前,我很少接触编程方面的知识,更不知道一个编写一个游戏程序应该从哪里下手,经过翻阅大量的书籍和在网上搜索相关资料,我对VC+的了解越来越深。在具体设计的过程中,我遇到了更大的困难。面对犹如天书般的程序设计书,我仍然硬着头皮把他们一点一点看了下来。有时一遍不懂看两遍,两遍不懂看三编。面对冗长的程序代码,我也是一字一句参照参考书把他们的注释都写了下来,并加以了解。虽然我的设计作品不是很成熟,即使借鉴前人的很多资料仍然还有很多不足之处,但我仍然心里有一种莫大的幸福感,因为我实实在在地走过了一个完整的设计所应该走的每一个过程,并且享受了每一个过程,更重要的是这个设计中我加入了自己鲜活的思想。总之,这次毕业设计的经历,会使我终身受益,他使我感受到做设计和写论文是要真真正正用心去做的一件事情,是真正的自己学习的过程和研究的过程,没有学习就不可能有研究的能力,没有自己的研究,就不会有所
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 日照市莒县中小学美术教师招聘考试试题及答案
- 2025年机务检修考试试题及答案
- 2025年铁路机务试题及答案
- 高企调账合同模板(3篇)
- qc知识考试试题及答案
- 现代农业企业代理记账服务合同
- 文化产业项目投资担保合同模板
- 消费电子行业商标许可及技术创新协议
- 剑桥数学专业测试题及答案
- 园长专业考试试题及答案
- 数字化印花工艺智能化
- 成人鼻肠管的留置与维护
- 专题02 概率与统计解答题综合(解析版)
- MOOC 模拟电子电路实验-东南大学 中国大学慕课答案
- 多格列艾汀使用指南2024课件
- MOOC 创业基础-暨南大学 中国大学慕课答案
- (2024年)面神经炎课件完整版
- GB/T 41666.4-2024地下无压排水管网非开挖修复用塑料管道系统第4部分:原位固化内衬法
- 云端药历健保署电子病历-慈济大学医学资讯学系
- 道路车辆 局域互联网络(LIN) 第3部分:协议规范
- 桩基工程施工总体部署
评论
0/150
提交评论