收藏 分享(赏)

深入体会C语言项目开发_-_俄罗斯方块游戏.doc

上传人:cjc2202537 文档编号:5381111 上传时间:2019-02-27 格式:DOC 页数:32 大小:1.60MB
下载 相关 举报
深入体会C语言项目开发_-_俄罗斯方块游戏.doc_第1页
第1页 / 共32页
深入体会C语言项目开发_-_俄罗斯方块游戏.doc_第2页
第2页 / 共32页
深入体会C语言项目开发_-_俄罗斯方块游戏.doc_第3页
第3页 / 共32页
深入体会C语言项目开发_-_俄罗斯方块游戏.doc_第4页
第4页 / 共32页
深入体会C语言项目开发_-_俄罗斯方块游戏.doc_第5页
第5页 / 共32页
点击查看更多>>
资源描述

1、 第 1 章俄罗斯方块游戏俄罗斯方块游戏是一款风靡全球的电视游戏机和掌上游戏机中的游戏产品,它曾 经产生了无与伦比的商业价值,影响了一代游戏产业链 。这款游戏最初是由苏联 的游戏制作人 Alex Pajitnov 制作的,它看似简单但却变化无穷,令人上瘾,并且可以引发无数遐想。在本章内容中,将介绍使用 C 语言开发一个简单的俄罗斯方块游戏的方法,并详细 介绍其具体的实现流程。2深入体验 C 语言项目开发1.1 第一个项目我叫 Bird,一名项目经理。和往常一样,早早地来到了办公室。和这个城市的大多数白领一样,有条不紊地进行着自己的工作。当闲暇时刻,我会静坐在办公桌前,展望我的未来,当然也会回忆

2、过去。我回忆最多的是第一次做项目时的情景。作为普通程序员的众多第一次中,肯定会对自己第一次做项目的情景印象深刻。追忆大学四载,做过很多东西:网页设计、个人网站、照片处理、扫雷游戏等。但是真正能称为项目的是大三那年做过的一款游戏俄罗斯方块游戏。1.1.1 老师的作业2004 年 7 月 1 日,晴,我的作业今天可以离校了,一想到未来两个月的假期,我的心情就不能平静,很早就向往这两个月假期了,我想趁着大学时期的最后一个暑假,好好地出去转一转,思索一下自己的未来路在离校前的 10 分钟,我们最敬仰的程序老师 TC 给我们布置了一个暑期作业:题目很简单用 C 语言实现俄罗斯方块游戏 (提示用 grap

3、hics.h 实现) ,并提醒务必做好前期的分析工作。1.1.2 准备工作2004 年 7 月 3 日,微风阵阵暑假,总能给人带来美好的心情和很多想象的空间,总想利用这个假期去旅游,去放飞心情,我也想出去玩玩。坐在家中的电脑前,我想起了老师的作业俄罗斯方块游戏,这是一款风靡全球的电视游戏机和掌上游戏机游戏,少时的我曾经为它痴狂过。时过境迁,没想到现在我能去开发这个游戏!永远记得老师的建议:在做项目前一定要好好地构思和规划项目,根据需求规划开发流程。于是,我在电脑上画了一个简单的项目开发流程图,如图 1-1 所示。 功 能 分 析 模 块 结 构 规 划 总 体 设 计数 据 结 构规 划 函

4、数具 体 编 码图 1-1 开发流程图第 1 章 俄罗斯方块游戏3 功能分析:分析整个系统所需要的功能; 模块结构规划:规划系统中所需要的功能模块; 总体设计:分析系统处理流程,探索系统核心模块的运作; 数据结构:设计系统中需要的数据结构; 规划函数:预先规划系统中需要的功能函数; 具体编码:编写系统的具体实现代码。1.2 功 能 分 析2004 年 7 月 4 日,阳光明媚清晨太阳未升,我起了一个大早。俄罗斯方块游戏在脑海中还隐隐约约有印象,为了更深入地了解这款游戏,我专门到网上下载了一个,并试玩了几分钟,其基本结构如图 1-2 所示。底 部 预 览 界 面 图 1-2 俄罗斯方块游戏的基本

