1、附件 1: 攀枝花学院学生课程设计(论文)题 目: 俄罗斯方块 学生姓名: 陈小蝶 学 号: 201310804005 所在院(系 ): 数学与计算机学院 专 业: 2013 级软件工程 班 级: 软件工程 1 班 指 导 教 师: 张会 职称: 2014 年 6 月 23 日攀枝花学院教务处制2攀枝花学院本科学生课程设计任务书题 目 俄罗斯方块1、课程设计的目的通过本课程设计使学生能够较全面的掌握面向对象程序设计的有关概念和开发方法,以便能较全面地理解、掌握和综合运用所学的知识,提高自身的编程能力。2、课程设计的内容和要求(包括原始数据、技术要求、工作要求等)实现一个俄罗斯游戏,要求:(1)
2、尽量使用图形用户界面方式实现(不作硬性要求)(2)可以实现人机对战,自动判断胜负(3)界面美观3、主要参考文献4、课程设计工作进度计划序号 时间(天) 内容安排 备注1 1 分析设计准备 周一2 2 编程调试阶段 周至周三3 1 编写课程设计报告 周四4 1 考核 周五总计 5(天)指导教师(签字) 日期 年 月 日教研室意见:年 月 日学生(签字): 接受任务时间: 年 月 日注:任务书由指导教师填写。3附件 3: 课程设计(论文)指导教师成绩评定表题目名称评分项目 分值 得分 评价内涵01 学习态度 6 遵守各项纪律,工作刻苦努力,具有良好的科学工作态度。02 科学实践、调研 7 通过实验
3、、试验、查阅文献、深入生产实践等渠道获取与课程设计有关的材料。工作表现20% 03 课题工作量 7 按期圆满完成规定的任务,工作量饱满。04 综合运用知识的能力 10能运用所学知识和技能去发现与解决实际问题,能正确处理实验数据,能对课题进行理论分析,得出有价值的结论。05 应用文献的能力 5能独立查阅相关文献和从事其他调研;能提出并较好地论述课题的实施方案;有收集、加工各种信息及获取新知识的能力。06 设计(实验)能力,方案的设计能力 5能正确设计实验方案,独立进行装置安装、调试、操作等实验工作,数据正确、可靠;研究思路清晰、完整。07 计算及计算机应用能力 5 具有较强的数据运算与处理能力;
4、能运用计算机进行资料搜集、加工、处理和辅助设计等。能力水平35%08对计算或实验结果的分析能力(综合分析能力、技术经济分析能力)10 具有较强的数据收集、分析、处理、综合的能力。09插图(或图纸)质量、篇幅、设计(论文)规范化程度5 符合本专业相关规范或规定要求;规范化符合本文件第五条要求。10 设计说明书(论文)质量 30 综述简练完整,有见解;立论正确,论述充分,结论严谨合理;实验正确,分析处理科学。成果质量45% 11 创新 10 对前人工作有改进或突破,或有独特见解。成绩指导教师评语指导教师签名: 年 月 日45摘 要近年来,随着游戏产业的突飞猛进,游戏玩家的技术也是与日俱增,当你看见
5、游戏高手完美的表演时,你是否想过我也能达到那种水平,本程序采用全世界最金典的游戏俄罗斯方块作为背景,程序设置了鼠标和键盘两个选择方式,游戏运行时随着等级的提高而速度加快,这需要玩家快速操作。因此,本程序主要意义是为高手玩家提供训练平台。其次也可为刚踏入游戏领域的新手们,提供一个很好的锻炼机会。 本次课程设计主要解决利用 Visual C+设计实现俄罗斯方块游戏的算法、游戏内部功能、游戏区域的绘图的程序设计。对于每个俄罗斯方块各自的形态变化改变到下一个形态利用数组来实现,在程序设计中,采用 WIN32 机制来实现,并且直接从架构的其中一个类对象中继承下来,将它完善而变成有某功能特性的物件对象。关
6、键词 俄罗斯方块 数据结构 算法 数组 Visual C+6目 录摘 要一、 绪论21.1 课题背景2二、课程设计的要求与目的32.1 课程设计的要求32.2 课程设计的目的3 三、程序需求分析3.1 功能需求3.2 方块及各种变化需求3.3 操作需求3.31 向上键3.32 向下键3.33 向右键.四、程序流程图4.1 主要功能设计4.2 程序流程图4.3 游戏界面4.4 生成方块4.5 方块变形4.6 方块显示4.7 障碍判断4.8 消行记分4.9 暂停退出4.10 软件使用说明五、源程序代码5.1 源程序代码六、程序结果76.1 程序结果参考文献致 谢568第一章 绪论俄罗斯方块是个老幼
7、皆宜的小游戏,是经久不衰的一款游戏,自从它诞生那天起就一直深受人们的喜爱。几乎每个人都玩过这个游戏,也是人们接触最多的一款游戏,它实现由四块正方形的色块组成,然后存储在一个数组的四个元素中,计算机随机产生不同七种类型的方块,根据计算机时钟控制它在一定的时间不停得产生,用户根据键盘的四个方向翻转、向左、向右和向下操作,(控制键的实现是由键盘的方向键消息函数实现) 。然后程序根据这七种方块堆叠成各种不停得模型。1.1 游戏的背景俄罗斯方块是一款风靡全球的电视游戏机和掌上游戏机游戏,它曾造成的轰动与造成的经济价值可言说是游戏史上的一件大事。这款游戏最初是由苏联的游戏制作人 Alex Pajitnov
8、 制作的,它看似简单但却变化无穷,令人上瘾。相信大多数用户都还记得为它痴迷得茶饭不思不想的那个俄罗斯方块时代。俄罗斯方块最早还是出现在 PC 机上,而我国的用户都是通过红白机了解、喜欢上它的。现在联众又将重新掀起这股让人沉迷的俄罗斯方块风潮。对于一般用户来说,它的规则简单,容易上手,且 u、游戏过程变化无穷,俄罗斯方块游戏现在基本上是每个手机必备的游戏,种类千变万化,多种多样。9第二章 课程设计的目的与要求2.1 课程设计的目的本课程是一个综合性的实践教学环节,其目的在于促进学生复习和巩固计算机软件设计知识,加深对软件设计方法、软件设计技术和设计思想的理解,并能运用所学知识进行开发。希望通过本
9、课程设计中简单系统的开发,使学生掌握软件设计的基本方法和基本的流程,提高学生的综合应用能力。2.2 课程设计的要求要求用 VC+编写与实现俄罗斯方块。要求包括系统的需求分析;系统总框图及每个模块的设计分析;算法的设计与实现;游戏的内部实现;游戏区域绘画的实现;系统存在的问题及错误处理;列出所有定义的函数及说明;附上源程序;10第三章 程序需求分析3.1 功能需求随机给出不同的形状下落填充给定的区域,若填满一条便消掉,记分,设计不同的游戏难度,即方块下落的速度不同,若在游戏中各形状填满了给定区域为输者。3.2 方块及各种变换需求本游戏需要七种方块,而每种方块还可以进行旋转。每种方块每行每列最多只
10、有 4 个小方块。可以将它们放在一个 n*m 的区域内,该区域可以看做是有许多个等面积小方块构成的区域,而这些区域的状态只有两种,被方块占据或空闲。因此,对于整个游戏区域的空间是被占据或空闲,可以用一位数来标识。对于七种方块和它们旋转后的形态我们可以用不同的标识进行标记。对于旋转,游戏中所有方块都是按照逆时针旋转的规则进行的,而且在旋转过程中它们不会因为旋转而下降,总会保持在同一高度。任何方块经过一个旋转周期还会变回原型。3.3 操作需求3.31 向上键产生方块旋转操作,方块并非任何情况都能旋转,如果旋转后与小方块矩阵显示的方块有冲突或超出边界是,均不发生旋转。因此首先要判断是否有足够的空间进
11、行旋转。然后是旋转是否旋转。3.32 向下键产生方块加速下落操作,如果方块已经达到游戏区域底部或者有其他方块遮挡,则方块停止下降。3.33 向右键产生下落方块右移操作。首先要判断此方块是否能够发生右移,当越界或被其他显示方块阻挡时,则不能右移。11第四章 详细设计4.1 主要功能设计根据分析,俄罗斯方块这个程序一共要实现如下几个功能,开始游戏(F8) 、游戏的暂停继续(S)和退出游戏(Q)。其中游戏控制最为主要和重要,它控制着整个游戏的画面和有关数据的操作,是游戏的核心部分。暂停和退出功能做成一体,在退出的提示下不做任何操作即可实现暂停的功能。4.2 程序流程图根据分析后的程序结构图设计出相应
12、的流程图。俄罗斯方块的内容主要包括游戏开始,画背景和边框,显示分数等级和下一个方块的预览图;根据速度没隔一定时间方块自动下落,当有按键操作时,根据相应按键执行动作,每次动作前要判断是否动作可以执行。下落方块满一行时,消去该行,根据消去行数得到相应分数。分数达到一定程度,等级提升,速度加快。同时可以响应Esc 按键,提示是否退出程序。124.3 游戏界面俄罗斯方块的游戏界面包括游戏区域边框、下落方块绘制、右部计分和预览图显示等。游戏区域边框的绘制比较简单,循环中确定光标的位置输出特定字符,即可完成边框绘制。游戏区方块的绘制,循环从数据数组中依次读出数据,根据13读到的数据显示“” ,最后组成方块
13、的形状,完成方块的绘制。计分和预览图部分先画出一个矩形区域,然后控制光标在其中显示分数、等级、预览图和提示信息。4.4 生成方块本程序中生成的方块有 7 种形状,每一种方块以 shapeindex 标记,在程序运行生成方块时,调用 shapeindex=rand()%5+1;语句,确定当前要显示的是哪一个方块形状。而在实际运行中,第一次需要调用两次生成方块函数 make(),将先产生的赋给游戏当前方块,第二个赋给预览图方块。以后每次产生一个方块,把预览方块赋给当前方块,把新产生的赋给预览方块。4.5 方块变形俄罗斯方块的特点就在于通过方块的变形拼满整行来消去该行方块从而使游戏可以继续下去,很难
14、想象不能变形的俄罗斯方块是什么样子。而变形的过程就是根据当前方块形状改变方块的相对位置,这样就可以改变方块的形状了。在程序中每当按下“”键,程序判断可以变形后,根据当前方块的形状序号shapeindex 和变化形状序号 changeindex 调用相应的方块数值赋给 draw()函数,通过刷新重画就可以显示变化后的方块了。4.6 方块显示以上方块的操作都是数据层面的操作,而真正要在游戏窗口中看到数据的变化,还必须把方块不断的绘制出来。这就是 draw()函数的作用。把当前运动的方块对应节点存储在一个 4*4 数组里,变形和生成方块的过程就是更新该数组数据的过程。然后在 draw()函数里检测数
15、组的各个值,并控制光标跳到一定位置,画出“”组成方块。144.7 障碍判断障碍判断,就是在方块运动中或者变形中判断周围是否有障碍阻碍下落、移位、变形。当方块下落遇到下面有方块或者到达下边界则应停止下落并记录数据,存入背景数据数组。变形时应判断这个变形是否可以进行,如果有障碍则不能变形。例如当方块达到右边界,而若变形则会越过边界,那么这个变形的命令是不应执行的。所有这些判断都由 meet()函数进行,根据是否有障碍返回 1 或 0,再由其他函数接收执行相应操作。4.8 消行计分游戏玩家拼满一行后,程序消去满行,并计分。中当一个方块下落停止后,程序检查方块是否充满了游戏区域,如果是结束游戏。不是,
16、则判断是否构成消行条件,从下落方块的最低点依次向上检查是否可以消行,根据消去行数分数增加。分数达到一定程度,等级提升,分数暂定为每 1000 升一级。4.9 暂停退出游戏的友好性在于能考虑用户的需要,随时可以暂停/继续游戏,在不愿继续游戏时退出游戏。本程序可以在用户需要的时候响应 Esc 按键,提示是否退出游戏,如果不做选择即可暂停游戏,等待选择。程序调试经过调试和修改,程序完全实现设计要求,成功模拟了俄罗斯方块的运行过程和游戏效果,只是界面略微简陋,但已从程序层面上实现了游戏,达到了这次实训的要求和目的。程序正常生成方块,根据速度值每隔一定时间自动下落,如有操作按键按下,根据按键实现位移和变
17、形。当方块满一行后,可以消除该行,同时记录分数和等级。按下 Esc 键红色提示信息正常显示,可以响应 Y,N 键决定是否退出游戏4.10 软件使用说明打开俄罗斯方块游戏后,通过控制方向区域的“” 、 “” 、 “” 、 “”来控制, “”键代表变形转换, “” 、 “” 、 “右”均代表方向键, “Q”代表退出游戏键。若想暂停游戏,可通过“S”键,当初来询问框是,可不做选择,则可达到暂停的效果15第五章 源代码源程序代码(详细的注释) #include #include #include #include #include class Consolepublic:Console()hStdOu
18、tput = INVALID_HANDLE_VALUE;hStdError = INVALID_HANDLE_VALUE;bool Open( void )hStdOutput = GetStdHandle( STD_OUTPUT_HANDLE );hStdError = GetStdHandle( STD_ERROR_HANDLE );return INVALID_HANDLE_VALUE!=hStdOutput inline bool SetTitle( char* title ) / 设置标题return TRUE=SetConsoleTitle(title);bool RemoveCu
19、rsor( void ) / 去处光标CONSOLE_CURSOR_INFO cci;if( !GetConsoleCursorInfo( hStdOutput, cci.bVisible = false;if( !SetConsoleCursorInfo( hStdOutput, if( !GetConsoleCursorInfo( hStdError, cci.bVisible = false;if( !SetConsoleCursorInfo( hStdError, return true;bool SetWindowRect( short x, short y ) / 设置窗体尺寸SM
20、ALL_RECT wrt = 0, 0, x, y ;if( !SetConsoleWindowInfo( hStdOutput, TRUE, if( !SetConsoleWindowInfo( hStdError, TRUE, return true;16bool SetBufSize( short x, short y ) / 设置缓冲尺寸COORD coord = x, y ;if( !SetConsoleScreenBufferSize( hStdOutput, coord ) ) return false;if( !SetConsoleScreenBufferSize( hStdE
21、rror, coord ) ) return false;return true;bool GotoXY( short x, short y ) / 移动光标COORD coord = x, y ;if( !SetConsoleCursorPosition( hStdOutput, coord ) ) return false;if( !SetConsoleCursorPosition( hStdError, coord ) ) return false;return true;bool SetColor( WORD color ) / 设置前景色/背景色if( !SetConsoleText
22、Attribute( hStdOutput, color ) ) return false;if( !SetConsoleTextAttribute( hStdError, color ) ) return false;return true;bool OutputString( const char* pstr, size_t len=0 ) / 输出字符串DWORD n = 0;return TRUE=WriteConsole( hStdOutput, pstr, len?len:strlen(pstr), bool OutputStringNoMove( short x, short y
23、, const char* pstr, size_t len=0 ) / 输出字符串COORD coord = x, y ;DWORD n = 0;return TRUE=WriteConsoleOutputCharacter( hStdOutput, pstr, len?len:strlen(pstr), coord, private:HANDLE hStdOutput;HANDLE hStdError;const char bg =“ “ “17“ Begin: F8 “ “ Sleep “ Quit “ “ “ “ “ “ “ “ “ “ 0“ “ “ “ 00000“;const ch
24、ar bk7444 = 0,1,1,0 , 1,1,0,0 , 0,0,0,0 , 0,0,0,0 , 1,0,0,0 , 1,1,0,0 , 0,1,0,0 , 0,0,0,0 ,18 0,1,1,0 , 1,1,0,0 , 0,0,0,0 , 0,0,0,0 , 1,0,0,0 , 1,1,0,0 , 0,1,0,0 , 0,0,0,0 , 1,1,0,0 , 0,1,1,0 , 0,0,0,0 , 0,0,0,0 , 0,1,0,0 , 1,1,0,0 , 1,0,0,0 , 0,0,0,0 , 1,1,0,0 , 0,1,1,0 , 0,0,0,0 , 0,0,0,0 , 0,1,0,
25、0 , 1,1,0,0 , 1,0,0,0 , 0,0,0,0 , 1,1,1,0 , 1,0,0,0 , 0,0,0,0 , 0,0,0,0 , 1,0,0,0 , 1,0,0,0 , 1,1,0,0 , 0,0,0,0 , 0,0,1,0 , 1,1,1,0 , 0,0,0,0 , 0,0,0,0 , 1,1,0,0 , 0,1,0,0 , 0,1,0,0 , 0,0,0,0 , 1,1,1,0 , 0,0,1,0 , 0,0,0,0 , 0,0,0,0 , 1,1,0,0 , 1,0,0,0 , 1,0,0,0 , 0,0,0,0 , 1,0,0,0 , 1,1,1,0 , 0,0,0,
26、0 , 0,0,0,0 , 0,1,0,0 , 0,1,0,0 , 1,1,0,0 , 0,0,0,0 , 1,1,0,0 , 1,1,0,0 , 0,0,0,0 , 0,0,0,0 , 1,1,0,0 , 1,1,0,0 , 0,0,0,0 , 0,0,0,0 , 1,1,0,0 , 1,1,0,0 , 0,0,0,0 , 0,0,0,0 , 1,1,0,0 , 1,1,0,0 , 0,0,0,0 , 0,0,0,0 , 0,1,0,0 , 1,1,1,0 , 0,0,0,0 , 0,0,0,0 , 0,1,0,0 , 1,1,0,0 , 0,1,0,0 , 0,0,0,0 , 1,1,1,
27、0 , 0,1,0,0 , 0,0,0,0 , 0,0,0,0 , 1,0,0,0 , 1,1,0,0 , 1,0,0,0 , 0,0,0,0 , 1,1,1,1 , 0,0,0,0 , 0,0,0,0 , 0,0,0,0 , 1,0,0,0 , 1,0,0,0 , 1,0,0,0 , 1,0,0,0 , 1,1,1,1 , 0,0,0,0 , 0,0,0,0 , 0,0,0,0 , 1,0,0,0 , 1,0,0,0 , 1,0,0,0 , 1,0,0,0 19;const WORD COLOR_A = FOREGROUND_GREEN|FOREGROUND_RED|FOREGROUND_I
28、NTENSITY; / 运动中的颜色const WORD COLOR_B = FOREGROUND_RED; / 固定不动的颜色const WORD COLOR_C = FOREGROUND_GREEN|FOREGROUND_RED|FOREGROUND_BLUE; / 空白处的颜色int score = 0, level = 0;char data1911 = 0 ;int next = -1;int x=4, y=-2, c=-1, z=0; / x 坐标,坐标,当前方块,方向Console csl; / 定义控制台对象void DrawScoreLevel( void ) / 绘制得分c
29、har tmp6;sprintf( tmp, “%05d“, score );csl.OutputStringNoMove( 31, 19, tmp, 5 );sprintf( tmp, “%1d“, level );csl.OutputStringNoMove( 35, 15, tmp, 1 );void DrawNext( void ) / 绘制 “next 框“ 中的图形for( int i=0; i= 19 ) continue;for( int j=0; j=19 | x+j=11 | datay+ix+j=1 ) return false;return true;void Remo
30、veRow( void ) / 消行const char FULLLINE = 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 ;int linecount = 0;for( int i=0; i1; -n )datanm = datan-1m;csl.SetColor( datanm=1?COLOR_B:COLOR_C );csl.GotoXY( 2+m*2, 1+n );21csl.OutputString( “, 2 );data0m = 0;csl.OutputStringNoMove( 2+m*2, 1, “, 2 );char data1911 = 0 ;if( l
31、inecount = 0 ) return;int _score = 0;switch( linecount )case 1: _score = 100; break;case 2: _score = 300; break;case 3: _score = 700; break;case 4: _score = 1500;break;score += _score;if( score 99999 ) score = 99999;level = score/10000;DrawScoreLevel();void MoveTrans( void ) / 逆时针翻转if( IsFit( x, y,
32、c, (z+1)%4 ) )Draw( COLOR_C );z=(z+1)%4;Draw( COLOR_A );void MoveLeft( void ) / 向左移if( IsFit( x-1, y, c, z ) )Draw( COLOR_C );-x;Draw( COLOR_A );void MoveRight( void ) / 向右移22if( IsFit( x+1, y, c, z ) )Draw( COLOR_C );+x;Draw( COLOR_A );void MoveDown( void ) / 向下移if( IsFit( x, y+1, c, z ) )Draw( COL
33、OR_C );+y;Draw( COLOR_A );else if( y != -2 ) / 触底Draw( COLOR_B );for( int i=0; i4; +i )if( y+i0 ) continue;for( int j=0; j4; +j )if( bkczij = 1 )datay+ix+j = 1;RemoveRow();x=4, y=-2, c=next, z=0;next = rand()%7;DrawNext();else / 游戏结束DrawOver();23void MessageDeal( void )int cycle = 9 - level;for( ; ;
34、 )for( int i=0; icycle; +i )if( _kbhit() )switch( _getch() )case Q:case q: / 退出return;break;case S: / 暂停case s:for( ; ; )switch( _getch() )case Q:case q: / 退出return;case S:case s:goto LABLE_CONTINUE;break;LABLE_CONTINUE:break;case 0xe0: / switch( _getch() )case 0x4B: / MoveLeft();break;case 0x50: /
35、MoveDown();break;case 0x4d: / 24MoveRight();break; / 变形case 0x48:MoveTrans();default:break;break;default:break;Sleep( 55 );MoveDown();int main()csl.Open();csl.SetTitle( “俄罗斯方块 “ ); / 设置标题csl.RemoveCursor(); / 去处光标csl.SetWindowRect( 38-1, 21-1 ); / 设置窗体尺寸csl.SetBufSize( 38, 21 ); / 设置缓冲尺寸csl.OutputSt
36、ringNoMove( 0,0,bg ); / 输出背景字符srand( time(0) ); / 设置随机种子next = rand()%7;DrawNext();for( char c = (char)_getch(); c!=B c=(char)_getch() ) / 开始 Begin;x=4, y=-2, c=next, z=0;next = rand()%7;DrawNext();MessageDeal();return 0;25第六章 实验结果6.1 程序实验结果26参考文献参考文献(1). 谭浩强 C+程序设计(第 2 版) 清华大学出版社参考网址(1). (2). ( 3). 27致谢