C++俄罗斯方块课程设计.doc
商丘职业技术学院 毕业论文 C+俄罗斯方块设计论文 学生姓名:张 辰 院 系:计算机系 专 业:信息安全 学 号: 辅导教师:赵 康 2012 年 月 日 前言C+程序设计牵涉到面向对象程序设计的理论、C+语言的语法以及算法等3个方面的内容,其中每一方面都包含十分丰富的内容,都可以分别单独成论。显然在一个程序中深入、详细地介绍以上3个方面的知识是不可能的,必须把它们有机地结合起来,综合应用。不同的书对此采取不同的写法,侧重点有所不同,各有道理,也各有优缺点,适合于不同的读者。需要在教学实践中检验,取长补短,不断完善。 作者认为:要进行C+程序设计当然需要了解面向对象程序设计的有关概念,但是本课程毕竟不是一门面向对象程序设计的理论课程,在本书中不是抽象地介绍面向对象程序设计的理论,而是在介绍C+语言的特点和应用过程中自然地引出面向对象程序设计的有关概念,通过C+的编程过程理解面向对象程序设计方法。在介绍程序设计过程中,介绍有关的算法,引导读者思考怎样构造一个算法。编写程序的过程就是设计算法的过程。 要用C+编程序,最基本的要求是正确掌握和运用C+。由于C+语法复杂,内容又多,如果对它缺乏系统的了解,将难以真正应用,编出来的程序将会错误百出,编译出错,事倍功半。本书的做法是全面而系统地介绍C+的主要特点和功能,引导读者由简而繁地学会编写C+程序。有了C+编程的初步基础后,再进一步提高,掌握更多更深入的算法。这样的方法可能符合大多数学习者的情况,降低了学习难度。程序设计是一门实践性很强的课程,只靠听课和看书是学不好的。衡量学习好坏的标准不是“懂不懂”,而是“会不会干”。因此必须强调多编程,多上机实践。考虑到不同学校、不同专业、不同读者对学习C+有不同的要求。 introduction C+ programming involves the object-oriented programming theory, C+ language syntax, as well as algorithm 3, such as the content of each of these areas contains 10 sub-rich content, you can separate into theory. It is obvious that in a program in-depth and detailed information relating to the above three aspects of the knowledge is not possible, they must be organically, integrated applications. The book takes a different approach to the law, the focus is different, there is a measure of truth, and the advantages and disadvantages, and suitable for different audiences. Needs to be tested in practice in teaching and learning from each other, and continuously improved.The author believes that: for C+ programming of course need to know about object-oriented programming concepts relating to the course, after all, but this is not a facade to the object of design theory course, and in this book is not an abstract presentation of object-oriented programming theory, but in introducing C+ language features, and application process naturally leads to the concept of object programming, through C+ programming process understanding object-oriented design approach. In the process of programming, and presentation of the relevant algorithms guide the reader to think about how to construct an algorithm. Write a program that is the process of the algorithm design process.You want to use C+ programming, the most fundamental of which is properly mastered and used C+. Since C+ syntax, content and more complex, if you lack the system, and it will be difficult to actually apply to the Error 100 will be a compilation errors, and frustrating. The book's approach is comprehensive and systematic introduction C+ main features and functions, and guide the reader from simple to ensure that learning to write C+ programs. There are a C+ programming after the initial basis, to further increase, and have a more in-depth of the algorithm. In this way may be in line with most of the learners, reducing the learning curve.Programming is a practical, very strong, and can only rely on lecture courses and read a book that didn't have the. Measure the learning of the standard is not good or bad "understand it or not, but the "dry" will be. Therefore, it must be stressed more programming, more than the practice. Taking into account the different schools, different professions, different readers to learn C+ have different requirements. 目录第一章 系统概述1 . 1 课程设计的目的和要求-11 . 2 课程设计任务内容-11 . 3 关于编译软件-1第二章 详细设计说明-22 . 1 程序设计-2 2 .1 .1 主要功能设计-2 2 .1 .2 程序流程图-22 . 2 参数说明-3 2 .2 .1 类设计声明(view类)-3 2 .2 .2 类设计声明(squar类)-42 . 3 函数功能说明-5 2 .3 .1 游戏界面-5 2 .3 .2 生成方块-5 2 .3 .3 方块变形-6 2 .3 .4 方块显示-6 2 .3 .5 障碍判断-7 2 .3 .6 消行计分-7 2 .3 .7 暂停退出-72 . 4 程序调试-92 . 5 软件使用说明-9第三章 心得与体会-10附录1-11附录2-11 第一章 系统概述1.1课程设计的目的和要求 俄罗斯是家喻户晓的益智小游戏,选择这个题目一是为了将自己的所学知识加以运用,二是俄罗斯方块是我第一个接触到的游戏,它的实现方法也吸引着我。我希望通过探索实践去实现它,在这次学习中从实践和实际的项目中提高自己的编程能力。因此我选定了这个题目。C+课程所学的概念、理论和方法,按照C+程序设计的基本步骤,设计出一个适当规模的程序来实现设计课程内容中的全部功能;设计主控模块程序对给出的程序源代码要给出各部分的详细注释自己根据能力及需要添加相应功能模块,增强模拟系统功能。1.2课程设计任务内容利用Microsoft Visual C+编写一个文本窗口下的俄罗斯方块游戏。要求:(1)利用类和多文件编写。(2)能够记录游戏得分和等级。(3)可暂停/继续游戏,使玩家在不愿游戏时退出。(4)信息提示时显示颜色变化。1.3关于编译软件本程序采用Microsoft Visual C+6.0的英文版本进行编译。VisualC+6.0是Microsoft公司推出的基于Windows操作系统的可视化C+编程工具,尽管Microsoft公司推出了.NET平台的集成开发环境,但由于其良好的界面和可操作性,加上支持标准C/C+规范,但仍有相当多的编程人员使用VisualC+6.0进行应用系统的开发。关于稳定性,经测试,本程序可以在windows操作系统中稳定运行,较为稳定。 第二章 详细设计说明2.1程序设计2.1.1主要功能设计根据分析,俄罗斯方块这个程序一共要实现如下几个功能,开始游戏、游戏的暂停继续、游戏控制和退出游戏。其中游戏控制最为主要和重要,它控制着整个游戏的画面和有关数据的操作,是游戏的核心部分。暂停和退出功能做成一体,在退出的提示下不做任何操作即可实现暂停的功能。程序结构如图2.1所示。 图2.1 2.1.2 程序流程图根据分析后的程序结构图设计出相应的流程图。俄罗斯方块的内容主要包括游戏开始,画背景和边框,显示分数等级和下一个方块的预览图;根据速度没隔一定时间方块自动下落,当有按键操作时,根据相应按键执行动作,每次动作前要判断是否动作可以执行。下落方块满一行时,消去该行,根据消去行数得到相应分数。分数达到一定程度,等级提升,速度加快。同时可以响应Esc按键,提示是否退出程序。如图2.2所示。 图2.2 2.2参数说明根据程序的结构,将俄罗斯方块需要实现的功能细化为相应的类成员函数。程序有两个类,一个view类,用于背景相关操作。一个squar类,用于方块相关操作。2.2.1类设计声明(view类)class viewpublic:view();/类的缺省构造函数int getbgdata(int,int);/取得数组x,y点的数据值void scoreadd(int);/得分增加,根据消去行数void scorereset();/得分清零,用于升级后void levelup();/等级提升,当分数达到规定值后执行int gameover();/游戏结束void rowdelete();/消除满行void previewset(int (*p)4);/设置预览方块的形状数据void previewreset();/预览方块数据清零void setdata(int (*)2);/设置主游戏区数据值void datareset();/主游戏区数据清零void drawpreview();/显示预览方块private:int data2526;/主游戏区数组int preview44;/预览方块数组int rowsdelete;/每次消除行数变量int score;/得分变量int scorelevel;/升级规定值变量int level;/等级变量bool overflag;/结束标记变量void scorelevelup();/升级规定值提升;2.2.2类设计声明(squar类)class view;/先向引用声明class squarpublic:squar();/类的缺省构造函数squar(squar &);/拷贝构造函数friend void cursor(int,int);/友元函数 控制光标位置void getcursor(int &,int &);/取得位置记录坐标void make();/随机产生一个方块void getmake(int (*p)4);/取得方块数据值void draw();/显示主方块void drop(view &);/方块下落void change();/方块变形int meet(int);/判断方块周围是否有障碍void torecord(int (*)2);/传送需要记录的数据void reset();/方块数组清零int moveflag;/方块运动标记变量private:void move();/方块运动int shape44;/方块形状数据int x,y;/坐标int shapeindex;/方块形状序号int changeindex;/变形序号变量int speed;/下落速度变量;2.3函数功能说明2.3.1游戏界面俄罗斯方块的游戏界面包括游戏区域边框、下落方块绘制、右部计分和预览图显示等。游戏区域边框的绘制比较简单,循环中确定光标的位置输出特定字符,即可完成边框绘制。游戏区方块的绘制,循环从数据数组中依次读出数据,根据读到的数据显示“”,最后组成方块的形状,完成方块的绘制。计分和预览图部分先画出一个矩形区域,然后控制光标在其中显示分数、等级、预览图和提示信息。2.3.2生成方块本程序中生成的方块有六种形状,每一种方块以shapeindex标记,在程序运行生成方块时,调用shapeindex=rand()%5+1;语句,确定当前要显示的是哪一个方块形状。而在实际运行中,第一次需要调用两次生成方块函数make(),将先产生的赋给游戏当前方块,第二个赋给预览图方块。以后每次产生一个方块,把预览方块赋给当前方块,把新产生的赋给预览方块。具体如图2.3所示。 图2.32.3.3方块变形俄罗斯方块的特点就在于通过方块的变形拼满整行来消去该行方块从而使游戏可以继续下去,很难想象不能变形的俄罗斯方块是什么样子。而变形的过程就是根据当前方块形状改变方块的相对位置,这样就可以改变方块的形状了。在程序中每当按下Up键,程序判断可以变形后,根据当前方块的形状序号shapeindex和变化形状序号changeindex调用相应的方块数值赋给draw()函数,通过刷新重画就可以显示变化后的方块了。具体形状变化如图2.4所示。2.3.4方块显示 以上方块的操作都是数据层面的操作,而真正要在游戏窗口中看到数据的变化,还必须把方块不断的绘制出来。这就是draw()函数的作用。把当前运动的方块对应节点存储在一个4*4数组里,变形和生成方块的过程就是更新该数组数据的过程。然后在draw()函数里检测数组的各个值,并控制光标跳到一定位置,画出“”组成方块。具体方块对应数组数值关系如图2.5所示。 图2.42.3.5障碍判断障碍判断,就是在方块运动中或者变形中判断周围是否有障碍阻碍下落、移位、变形。当方块下落遇到下面有方块或者到达下边界则应停止下落并记录数据,存入背景数据数组。变形时应判断这个变形是否可以进行,如果有障碍则不能变形。例如当方块达到右边界,而若变形则会越过边界,那么这个变形的命令是不应执行的。所有这些判断都由meet()函数进行,根据是否有障碍返回1或0,再由其他函数接收执行相应操作。2.3.6消行计分游戏玩家拼满一行后,程序消去满行,并计分。中当一个方块下落停止后,程序检查方块是否充满了游戏区域,如果是结束游戏。不是,则判断是否构成消行条件,从下落方块的最低点依次向上检查是否可以消行,根据消去行数分数增加。分数达到一定程度,等级提升,速度加快。如图2.6所示。2.3.7暂停退出游戏的友好性在于能考虑用户的需要,随时可以暂停/继续游戏,在不愿继续游戏时退出游戏。本程序可以在用户需要的时候响应Esc按键,提示是否退出游戏,如果不做选择即可暂停游戏,等待选择。界面如图2.7所示。 图2.5 图2.6 图2.72.4 程序调试经过调试和修改,程序完全实现设计要求,成功模拟了俄罗斯方块的运行过程和游戏效果,只是界面略微简陋,但已从程序层面上实现了游戏,达到了这次实训的要求和目的。程序正常生成方块,根据速度值每隔一定时间自动下落,如有操作按键按下,根据按键实现位移和变形。当方块满一行后,可以消除该行,同时记录分数和等级。按下Esc键红色提示信息正常显示,可以响应Y,N键决定是否退出游戏。2.5 软件使用说明 打开俄罗斯方块游戏后,通过控制方向区域的“上”、“下”、“左”、“右”来控制,“上”键代表变形转换,“下”、“左”、“右”均代表方向键,而“空格”代表“沉底”,也可以通过“W”、“S”、“A”、“D”来控制方向;“esc”代表退出游戏键。若想暂停游戏,也可通过“esc”键,当初来询问框是,可不做选择,则可达到暂停的效果。 第三章 总结与体会通过这次课程设计,我收获了很多。首先把所学知识加以利用和巩固,其次在实践中遇到问题去探索和学习,更增加了新知识。在程序设计编写过程中两个类的数据交换是个比较麻烦的过程,这个类的定义过程中要用到另一个类做参数类型,而在后一个类中亦需要第一个类做参数类型,出现了互相调用的情况。编译提示未定义,只好在两个类外定义函数负责两个类函数的数据交换。实践证明达到了预期的目的,积累了经验。由于程序是用文本窗口模拟的图形,界面比较简陋,如果使用MFC用C+来实现,那么界面将会非常好,只是由于所学知识有限,只有下一步去探索了。通过这次的学习设计,我发现我还有许许多多的不足的地方,比如c+的程序设计,源代码的书写等等,刚开始我发现我的问题后,十分紧张,感觉很绝望,没有别人的帮助,自己动手设计曾经自己想都没想过的东西,虽然很兴奋,但想想自己无从下手,原来的兴奋劲一下子都没了,很忙然。但是,通过与王老师的交流,经过老师的耐心讲解,我慢慢感到希望又重生了,于是我通过上网查找资料,进图书馆查找书籍等,终于知道了俄罗斯方块游戏的设计概念,终于知道了设计的方法,于是,渐渐地我的游戏设计理念诞生了。通过几个礼拜的设计,我的游戏渐渐初见成效了,当我把回车键摁下的一刹那,我十分激动,眼前的既熟悉又陌生的游戏出现在了我的面前,看着自己设计的童年时代经常玩的游戏,我感慨万千。通过这次设计,我学会了很多东西,例如通过网络资料来寻求帮助,自己改正错误,加强了我自己的自己动手能力,对今后的学习和生活有很大的帮助,有助于以后的课程设计顺利完成。附录1 参考文献1段钢 编著 加密与解密(第三版).电子工业出版社.2009年8月2赵树升 赵韶平.Windows信息安全原理与实现.北京:清华大学出版社.2004年3杨永国.Visual C+ 6.0实用教程.北京:清华大学出版社.2004年4唐俊明.Visual C+ 6.0 编程实例与技巧.北京:高等教育出版,2002年5潘锦平.软件系统开发技术.西安:西安电子科技大学出版社, 1997年 附录2 源程序代码#include <graphics.h>#include <conio.h>#include <time.h>/ 定义常量、枚举量、结构体、全局变量/#define WIDTH 10 / 游戏区宽度#define HEIGHT 22 / 游戏区高度#define SIZE 20 / 每个游戏区单位的实际像素/ 定义操作类型enum CMD CMD_ROTATE, / 方块旋转 CMD_LEFT, CMD_RIGHT, CMD_DOWN, / 方块左、右、下移动 CMD_SINK, / 方块沉底 CMD_QUIT / 退出游戏;/ 定义绘制方块的方法enum DRAW SHOW, / 显示方块 HIDE, / 隐藏方块 FIX / 固定方块;/ 定义七种俄罗斯方块struct BLOCK WORD dir4; / 方块的四个旋转状态 COLORREF color; / 方块的颜色 g_Blocks7 = 0x0F00, 0x4444, 0x0F00, 0x4444, RED, / I 0x0660, 0x0660, 0x0660, 0x0660, BLUE, / 口 0x4460, 0x02E0, 0x0622, 0x0740, MAGENTA, / L 0x2260, 0x0E20, 0x0644, 0x0470, YELLOW, / 反L 0x0C60, 0x2640, 0x0C60, 0x2640, CYAN, / Z 0x0360, 0x4620, 0x0360, 0x4620, GREEN, / 反Z 0x4E00, 0x4C40, 0x0E40, 0x4640, BROWN; / T/ 定义当前方块、下一个方块的信息struct BLOCKINFO byte id; / 方块 ID char x, y; / 方块在游戏区中的坐标 byte dir:2; / 方向 g_CurBlock, g_NextBlock;/ 定义游戏区BYTE g_WorldWIDTHHEIGHT = 0;/ 函数声明/void Init(); / 初始化游戏void Quit(); / 退出游戏void NewGame(); / 开始新游戏void GameOver(); / 结束游戏CMD GetCmd(); / 获取控制命令void DispatchCmd(CMD _cmd); / 分发控制命令void NewBlock(); / 生成新的方块bool CheckBlock(BLOCKINFO _block); / 检测指定方块是否可以放下void DrawBlock(BLOCKINFO _block, DRAW _draw = SHOW); / 画方块void OnRotate(); / 旋转方块void OnLeft(); / 左移方块void OnRight(); / 右移方块void OnDown(); / 下移方块void OnSink(); / 沉底方块/ 函数定义/ 主函数void main() Init(); CMD c; while(true) c = GetCmd(); DispatchCmd(c); / 按退出时,显示对话框咨询用户是否退出 if (c = CMD_QUIT) HWND wnd = GetHWnd(); if (MessageBox(wnd, _T("您要退出游戏吗?"), _T("提醒"), MB_OKCANCEL | MB_ICONQUESTION) = IDOK) Quit(); / 初始化游戏void Init() initgraph(640, 480); srand(unsigned)time(NULL);/ 显示操作说明 setfont(14, 0, _T("宋体"); outtextxy(20, 330, _T("操作说明"); outtextxy(20, 350, _T("上:旋转"); outtextxy(20, 370, _T("左:左移"); outtextxy(20, 390, _T("右:右移"); outtextxy(20, 410, _T("下:下移"); outtextxy(20, 430, _T("空格:沉底"); outtextxy(20, 450, _T("ESC:退出"); / 设置坐标原点 setorigin(220, 20);/ 绘制游戏区边界 rectangle(-1, -1, WIDTH * SIZE, HEIGHT * SIZE); rectangle(WIDTH + 1) * SIZE - 1, -1, (WIDTH + 5) * SIZE, 4 * SIZE); / 开始新游戏 NewGame();/ 退出游戏void Quit() closegraph(); exit(0);/ 开始新游戏void NewGame() / 清空游戏区 setfillstyle(BLACK); bar(0, 0, WIDTH * SIZE - 1, HEIGHT * SIZE - 1); ZeroMemory(g_World, WIDTH * HEIGHT);/ 生成下一个方块 g_NextBlock.id = rand() % 7; g_NextBlock.dir = rand() % 4; g_NextBlock.x = WIDTH + 1; g_NextBlock.y = HEIGHT - 1;/ 获取新方块 NewBlock();/ 结束游戏void GameOver() HWND wnd = GetHWnd(); if (MessageBox(wnd, _T("游戏结束。n您想重新来一局吗?"), _T("游戏结束"), MB_YESNO | MB_ICONQUESTION) = IDYES) NewGame(); else Quit();/ 获取控制命令DWORD m_oldtime;CMD GetCmd() / 获取控制值 while(true) / 如果超时,自动下落一格 DWORD newtime = GetTickCount(); if (newtime - m_oldtime >= 500) m_oldtime = newtime; return CMD_DOWN; / 如果有按键,返回按键对应的功能 if (kbhit() switch(getch() case 'w': case 'W': return CMD_ROTATE; case 'a': case 'A': return CMD_LEFT; case 'd': case 'D': return CMD_RIGHT; case 's': case 'S': return CMD_DOWN; case 27: return CMD_QUIT; case ' ': return CMD_SINK; case 0: case 0xE0: switch(getch() case 72: return CMD_ROTATE; case 75: return CMD_LEFT; case 77: return CMD_RIGHT; case 80: return CMD_DOWN; / 延时 (降低 CPU 占用率) Sleep(20); / 分发控制命令void DispatchCmd(CMD _cmd) switch(_cmd) case CMD_