5、结构这样,我总结出了俄罗斯方块游戏的基本功能模块,并做了一个简单的项目规划书,整个规划书分为两个部分: 系统需求分析; 结构规划。1.2.1 系统需求分析1) 游戏方块的预览功能当游戏运行后并在底部出现一个游戏方块时,必须在预览界面中出现下一个方块,这样便于玩家提前进行控制处理。因为在该游戏中共有 19 种方块,所以在方块预览区内要4深入体验 C 语言项目开发显示随机生成的游戏方块。2) 游戏方块的控制功能游戏玩家可以对出现的方块进行移动处理,分别实现左移、右移、快速下移、自由下落和行满自动消除功能的效果。3) 更新游戏显示当在游戏中移动方块时,需要先消除先前的游戏方块,然后在新坐标位置重新绘

6、制新方块。4) 游戏速度设置和分数更新通过游戏分数能够实现对行数的划分,例如,可以设置消除完整的一行为 10 分。当达到一定数量后,需要给游戏者进行等级上的升级。当玩家级别升高后,方块的下落速度将加快,从而游戏的难度就相应地提高了。5) 系统帮助游戏玩家进入游戏系统后,通过帮助了解游戏的操作提示。一个俄罗斯方块游戏的基本功能也就上述 5 条了,当然现实中的游戏产品更加复杂,但其基本的功能都是大同小异的。1.2.2 结构规划现在开始步入结构规划阶段。为了加深印象,我做了一个模块结构图,如图 1-3 所示。俄 罗 斯 方 块 更 新 显 示方 块 控 制方 块 预 览速 度 分 数 更 新系 统

7、帮 助图 1-3 游戏的模块结构1.2.3 选择工具2004 年 7 月 5 日,晴,工具的困惑第 1 章 俄罗斯方块游戏5都说“工欲善其事,必先利其器!”,我也深知一个好的开发工具对整个项目进展的重要性。但是长久以来我一直很困惑:Turbo C 确实很好用,老师也极力推荐用 Turbo,但是我却一直不喜欢,主要原因是不能在里面实现复制、粘贴功能。我很想找一种既简单,功能又全面的开发工具,由于自己水平有限,只好电话求救师兄 A。我:“老师布置了一个作业:用 C 语言实现俄罗斯方块游戏(提示用 graphics.h 实现)。我不喜欢用 Turbo C,能否推荐几款能实现复制、粘 贴的工具? ”A

8、:“呵呵,我们现在的考试都是基于 Turbo C 的。除了 Turbo C,还有很多工具可以实现C 程序开 发,例如 DEV-C+、Visual C 和 Visual Studio.NET。DEV-C+是一个轻量级的开发工具,适合我们这样的初学者,Visual C 逐渐被 Visual C+6.0 所替代,而 Visual Studio.NET是微软推出为.NET 战略服务的,适合开发大型项目程序。”我:“为什么 Visual C 逐渐被 Visual C+6.0 所替代?”A:“因为 C 和 C+的相似性,所以大多数开 发工具既能开 发 C+程序,也能开发 C 程序。”我:“那我这个项目用什

9、么工具开发?”A:“只是一个简单的程序,所以首选 Turbo C 和 DEV-C+,但是老师已经提示了使用graphics.h 实现,所以建议选 Turbo C。因为在 DEV-C+中使用 graphics.h 比较复杂!”历时两天,我确定好了整个项目的功能模块,做好了整体规划,也选好了开发工具。接下来我将要步入总体设计阶段。1.3 总 体 设 计经过总体构成功能的分析后,接下来就可以根据各构成功能模块进行对应的总体设计处理。主要包括两个方面: 运行流程分析; 核心处理模块分析。1.3.1 运行流程分析2004 年 7 月 6 日,上午,阳光明媚今天是个好天气,我的心情也充满了期待。在闲暇之余

10、,整个俄罗斯方块游戏我已经玩了多遍了。根据总结的模块功能和规划的结构图,我得出了整个游戏的运行流程,并在电脑上绘出了整个游戏的具体运作流程图。游戏的具体运作流程如图 1-4 所示,用左移 VK_LEFT、右移 VK_RIGHT、下移VK_DOWN、旋转 VK_UP 和退出 VK_Esc 键判断键值。上述几个按键移动处理的具体说明如下。 VK_LEFT:调用 MoveAble( )函数,判断是否能左移,如果可以则调用EraseBox 函数,清除当前的游戏方块。并在下一步调用 show_box( )函数,在左移位置显示当前游戏的方块。6深入体验 C 语言项目开发 VK_RIGHT:右移处理,与上面

11、的 VK_LEFT 处理类似。 VK_DOWN:下移处理,如果不能再移,必须将 flag_newbox 标志设置为 1。 VK_UP:旋转处理,首先判断旋转动作是否执行,在此需要满足多个条件,如果不合条件,则不予执行。 VK_Esc:按 Esc 键后将退出游戏。图 1-4 游戏运行流程1.3.2 核心处理模块分析2004 年 7 月 6 日,下午,多云,还有很长的路要走每个人一出生就注定要走一段很长很长的旅程,到此为止,我才顿悟我距离完成项目还有很远很远的距离。但是此时我明白了整个游戏的核心内容:游戏预览、方块控制、更新显示、速度和分数更新。整个项目就是实现上述功能,而我的目标就是编码实现上述

12、功能。目标已明确,我需要做的就是大步往前走!第 1 章 俄罗斯方块游戏71方块预览新游戏的方块将在 44 的正方形小方块中预览,使用随机函数 rand( )可以产生 1-19之间的游戏方块编号,并作为预览的方块编号。其中品尼高正方形小方块的大小由BSIZEBSIZE 来计算。2游戏方块控制处理方块的移动控制是整个游戏的重点和难点,具体信息如下。1) 左移处理处理过程如下。(1) 判断是否能够左移,判断条件有两个:左移一位后方块不能超越游戏底板的左边线,否则将越界;并且在游戏方块有值(值为 1)的位置,游戏底板不能是被占用的 (占用时值为 1)。(2) 清除左移前的游戏方块;(3) 在左移一位的

13、位置处,重新显示此游戏的方块。2) 右移处理处理过程如下。(1) 判断是否能够右移,判断条件有两个:右移一位后方块不能超越游戏底板的右边线,否则将越界;游戏方块有值位置,游戏底板不能被占用;(2) 清除右移前的游戏方块;(3) 在右移一位的位置处,重新显示此游戏的方块。3) 下移处理处理过程如下。(1) 判断是否能够下移,判断条件有两个:下移一位后方块不能超越游戏底板的底边线,否则将越界;游戏方块有值位置,游戏底板不能被占用。满足上述两个条件后,可以被下移处理。否则将 flag_newbox 设置为 1,在主循环中会判断此标志;(2) 清除下移前的游戏方块;(3) 在下移一位的位置处,重新显示

14、此游戏的方块。4) 旋转处理处理过程如下。(1) 判断是否能够旋转,判断条件有两个:旋转后方块不能超越游戏底板的底边线、左边线和右边线,否则将越界;游戏方块有值位置,游戏底板不能被占用;(2) 清除旋转前的游戏方块;(3) 在游戏方块显示区域(4 4)的位置,使用当前游戏方块的数据结构中的 next 值作为旋转后形成的新游戏方块的编号,并重新显示这个编号的游戏方块。3更新显示当游戏中的方块在进行移动处理时,要清除先前的游戏方块,用新坐标重绘游戏方块。当消除满行后,要重绘游戏底板的当前状态。清除游戏方块的方法是先画轮廓再填充,具体过程如下:绘制一个轮廓,使用背景色填充小方块,然后使用前景色画一个

15、游戏底板中8深入体验 C 语言项目开发的小方块。循环此过程,变化当前坐标,填充并画出 19 个这样的小方块,从而在游戏底板中清除此游戏方块。第 1 章 俄罗斯方块游戏94游戏速度和分数更新处理当行满后,积分变量 score 会增加一个固定的值,然后将等级变量 level 和速度变量speed 相关联,实现等级越高速度越快的效果。2004 年 7 月 6 日,晚上,总体设计的重要性今天我完成了总体设计的工作。老师曾经多次说过总体设计是一个项目的开始,也是后续工作得以顺利进行的前提,所以我在此阶段一丝不苟,考虑到一切可能产生影响的因素,尽量为后续工作打好坚实的基础。这样做似乎前面工作使用了很多时间

16、,但实际上是节约了后面的时间。马上休息,为接下来的数据结构设计做准备。1.4 数 据 结 构2004 年 7 月 7 日,上午,阳光充足因为刚刚结束总体设计的工作,感觉有些累,所以起得有一点晚。在这个阳光明媚的夏日里,我开始了数据结构方面的设计工作。因为项目很简单,所以需要的结构也不多。花了很少的时间,我就设计好了系统所需要的数据结构。1游戏底板结构体此处的游戏底板结构体是 BOARD,具体的代码如下。struct BOARD /*游戏底板结构,表示每个点所具有的属性*/int var; /*当前状态只有 0 和 1,1 表示此点已被占用*/int color; /*颜色,游戏底板的每个点可以

17、拥有不同的颜色,增强美观性*/Table_boardVertical_boxsHorizontal_boxs;其中,BOARD 结构体表示了游戏底板中每个小方块的属性,var 表示了当前的状态,为 0 时表示未被占用,为 1 时表示已经被占用。2游戏方块结构体此处的游戏方块结构体是 SHAPE,具体的代码如下。struct SHAPE/*一个字节是 8 位, 用每 4 位表示游戏方块中的一行,例如:box0=“0x88“,box1=“0xc0“表示的是:1000100011000000*/char box2;int color; /*每个方块的颜色*/int next; /*下个方块的编号*/

18、;10深入体验 C 语言项目开发SHAPE 结构体表示某个小方块的属性,char box2表示用 2 个字节来表示这个块的形状,每 4 位来表示一个方块的一行。color 表示每个方块的颜色,颜色值可以根据需要设置。3SHAPE 结构数组此处的游戏方块结构体是 SHAPE,具体的代码如下。/*初始化方块内容,即定义 MAX_BOX 个 SHAPE 类型的结构数组,并初始化*/struct SHAPE shapesMAX_BOX=/* 口 口口口 口口 口* 口 口 口 口口口* 口口 口 */0x88, 0xc0, CYAN, 1,0xe8, 0x0, CYAN, 2,0xc4, 0x40,

19、CYAN, 3,0x2e, 0x0, CYAN, 0,/* 口 口口 口口口* 口 口 口 口* 口口 口口口 口 */0x44, 0xc0, MAGENTA, 5,0x8e, 0x0, MAGENTA, 6,0xc8, 0x80, MAGENTA, 7,0xe2, 0x0, MAGENTA, 4,/* 口* 口口 口口* 口 口口*/0x8c, 0x40, YELLOW, 9,0x6c, 0x0, YELLOW, 8,/* 口 口口* 口口 口口* 口*/0x4c, 0x80, BROWN, 11,0xc6, 0x0, BROWN, 10,/* 口 口 口* 口口口 口口 口口口 口口* 口

20、 口 口*/0x4e, 0x0, WHITE, 13,0x8c, 0x80, WHITE, 14,0xe4, 0x0, WHITE, 15,第 1 章 俄罗斯方块游戏110x4c, 0x40, WHITE, 12,/* 口* 口* 口 口口口口* 口*/0x88, 0x88, RED, 17,0xf0, 0x0, RED, 16,/* 口口* 口口*/0xcc, 0x0, BLUE, 18;在上述代码中,定义了 MAX_BOX 个 SHAPE 类型的结构数组,并进行了初始化处理。因为共有 19 种不同的方块类型,所以 MAX_BOX 为 19。2004 年 7 月 7 日,晚上,数据结构的重要

21、性此刻我深刻地体会到数据结构在 C 语言中的作用,作为计算机存储、组织数据的方式。数据结构是相互之间存在一种或多种特定关系的数据元素的集合。通常情况下,精心选择的数据结构可以带来更高的运行或者存储效率。自我感觉上面的数据结构设计得很合理。1.5 一个神秘的箱子2004 年 7 月 8 日,晴空万里 武侠小说,是成年人的童话。从少年开始我就迷恋上了武侠小说,一直伴我读到大学。记得在某一段时间,我曾经特别痴迷一个神秘的箱子:一座高山,一处低岩,一道新泉,一株古松,一炉 红火,一 壶绿茶,一位老人,一个少年。“天下最可怕的武器是什么?”少年问老人:“ 是不是例不虚 发的小李飞刀?”“以前也许是, 现

22、在却不是了。”“为什么?”“因为自从小李探花仙去后, 这种武器已成绝响。 ”老人黯然叹息:“从今以后,世上再也不会有小李探花这种人;也不会再有小李飞刀这种武器了。”少年仰望高山,山巅白云悠悠。“现在世上最可怕的武器是什么?”少年又问老人:“ 是不是 蓝大先生的蓝山古剑?”“不是。”老人道:“你说的这些武器虽然都很可怕,却不是最可怕的一种。”“最可怕的一种是什么?”“是一口箱子。 ”“一口箱子?”少年惊奇极了:“ 当今天下最可怕的武器是一口箱子? ”“是的。”12深入体验 C 语言项目开发这是出自古龙的武侠名著英雄无泪的一段对白,没错最厉害的武器是一口箱子。等我看完全文之后我才明白,这不是一口简

23、单的箱子,箱子里有很多个零部件,能够根据不同的对手而迅速组成一个战胜对手的武器。现在我发现这个箱子和程序中的函数是那么的相似!我们要编程解决一个问题,要实现某个功能,我们可以编写一个函数来实现它。如果有多个问题,则编写多个函数就可以实现,函数就是我们编程中的那个神秘的箱子。书归正传,我预先设置好了整个项目中需要的函数,并做好了定义。1函数 NewTimer函数 NewTimer 用于实现新的时钟,具体结构如下:void interrupt newtimer(void)2函数 SetTimer函数 SetTimer 用于设置新时钟的处理过程,具体结构如下:void SetTimer(void i

24、nterrupt(*IntProc)(void)3函数 KillTimer函数 KillTimer 用于恢复原有的时钟处理过程,具体结构如下:void KillTimer()4函数 initialize函数 initialize 用于初始化界面,具体结构如下:void initialize(int x,int y,int m,int n)5函数 DelFullRow函数 DelFullRow 用于删除满行, y 设置删除的行数,具体结构如下:int DelFullRow(int y)6函数 setFullRow函数 setFullRow 用于查询满行,并调用 DelFullRow 函数进行处理

25、,具体结构如下:void setFullRow(int t_boardy)7函数 MkNextBox函数 MkNextBox 用于生成下一个游戏方块,并返回方块号,具体结构如下:int MkNextBox(int box_numb)8函数 EraseBox函 数 EraseBox 用 于 清 除 以 (x,y)位 置 开 始 的 编 号 为 box_numb 的 游 戏 方 块 , 具 体 结 构 如第 1 章 俄罗斯方块游戏13下 :void EraseBox(int x,int y,int box_numb)9函数 show_box函数 show_box 用于显示以(x,y)位置开始的编号

26、为 box_numb,颜色值为 color 的游戏方块,具体结构如下:void show_box(int x,int y,int box_numb,int color)10函数 MoveAble函数 MoveAble 首先判断方块是否可以移动,其中(x,y)是当前的位置,box_numb 是方块号,direction 是方向标志。具体结构如下:int MoveAble(int x,int y,int box_numb,int direction)2004 年 7 月 8 日,晚上,函数的重要性我历经 8 天的忙碌,终于完成了前期的所有工作。整个过程很顺利,虽然项目很简单,但是我很细心,可以说这

27、是我第一次这么细心地做一个项目。到此为止,我更加认识到了函数在 C 语言中的作用。几乎项目中的所有功能都是通过函数来实现的,函数构成了整个项目的主体。1.6 具 体 实 现2004 年 7 月 9 日,晴空万里 经过几天的忙碌,所有前期工作都完成了。前面 8 天的工作,都只能称为前期的准备工作,接下来的才是具体实现过程。下面我将根据前期的分析和规划,来编写各段代码。我已经准备好了自己的绝世好剑,开发征程正式拉开序幕!1.6.1 预处理如果说前面的准备工作是开发项目的第一步,那么预处理就打响了程序开发的第一枪。我们先看一下预处理的定义:预处理是在程序源代码被编译之前,由 预处理器(Preproc

28、essor)对程序源代码进行的处理。这个过程并不对程序的源代 码进行解析,但它把源代 码 分割或处理成为特定的符号用来支持宏调用。看来预处理也是一个准备工作,不搬到台面上。这就像我们辛苦学习知识,为将来的工作而做准备一样。在以后工作中,所学的知识只会在后台默默无闻地支持着我们。在开始之前画了一个简单的实现流程图,如图 1-5 所示。14深入体验 C 语言项目开发定义常量变量引用公用文件 定义按键码定义结构初始化方块内容图 1-5 预处理流程图(1) 先引用图形函数库等公用文件,具体代码如下所示。#include #include #include #include /*图形函数库*/(2) 定

29、 义 按 键 码 , 即 操 控 游 戏 的 按 键 : 左 移 、 右 移 、 下 移 、 上 移 等 。 具 体 代 码 如 下 所示 。/*定义按键码 */#define VK_LEFT 0x4b00#define VK_RIGHT 0x4d00#define VK_DOWN 0x5000#define VK_UP 0x4800#define VK_ESC 0x011b#define TIMER 0x1c /*设置中断号*/(3) 定义系统中需要的常量,例如方块种类、方块大小、方块颜色等。具体实现代码如下所示。/*定义常量 */#define MAX_BOX 19 /*总共有 19 种形

30、态的方块*/#define BSIZE 20 /*方块的边长是 20 个像素*/#define Sys_x 160 /*显示方块界面的左上角 x 坐标*/#define Sys_y 25 /*显示方块界面的左上角 y 坐标*/#define Horizontal_boxs 10 /*水平的方向以方块为单位的长度*/#define Vertical_boxs 15 /*垂直的方向以方块为单位的长度,也就说长是 15 个方块*/#define Begin_boxs_x Horizontal_boxes 2 /*产生第一个方块时出现的起始位置*/#define FgColor 3 /*前景颜色,如文

31、字.2-green*/#define BgColor 0 /*背景颜色.0-blac*/#define LeftWin_x Sys_x+Horizontal_boxs*BSIZE+46 /*右边状态栏的 x 坐标*/#define false 0#define true 1/*移动的方向 */#define MoveLeft 1第 1 章 俄罗斯方块游戏15#define MoveRight 2#define MoveDown 3#define MoveRoll 4/*以后坐标的每个方块可以看作像素点是 BSIZE*BSIZE 的正方形*/(4) 定义系统中需要的全局变量,例如,方块的下落速度

32、、玩家的分数、当前的方块编号等。具体实现代码如下所示。/*定义全局变量*/int current_box_numb; /*保存当前方块编号*/*x,y 是保存方块的当前坐标的*/int Curbox_x=Sys_x+Begin_boxs_x*BSIZE,Curbox_y=Sys_y;int flag_newbox=false; /*是否要产生新方块的标记 0*/int speed=0; /*下落速度*/int score=0; /*总分*/int speed_step=30; /*每等级所需要分数*/* 指向原来时钟中断处理过程入口的中断处理函数指针 */void interrupt (*ol

33、dtimer)(void);(5) 定义底板结构和方块结构。每一个新出现的方块结构是不同的,当方块下落到游戏底板后,结构也是不同的,所以必须编写两个结构来存储即时结构。具体实现代码如下所示。struct BOARD /*游戏底板结构,表示每个点所具有的属性*/int var; /*当前状态 只有 0 和 1,1 表示此点已被占用*/int color; /*颜色,游戏底板的每个点可以拥有不同的颜色,增强美观性*/Table_boardVertical_boxsHorizontal_boxs;/*方块结构 */struct SHAPEchar box2; /*一个字节等于 8 位,每 4 位表示

34、一个方块的一行如:box0=“0x88“,box1=“0xc0“表示的是:100000011000000*/int color; /*每个方块的颜色*/int next; /*下个方块的编号*/;(6) 开始初始化方块内容,即定义允许 MAX_BOX 个预定义类型的数组,其中MAX_BOX 代表允许的最多箱子个数,并初始化。初始化就是把变量赋为默认值,把控件设为默认状态,把没准备的准备好。具体实现代码如下所示。/*初始化方块内容 */struct SHAPE shapesMAX_BOX=/* 口 口口口 口口 口* 口 口 口 口口口* 口口 口 16深入体验 C 语言项目开发*/0x88,

35、0xc0, CYAN, 1,0xe8, 0x0, CYAN, 2,0xc4, 0x40, CYAN, 3,0x2e, 0x0, CYAN, 0,/* 口 口口 口口口* 口 口 口 口* 口口 口口口 口 */0x44, 0xc0, MAGENTA, 5,0x8e, 0x0, MAGENTA, 6,0xc8, 0x80, MAGENTA, 7,0xe2, 0x0, MAGENTA, 4,/* 口* 口口 口口* 口 口口*/0x8c, 0x40, YELLOW, 9,0x6c, 0x0, YELLOW, 8,/* 口 口口* 口口 口口* 口*/0x4c, 0x80, BROWN, 11,0x

36、c6, 0x0, BROWN, 10,/* 口 口 口* 口口口 口口 口口口 口口* 口 口 口*/0x4e, 0x0, WHITE, 13,0x8c, 0x80, WHITE, 14,0xe4, 0x0, WHITE, 15,0x4c, 0x40, WHITE, 12,/* 口* 口* 口 口口口口* 口*/0x88, 0x88, RED, 17,0xf0, 0x0, RED, 16,/* 口口* 口口*/0xcc, 0x0, BLUE, 18;第 1 章 俄罗斯方块游戏1718深入体验 C 语言项目开发2004 年 7 月 9 日,晚上,时刻要学习在具体编码之前,在我脑海中关于预处理的知

37、识毫无印象。因此在具体编码时,我发现一行代码也写不出来。这种情况我相信在很多初学者身上也发生过,而且不止发生一次。我没有办法,只能自己搜集资料学习。看来无论是一个学生,还是以后步入职场,都要随时提高自己,来应对新技术的发展。1.6.2 主函数我深知主函数的重要性,所以在设计之前,特意请教了师兄 A:我:“开始主函数设计了,哈哈!”A:“呵呵,看来准备工作都已经做完了。我不知你前面的工作流程,但是我还是提醒你要注意:前期准备工作的重要性!整体分析和规划都要仔细考虑,并且尽可能的书面化!”我:“嗯,明白了!作 为主函数,您有什么建议?”A:“五个字:尽量的简单!因为主函数肩负着入口和出口的重任,所

38、以尽量不要把太多细节方面的逻辑直接放在主函数内, 这样不利于维护和扩 展。主函数 应该尽量简洁,具体的实现细节应该封装到被调用的子函数中。 ”简单是编写函数的第一要务,我编写的主函数如下。void main()int GameOver=0;int key,nextbox; int Currentaction=0;/*标记当前动作状态*/int gd=VGA,gm=VGAHI,errorcode;initgraph(errorcode = graphresult(); if (errorcode != grOk) printf(“nNotice:Graphics error: %sn“, gra

39、pherrormsg(errorcode);printf(“Press any key to quit!“);getch(); exit(1); setbkcolor(BgColor);setcolor(FgColor);randomize();SetTimer(newtimer);initialize(Sys_x,Sys_y,Horizontal_boxs,Vertical_boxs);/*初始化*/nextbox=MkNextBox(-1);show_box(Curbox_x,Curbox_y,current_box_numb,shapescurrent_box_numb.color);s

40、how_box(LeftWin_x,Curbox_y+200,nextbox,shapesnextbox.color);show_intro(Sys_x,Curbox_y+320);getch();while(1)第 1 章 俄罗斯方块游戏19/* Currentaction=0;flag_newbox=false;检测是否有按键*/if (bioskey(1)key=bioskey(0); else key=0; switch(key)case VK_LEFT:if(MoveAble(Curbox_x,Curbox_y,current_box_numb,MoveLeft)EraseBox(C

41、urbox_x,Curbox_y,current_box_numb);Curbox_x-=BSIZE;Currentaction=MoveLeft;break;case VK_RIGHT:if(MoveAble(Curbox_x,Curbox_y,current_box_numb,MoveRight)EraseBox(Curbox_x,Curbox_y,current_box_numb);Curbox_x+=BSIZE;Currentaction=MoveRight;break;case VK_DOWN:if(MoveAble(Curbox_x,Curbox_y,current_box_num

42、b,MoveDown)EraseBox(Curbox_x,Curbox_y,current_box_numb);Curbox_y+=BSIZE;Currentaction=MoveDown;else flag_newbox=true;break;case VK_UP:/*旋转方块*/if(MoveAble(Curbox_x,Curbox_y,shapescurrent_box_numb.next,MoveRoll)EraseBox(Curbox_x,Curbox_y,current_box_numb);current_box_numb=shapescurrent_box_numb.next;C

43、urrentaction=MoveRoll;break;case VK_ESC:GameOver=1;break;default:break;if(Currentaction) /*表示当前有动作,移动或转动*/show_box(Curbox_x,Curbox_y,current_box_numb,shapescurrent_box_numb.color);Currentaction=0;/*按了向下键,但不能下移,就产生新方块*/if(flag_newbox)20深入体验 C 语言项目开发/*这时相当于方块到底部了,把其中占满一行的清去,置 0*/ErasePreBox(LeftWin_x,

44、Sys_y+200,nextbox);nextbox=MkNextBox(nextbox);show_box(LeftWin_x,Curbox_y+200,nextbox,shapesnextbox.color);/*刚一开始,游戏结束*/if(!MoveAble(Curbox_x,Curbox_y,current_box_numb,MoveDown)show_box(Curbox_x,Curbox_y,current_box_numb,shapescurrent_box_numb.color);GameOver=1;elseflag_newbox=false;Currentaction=0;

45、else /*自由下落*/if (Currentaction=MoveDown | TimerCounter (20-speed*2)if(MoveAble(Curbox_x,Curbox_y,current_box_numb,MoveDown)EraseBox(Curbox_x,Curbox_y,current_box_numb);Curbox_y+=BSIZE;show_box(Curbox_x,Curbox_y,current_box_numb,shapescurrent_box_numb.color);TimerCounter=0;if(GameOver )/*| flag_newbo

46、x=-1*/printf(“game over,thank you! your score is %d“,score);getch();break;getch();KillTimer();closegraph();2004 年 7 月 10 日,傍晚的夜色,体会主函数的美丽经过一天的努力,我完成了预处理和主函数的编码工作,在此阶段体会到了主函数的重要性。在 C 语言中,任何程序的执行都是从主函数 main( )开始,并且在主函数中结束,退出程序。主函数可以调用其他函数,其他函数可以互相调用,但不能调用主函数。一般而言,编写一个能运行在操作系统上的程序,都需要一个主函数。主函数意味着建立一个独立

47、进程,且该进程成为程序的入口,对其他各函数(在某些 OOP 语言里称作方法,比如第 1 章 俄罗斯方块游戏21Java)进行调用,当然其他被调用函数也可以再去调用更多函数。工作一切顺利,接下来我开始进行界面初始化的设计工作。1.6.3 界面初始化2004 年 7 月 11 日,上午,晴早晨起来,呼吸着这座海边小城新鲜的空气,我顿时精神抖擞了许多。昨天疲惫的心态已经被我消灭的无影无踪,可以饱满的精神开发界面了!在每次玩俄罗斯方块时,需要对游戏的界面进行初始化处理。然后在主函数中对其进行调用,实现最终的初始化处理。初始化界面的处理流程如下。(1) 循环调用函数 line( ),用于绘制当前的游戏板

48、。(2) 调用函数 ShowScore( ),显示初始的得分,初始得分是 0。(3) 调用函数 ShowSpeed( ),显示初始的等级速度,初始速度是 1。在这里有两个参数需要特别注意: x,y:代表左上角坐标; m,n:对应于 Vertical_boxes,Horizontal_boxs ,分别表示纵横方向上方块的个数(以方块为单位)。编写具体的实现代码。/*初始化界面*/void initialize(int x,int y,int m,int n)int i,j,oldx;oldx=x;for(j=0;j=0;n-)/*从当前行往上看*/totoal=0;for(m=0;m=t_boardy;n-)if(n=Vertical_boxs )

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 实用文档 > 工作总结

本站链接:文库   一言   我酷   合作


客服QQ:2549714901微博号:道客多多官方知乎号:道客多多

经营许可证编号: 粤ICP备2021046453号世界地图

道客多多©版权所有2020-2025营业执照举报