俄罗斯方块设计报告书
- 格式:doc
- 大小:291.80 KB
- 文档页数:16
C课程设计报告设计人:*** ***日期:2011-11-12指导教师:**设计题目:俄罗斯方块游戏目录目录 (1)一、设计任务 (3)二、设计目的 (3)三、功能描述 (4)1、游戏方块预览功能 (4)2、游戏方块控制功能 (4)3、游戏显示更新功能 (4)4、游戏速度分数更新功能 (5)5、游戏帮助功能 (5)四、总体设计 (5)1、功能模块设计 (6)(1)游戏执行主流程 (6)(2)游戏方块预览 (6)(3)游戏方块控制 (6)(4)游戏显示更新 (8)(5)游戏速度分数更新 (8)(6)游戏帮助 (8)2、数据结构设计: (9)(1)游戏底板BOARD结构体 (9)(2)游戏方块SHAPE结构体, (9)(3)SHAPE结构数组 (9)3、函数功能描述 (12)(1)newtimer() (12)(2)SetTimer() (12)(3)KillTimer() (12)(4)initialize() (12)(5)DelFullRow() (12)(6)setFullRow() (12)(7)MkNextBox() (12)(8)EraseBox() (13)(9)show_box() (13)(10)MoveAble() (13)(11)主函数main() (13)五、程序实现 (13)1、源代码分析 (13)(1)程序预处理 (13)(2)主函数 (17)(3)初始化界面 (21)(4)时钟中断处理 (23)(5)成绩、速度及帮助的显示 (24)(6)满行处理 (26)(7)游戏方块的显示和清除 (29)(8)游戏方块操作判断处理 (34)2、运行结果及界面介绍 (39)(1)游戏初始状态 (39)(2)游戏进行状态 (39)八、设计心得 (40)九、小组合作分工情况 (41)十、附录 (42)1、程序完整源代码 (42)2、截图 (57)一、设计任务1. 随机产生经典俄罗斯方块图形2. 设置难度级别,不同级别速度不同3. 方向键实现下落图形的左移、右移、加速下落、变形等基本操作4. 正确判断游戏结束5. 对游戏成绩进行记分二、设计目的本程序旨在训练学生的基本编程能力和游戏开发的技巧,熟悉C语言图形模式下的编程。
C语言课程设计报告I、俄罗斯方块游戏需要解决的问题包括:⑴、随机产生方块并自动下移⑵、用Esc键退出游戏⑶、用键变体⑷、用键和键左右移动方块⑸、用空格键使游戏暂停⑹、能正确判断满行并消行、计分、定级别⑺、设定游戏为不同级别,级别越高难度越大II、俄罗斯方块游戏需要设计的功能函数包括:⑴、声明俄罗斯方块的结构体⑵、函数原型声明⑶、制作游戏窗口2、游戏方块控制功能;通过各种条件的判断,实现对游戏方块的左移、右移、自由下落、旋转功能,以及行满消除行的功能;3、游戏数据显示功能;在游戏玩家进行游戏过程中,需要按照一定的游戏规则给玩家计算游戏分数;例如,消除一行加100分,游戏分数达到一定数量之后,需要给游戏者进行等级的上升,每上升一个等级,游戏方块的下落速度将加快,游戏的难度将增加;以上游戏数据均会在游戏界面右侧显示以提示玩家;4、游戏信息提示功能;玩家进入游戏后,将有对本游戏如何操作的友情提示;5、游戏结束退出功能;判断游戏结束条件,通过Esc键进行退出;是关闭游戏界面返回程序游戏执行主流程图2、界面设计分为左右两个部分:左边为游戏面板右边有三部分:游戏数据提示框、下一个方块提示框和功能提示框3、重要功能函数设计1、声明俄罗斯方块的结构体struct Tetris{int x; //中心方块的x轴坐标int y; //中心方块的y轴坐标int flag; //标记方块类型的序号int next; //下一个俄罗斯方块类型的序号int speed; //俄罗斯方块移动的速度//开始游戏void start_game;3、制作游戏窗口void make_frame{HANDLE hOut = GetStdHandleSTD_OUTPUT_HANDLE; //定义显示器句柄变量gotoxyhOut,FrameX+Frame_width-5,FrameY-2; //打印游戏名称printf"俄罗斯方块";gotoxyhOut,FrameX+2Frame_width+3,FrameY+7; //打印选择菜单printf"下一个方块:";gotoxyhOut,FrameX+2Frame_width+3,FrameY+13;printf"";gotoxyhOut,FrameX+2Frame_width+3,FrameY+17;printf"↑键:变体";gotoxyhOut,FrameX+2Frame_width+3,FrameY+19;printf"空格:暂停游戏";gotoxyhOut,FrameX+2Frame_width+3,FrameY+15;printf"Esc :退出游戏";gotoxyhOut,FrameX,FrameY; //打印框角并记住该处已有图案printf"║"; //打印左竖框aFrameXFrameY+i=2; //记住左竖框有图案}fori=1;i<Frame_height;i++{gotoxyhOut,FrameX+2Frame_width-2,FrameY+i;printf"║"; //打印右竖框aFrameX+2Frame_width-2FrameY+i=2; //记住右竖框有图案}}4、制作俄罗斯方块void make_tetrisstruct Tetris tetris{atetris->xtetris->y=b0; //中心方块位置的图形状态:1-有,0-无switchtetris->flag //共6大类,19种类型{case 1: //田字方块{atetris->xtetris->y-1=b1;}case 5: //T字顺时针转90度方块{atetris->xtetris->y-1=b1;atetris->xtetris->y+1=b2;atetris->x-2tetris->y=b3;break;}case 6: //T字顺时针转180度方块{atetris->x-2tetris->y=b2;atetris->x+2tetris->y=b3;break;}case 7: //T字顺时针转270度方块{atetris->xtetris->y-1=b1;atetris->xtetris->y+1=b2;atetris->x+2tetris->y=b3;break;{atetris->xtetris->y+1=b1;atetris->x+2tetris->y-1=b2;atetris->x+2tetris->y=b3;break;}case 12: //7字方块{atetris->xtetris->y-1=b1;atetris->xtetris->y+1=b2;break;}case 13: //7字顺时针转90度方块{atetris->x-2tetris->y=b1;atetris->x-2tetris->y+1=b2;atetris->x+2tetris->y=b3;break;}case 14: //7字顺时针转180度方块atetris->x-2tetris->y-1=b2;atetris->x+2tetris->y=b3;break;}case 18: //倒7字顺时针转180度方块{atetris->xtetris->y-1=b1;atetris->xtetris->y+1=b2;atetris->x-2tetris->y+1=b3;break;}case 19: //倒7字顺时针转270度方块{atetris->x-2tetris->y=b1;atetris->x+2tetris->y+1=b2;atetris->x+2tetris->y=b3;break;}}tetris->flag==6 && atetris->xtetris->y-1==0 &&atetris->x-2tetris->y==0 && atetris->x+2tetris->y==0 || tetris->flag==7 && atetris->xtetris->y-1==0 &&atetris->xtetris->y+1==0 && atetris->x+2tetris->y==0 || tetris->flag==8 && atetris->xtetris->y+1==0 &&atetris->x-2tetris->y==0 && atetris->x+2tetris->y+1==0 || tetris->flag==9 && atetris->xtetris->y-1==0 &&atetris->x-2tetris->y==0 && atetris->x-2tetris->y+1==0 || tetris->flag==10 && atetris->xtetris->y-1==0 &&atetris->x-2tetris->y-1==0 && atetris->x+2tetris->y==0 ||tetris->flag==11 && atetris->xtetris->y+1==0 &&atetris->x+2tetris->y-1==0 && atetris->x+2tetris->y==0 || tetris->flag==12 && atetris->xtetris->y-1==0 &&atetris->xtetris->y+1==0 && atetris->x-2tetris->y-1==0 || tetris->flag==13 && atetris->x-2tetris->y==0 &&atetris->x-2tetris->y+1==0 && atetris->x+2tetris->y==0 || tetris->flag==14 && atetris->xtetris->y-1==0 &&atetris->xtetris->y+1==0 && atetris->x+2tetris->y+1==0 || tetris->flag==15 && atetris->x-2tetris->y==0 &&atetris->x+2tetris->y-1==0 && atetris->x+2tetris->y==0 || tetris->flag==16 && atetris->xtetris->y+1==0 &&tetris->flag = rand%19+1; //记住第一个方块的序号}tetris->next = rand%19+1; //记住下一个方块的序号}7、打印俄罗斯方块void print_tetrisHANDLE hOut,struct Tetris tetris{fori=0;i<4;i++bi=1; //数组b4的每个元素的值都为1 }make_tetristetris; //制作俄罗斯方块for i=tetris->x-2; i<=tetris->x+4; i+=2{forj=tetris->y-2;j<=tetris->y+1;j++{if aij==1 && j>FrameY{gotoxyhOut,i,j;{forj=tetris->y-2;j<=tetris->y+1;j++{if aij==0 && j>FrameY{gotoxyhOut,i,j;printf" "; //清除方块}}}9、判断是否满行并删除满行的俄罗斯方块void del_fullHANDLE hOut,struct Tetris tetris{ //当某行有Frame_width-2个方块时,则满行int k,del_count=0; //分别用于记录某行方块的个数和删除方块的行数的变量forj=FrameY+Frame_height-1;j>=FrameY+1;j--{k=0;printf"□";}}}j++; //方块下移后,重新判断删除行是否满行del_count++; //记录删除方块的行数}}}}tetris->score+=100del_count; //每删除一行,得100分if del_count>0 && tetris->score%1000==0 || tetris->score/1000>tetris->level-1 { //如果得1000分即累计删除10行,速度加快20ms并升一级tetris->speed-=20;tetris->level++;}}10、开始游戏Sleeptetris->speed; //延缓时间clear_tetrishOut,tetris; //清除痕迹temp1=tetris->x; //记住中心方块横坐标的值temp2=tetris->flag; //记住当前俄罗斯方块序号ifkbhit{ //判断是否有键盘输入,有则用ch↓接收ch=getch;ifch==75 //按←键则向左动,中心横坐标减2{tetris->x-=2;ifch==77 //按→键则向右动,中心横坐标加2{tetris->x+=2;}ifch==72 //按↑键则变体即当前方块顺时针转90度{if tetris->flag>=2 && tetris->flag<=3{tetris->flag++;tetris->flag%=2;tetris->flag%=4;tetris->flag+=16;}}ifch==32 //按空格键,暂停{print_tetrishOut,tetris;while1{ifkbhit //再按空格键,继续游戏ch=getch;ifch==32{goto label;}}}}ifif_moveabletetris==0 //如果不可动,上面操作无效{ifj==0{system"cls";getch;break;}//清除下一个俄罗斯方块的图形右边窗口tetris->flag = tetris->next;tetris->x=FrameX+2Frame_width+6;tetris->y=FrameY+10;clear_tetrishOut,tetris; } }4、函数设计流程 、进入俄罗斯方块程序定义全局变量 定义主函数 void main 声明俄罗斯方块的结构体 struct Tetris 函数原型声明 //制作游戏窗口make_frame; //开始游戏start_game; 制作俄罗斯方块判断是否可动。
V isual Basic 程序设计报告——俄罗斯方块游戏(四星)学院:能源与动力学院专业:新能源科学与工程学号:912108670129 姓名:汤海山㈠前言:经过一个学期的学习,已经基本掌握了Visual Basic的各种控件使用,所以这个学期设计了俄罗斯方块这个小游戏,从而检查自己半年多来的学习情况。
这款小游戏设计风格简单,操作也非常简单,设计时主要包括对各种控件的合理使用,对多模块设计的掌握,还有就是对绘图方法的利用,等等。
设计时感觉确实非常有难度,也因本人实力实在有限,故只能设计一个极其简单的俄罗斯方块,希望大家喜欢。
㈡功能:首先,进入程序时,会弹出游戏界面,点击开始,就可进行游戏。
开始游戏后,你可点击“暂停”来暂停游戏,再次点击为继续。
在游戏过程中,你可点击“文件”其中有“选项”,“关于”,还有“退出”。
选项里面有对游戏功能键的设置——两种方案。
点击“关于”时,会跳出另一个窗体,是此程序的一些相关信息。
“退出”顾名思义是退出游戏。
然后就是在“下一个”框架中会显示下一个方块的形状,以便游戏者更好的发挥自己的水平。
在“最高分”框架中显示的是这次游戏过程中的最高分,以鼓励游戏者不断刷新纪录哦!在游戏过程中,方块下落的速度会随着得分的不断增加而增加,等于是增加了游戏的难度。
亮点:其中有Windowedia player控件,它是为背景音乐服务的,当进入游戏界面时,背景音乐会自动播放,当你点击Windows media player控件,可以暂停和再次播放背景音乐。
音乐可以自己选择,保证用户在游戏过程中也能享受音乐的美妙熏陶。
(此为游戏界面截图)㈢俄罗斯方块中的详细设计:1.frmmain窗体:此窗体为游戏界面窗体,是程序设计中最主要的窗体,因为该窗体控件数目较多,故在方格上运用了绘图方法,但绘图方法在上个学期没有学到,所以在编程过程中自学了绘图方法,并应用了较多的Line方法,达到了绘制方格的目的。
俄罗斯方块游戏设计报告游戏名称:俄罗斯方块设计理念:游戏玩法:1.游戏开始后,屏幕上会出现一个空白的游戏区域,玩家可以通过左右箭头键控制方块的左右移动,通过下箭头键加速方块的下落。
2.当方块下落到底部或者与其他方块重叠时,方块会停止下落。
3.玩家可以通过上箭头键旋转方块的形状,使其更好地适应下落的位置。
4.当一行或多行方块完全填满时,该行方块会被消除并得分。
5.游戏结束条件:当放置的方块堆积过高,触碰到游戏区域的上边界时,游戏结束。
游戏功能设计:1.游戏计分系统:根据消除的行数,给予不同的得分。
消除的行数越多,得分越高。
2.难度递增系统:随着游戏的进行,方块的下落速度会逐渐增加,提升游戏难度。
3.存档和读档功能:游戏进行中,玩家可以随时存档,下一次进入游戏时可以选择读取存档继续游戏,方便玩家在合适的时间继续游戏。
4.多种游戏模式:游戏提供经典模式和挑战模式,经典模式可供玩家自由操作和无时间限制地进行游戏,挑战模式则有时间限制,为玩家增加一定的游戏压力。
5.游戏音效设计:游戏中方块落地、消除和游戏结束等操作都会有对应的音效,增强游戏的可玩性和趣味性。
界面设计:1.游戏主界面:展示游戏的名称、开始游戏、读取存档、退出游戏等功能按钮,并展示最高得分和当前得分。
2.游戏界面:展示游戏区域,包括方块的下落区域和已经堆积的方块堆,同时显示下一个方块的形状。
3.游戏结束界面:展示当前得分和最高得分,并显示重新开始和返回主界面的按钮。
技术实现:1. 在游戏的开发过程中,可以使用HTML5、CSS和JavaScript技术进行实现,其中HTML5负责搭建游戏界面,CSS负责界面的样式美化,JavaScript负责游戏逻辑的编写与处理。
2. 使用Canvas绘制游戏界面,使用Dom操作游戏的按钮和文字信息。
3.利用各种事件监听,如键盘事件监听、定时器等,来实现游戏操作的响应和游戏逻辑的控制。
4.对游戏数据进行合理的存储和管理,使用本地存储技术实现游戏的存档和读档功能。
俄罗斯方块游戏设计报告【引言】【设计理念】1.目标:游戏的目标是通过操作和放置不同形状的方块,使它们在游戏区域中连成一行或多行,以获得分数。
2.简单易上手:俄罗斯方块游戏以其简单易上手的特点而受到玩家的喜爱。
设计时应注意保持游戏的简洁性,使玩家能够快速上手并迅速融入游戏。
3.挑战性:尽管游戏规则简单,但由于方块的随机性和加速度的增加,游戏也具备一定的挑战性。
设计时要注意保持游戏的平衡,使玩家能够享受游戏的挑战。
【游戏要点】1.游戏区域:游戏区域是一个矩形网格,由多个方格组成。
玩家需要在游戏区域内操作和放置方块。
2.方块种类:方块由四个小方块组成,每个小方块可以是不同的颜色。
常见的方块种类有:直线、方块、L形、反L形、Z形和反Z形。
3.方块操作:玩家可以通过键盘或触摸屏操作方块的移动和旋转。
方块可以向左、向右、向下移动,以及顺时针或逆时针旋转。
4.方块放置:当玩家将一个方块放置在游戏区域中时,方块将固定在该位置并不能再进行移动。
5.消除行:当一行或多行的方块完全填满时,这些方块将会被消除,玩家将得到分数。
消除多行的同时会获得更高的积分。
6.加速度:随着时间的推移,方块的下降速度将会逐渐增加,增加游戏的难度。
7.游戏结束:当游戏区域中的方块堆叠到达顶部时,游戏结束。
【游戏设计】1.游戏界面设计:a.主菜单:包含开始游戏、设置、退出等选项。
b.游戏区域:显示游戏的主要内容,包括方块、分数、下一个方块等。
c.分数和排行榜:显示玩家的最高分数和排名信息。
d.设置界面:包含音效、游戏速度等设置选项。
e.游戏结束界面:显示玩家的得分和排名,并提供重新开始和返回主菜单的选项。
2.游戏逻辑和算法设计:a.方块生成:通过随机算法生成各种类型的方块,并在游戏区域中显示当前方块和下一个方块。
b.方块移动:根据玩家的操作,判断方块能否向左、向右、向下或旋转,并更新方块的位置和状态。
c.方块回合:当方块不能再向下移动时,方块将固定在游戏区域中,并进行消行检测和分数计算。
软件体系结构设计课程设计报告课程设计题目:俄罗斯方块小游戏专业名称:软件工程2017 年6月30日一、简介1.1俄罗斯方块游戏简介《俄罗斯方块》(Tetris,俄文:Тетрис)是一款由俄罗斯人阿列克谢·帕基特诺夫于1984年6月发明的休闲游戏。
由小方块组成的不同形状的板块陆续从屏幕上方落下来,玩家通过调整板块的位置和方向,使它们在屏幕底部拼出完整的一条或几条。
这些完整的横条会随即消失,给新落下来的板块腾出空间,与此同时,玩家得到分数奖励。
没有被消除掉的方块不断堆积起来,一旦堆到屏幕顶端,玩家便告输,游戏结束。
1.2 俄罗斯方块游戏规则1.游戏主画面在一个用于摆放方块的面板上2.(1)一组由4个小型正方形组成的规则图形(即方块)共有7种形状,分别为一字形、田字形、7字形、反7形、Z形、反Z形、T形。
(2)一字形:一次最多消除四层田字形:消除一至二层7字形:最多消除三层,或消除二层反7形:最多消除三层,或消除二层Z形:最多二层,容易造成孔洞反Z形:最多二层,容易造成孔洞T形:最多二层3. 方块从区域上方开始下落,玩者可以按指定按钮左右移动方块、逆时针旋转方块,以及让方块加速落下。
4. 方块移到区域最下方或是着地到其他方块上无法移动时,就会固定在该处,而新的方块出现在区域上方开始落下。
5. 当区域中某一行横向格子全部由方块填满,则该列会消失,玩家得分。
6. 当固定的方块累积堆到一定层数(设计游戏时设置)时,游戏结束。
7. 游戏会提示下一个要落下的方块形状。
二、需求分析与游戏设计2.2 需求分析2.2.1 游戏界面需求良好的用户界面设计。
本游戏主要有三个界面,一是主游戏区的面板,显示变化和下落的方块;二是用于放置按钮以及显现游戏信息的面板,三是双人对战时用以显示对方游戏信息的面板。
2.2.2 方块控制需求方块下落时,可通过特定按钮对该方块进行翻转、加速,以及向左、向右移动等操作。
2.2.3 图形显示需求随机给出不同的形状(一字形、田字形、7字形、反7形、Z形、反Z形、T形),下落填充给定的区域,填满一行则消掉记分,方块累积到一定层数无法再消去行时游戏结束。
课程设计报告题目:俄罗斯方块设计设计者:* *专业班级:* *学号:* *指导教师:* *所属系部:* ** *年* *月* *日、目录目录 .................... 错误!未定义书签。
一.设计的目的和要求..... 错误!未定义书签。
二.设计内容............. 错误!未定义书签。
三.设计任务............. 错误!未定义书签。
四.游戏基本规则......... 错误!未定义书签。
五.总体设计............. 错误!未定义书签。
六.详细设计与程序实现... 错误!未定义书签。
七.主要处理流程.......... 错误!未定义书签。
八.游戏设计源程序........ 错误!未定义书签。
九.截图 ................. 错误!未定义书签。
十心得体会.............. 错误!未定义书签。
十一参考文献............ 错误!未定义书签。
一.设计的目的和要求加深对《C语言》课程所学知识的理解,进一步巩固C语言语法规则。
学会编制结构清晰、风格良好、数据结构适当的C语言程序,从而具备解决综合性实际问题的能力。
二.设计内容在熟练掌握C语言的基本知识:数据类型(整形、实型、字符型、指针、数组、结构等);运算类型(算术运算、逻辑运算、自增自减运算、赋值运算等);程序结构(顺序结构、判断选择结构、循环结构);大程序的功能分解方法(即函数的使用)等。
进一步掌握各种函数的应用,包括时间函数、绘图函数,以及文件的读写操作等。
三.设计任务1.游戏欢迎界面。
2.游戏执行功能,包括计算得分。
3.游戏结束界面。
四.游戏基本规则游戏共由7种不同形状的方块组成,游戏开始以后随机产生一个方块由屏幕的顶端开始向下落下,落到低端则固定到桌面,并开始下一个方块。
在游戏窗口的左边作为游戏的桌面,用宽度10和高度20的表格表示。
游戏桌面的右边靠上显示得分,最下边显示游戏帮助。
1.系统概述 (1)2.设计说明书 (4)3.系统操作界面 (6)4.源程序编码 (7)5.测试计划 (36)6.改进意见 (39)7 •课程设计心得体会 (40)8.参考书籍、资料 (40)系统概述1.1现状分析在个人电脑日益普及的今天,一些有趣的桌面游戏已经成为人们在使用计算机进行工作或学习之余休闲娱乐的首选,而俄罗斯方块游戏是人们最熟悉的小游戏之一,它以其趣味性强,易上手等诸多特点得到了大众的认可,因此开发此游戏软件可满足人们的一些娱乐的需求。
此俄罗斯方块游戏可以为用户提供一个可在普通个人电脑上运行的,界面美观的,易于控制的俄罗斯方块游戏。
1.2项目要求俄罗斯方块游戏是一款适合大众的游戏软件,它适合不同年龄的人玩。
本软件要实现的功能如下:(1)游戏区:玩家可以在游戏区中堆积方块,并能够在游戏过程中随时了解得分情况。
(2)游戏控制:玩家可以通过游戏控制功能来选择开始新的一局游戏,暂停或退出游戏。
(3)级别设置:玩家可以根据自己的需要自行设定游戏的开始级别,级别越高,游戏的速度越快,难度越大。
(4)1.3 系统功能模块示意图项目开发计划书项目开发计划书设计说明1.1游戏区模块1.2控制区模块1.3系统流程图(2)游戏控制模块(开始,暂停继续,提高等级,降低等级, 停止,新游戏,帮助)系统操作界面游戏打开界面回鬲矗慕歹斯方块苦戏□Array游戏进行中界面自犠罗斯方块却E源代码编码#i nclude <stdio.h>#in elude <bios.h>#in elude <dos.h>#in elude vgraphics.h> #i nclude <stri ng.h>#i nclude <stdlib.h>#define true 1#define false 0#defi ne BoardWidth 12#defi ne BoardHeight 23 #define _INNER_HELPERinner helper method */ /*Scan Codes Define*/en umKEYCODESK_ESC =0x011b.K_UP =0x4800, /* upward arrow */K_LEFT =0x4b00,K_DOWN =0x5000,K_RIGHT =0x4d00,K_SPACE =0x3920,K_P =0x1970};/* the data structure of the block */ typedef struct tagBlock {char c[4][4]; /* cell fill info array, 0-empty, 1-filled */ int x; /* block position cx [ 0,BoardWidht -1] */ int y; /* block position cy [-4,BoardHeight-1] */ char color; /* block color */char size; /* block max size in w idth or height */char name; /* block name (the block's shape) */} Block;/* game's global info */int FrameTime= 1300;int CellSize= 18;int BoardLeft= 30;int BoardTop= 30;/* next block grid */int NBBoardLeft= 300;int NBBoardTop= 30;int NBCellSize= 10;/* score board position */int ScoreBoardLeft= 300;int ScoreBoardTop=100;int ScoreBoardWidth=200;int ScoreBoardHeight=35;int ScoreColor=LIGHTCYAN;/* infor text postion */int InfoLeft=300;int InfoTop=200;int InfoColor=YELLOW;int BorderColor=DARKGRAY;int BkGndColor=BLACK;int GameRunning=true;int TopLine=BoardHeight-1; /* top empty line */int TotalScore=100;char info_score[20];char info_help[255];char info_common[255];/* our board, Board[x][y][0]-isFilled, Board[x][y][1]-fillColor*/unsigned char Board[BoardWidth][BoardHeight][2];char BufferCells[4][4]; /* used to judge if can rotate/* current moving block */ next Blockto appear */ /* function list */int GetKeyCode();int CanMove(int dx,int dy);int CanRotate();int RotateBlock(Block *block);int MoveBlock(Block *block,int dx,int dy); void DrawBlock(Block *block,int,int,int); void EraseBlock(Block *block,int,int,int); void DisplayScore();void DisplayInfo(char* text);void GenerateBlock(Block *block);void NextBlock();void InitGame();int PauseGame();void QuitGame();/*Get Key Code */int _INNER_HELPEGRetKeyCode(){int key=0;if(bioskey(1)){key=bioskey(0);}return key;}/* display text! */void _INNER_HELPEDRisplayInfo(char *text) {setcolor(BkGndColor);outtextxy(InfoLeft,InfoTop,info_common);strcpy(info_common,text); setcolor(InfoColor);outtextxy(InfoLeft,InfoTop,info_common);}/* create a new block by key number,* the block anchor to the top-left corner of 4*4 cells block */Block curBlock; Block nextBlock; /*_INNER_HELPEGRenerateBlock(Block *block)int key=(random(13)*random(17)+random(1000)+random(3000))%7;block->size=3;/* because most blocks' size=3 */ memset(block->c,0,16); switch(key){case 0:block->name='T'; block->color=RED; block->c[1][0]=1;block->c[1][1]=1, block->c[2][1]=1; block->c[1][2]=1; break; case 1:block->name='L'; block->color=YELLOW; block->c[1][0]=1; block->c[1][1]=1;block->c[1][2]=1, block->c[2][2]=1; break; case 2:block->name='J';block->color=LIGHTGRAY; block->c[1][0]=1; block->c[1][1]=1;block->c[1][2]=1, block->c[0][2]=1; break; case 3:block->name='z'; block->color=CYAN;block->c[0][0]=1, block->c[1][0]=1; block->c[1][1]=1, block->c[2][1]=1; break; case 4:block->name='5';block->color=LIGHTBLUE;block->c[1][0]=1, block->c[2][0]=1; block->c[0][1]=1, block->c[1][1]=1; break; case 5:block->name='o'; block->color=BLUE;*/void {block->size=2;block->c[0][0]=1, block->c[1][0]=1;block->c[0][1]=1, block->c[1][1]=1; break;case 6: block->name='I'; block->color=GREEN;block->size=4; block->c[1][0]=1; block->c[1][1]=1;block->c[1][2]=1; block->c[1][3]=1; break;}}/* get next block! */ void NextBlock(){/* copy the nextBlock to curBlock */curBlock.size=nextBlock.size; curBlock.color=nextBlock.color;curBlock.x=(BoardWidth-4)/2; curBlock.y=-curBlock.size;memcpy(curBlock.c,nextBlock.c,16);/* generate nextBlock and show it */EraseBlock(&nextBlock,NBBoardLeft,NBBoardTop,NBCellSize);GenerateBlock(&nextBlock);nextBlock.x=1,nextBlock.y=0;DrawBlock(&nextBlock,NBBoardLeft,NBBoardTop,NBCellSize);}/* rotate the block, update the block struct data */int _INNER_HELPE R otateCells(char c[4][4],char { char temp,i,j;switch(blockSize){case 3:temp=c[0][0];c[0][0]=c[2][0], c[2][0]=c[2][2], c[0][2]=temp;temp=c[0][1];c[0][1]=c[1][0], c[1][0]=c[2][1],blockSize)c[2][2]=c[0][2],c[2][1]=c[1][2break;/* judge if the block can move toward the direction */ int CanMove(int dx,int dy){int i,j,tempX,tempY;for(i=0;i<curBlock.size;i++){for(j=0;j<curBlock.size;j++){if(curBlock.c[i][j]){/* cannot move leftward or rightward */ tempX = curBlock.x + i + dx;if(tempX<0 || tempX>(BoardWidth-1)) return false;/* make sure x is valid! *//* cannot move downward */tempY = curBlock.y + j + dy; if(tempY>(BoardHeight-1)) onlychecked lower bound, maybe negative!!!! /* the cell already filled,if(tempY>=0 && Board[tempX][tempY][0]) returnfalse;}}}return true;}/* judge if the block can rotate */ int CanRotate(){int i,j,tempX,tempY; /* update buffer */memcpy(BufferCells, curBlock.c, 16); RotateCells(BufferCells,curBlock.size); for(i=0;i<curBlock.size;i++){for(j=0;j<curBlock.size;j++)c[1][2]=temp ; case 4: /* only 'I'c[1][0]=1-c[1][0], c[0][1]=1-c[0][1], c[3][1];break;}}block arived here! */ c[1][2]=1-c[1][2], c[2][1]=1-c[1][3]=1-c[1][3];c[3][1]=1- return false; /* y is*/ we must check Y's upper bound before check cell*/{if(BufferCells[i][j]){tempX=curBlock.x+i;tempY=curBlock.y+j;if(tempX<0 || tempX>(BoardWidth-1))return false;if(tempY>(BoardHeight-1))return false;if(tempY>=0 && Board[tempX][tempY][0])return false;}}}return true;}/* draw the block */void _INNER_HELPERDrawBlock(Block *block,int bdLeft,intbdTop,int cellSize){int i,j;setfillstyle(SOLID_FILL,block->color);for(i=0;i<block->size;i++){for(j=0;j<block->size;j++){if(block->c[i][j] && (block->y+j)>=0){floodfill(bdLeft+cellSize*(i+block->x)+cellSize/2,bdTop+cellSize*(j+block->y)+cellSize/2,BorderColor);}}}}/* Rotate the block, if success, return true */int RotateBlock(Block *block){char temp,i,j;int b_success;if(block->size==2)return true;if(( b_success=CanRotate())){EraseBlock(block,BoardLeft,BoardTop,CellSize);memcpy(curBlock.c,BufferCells,16);DrawBlock(block,BoardLeft,BoardTop,CellSize);}return b_success;}/* erase a block, only fill the filled cell with background color */ void_INNER_HELPEREraseBlock(Block *block,int bdLeft,int bdTop,int cellSize){int i,j;setfillstyle(SOLID_FILL,BkGndColor);for(i=0;i<block->size;i++){for(j=0;j<block->size;j++){if(block->c[i][j] && (block->y+j>=0)){floodfill(bdLeft+cellSize*(i+block->x)+cellSize/2,bdTop+cellSize*(j+block->y)+cellSize/2, BorderColor);}}}}/* move by the direction if can, donothing if cannot* return value: true - success, false - cannot move toward this direction */ int MoveBlock(Block *block,int dx,int dy) {int b_canmove=CanMove(dx,dy); if(b_canmove){EraseBlock(block,BoardLeft,BoardTop,CellSize); curBlock.x+=dx; curBlock.y+=dy;DrawBlock(block,BoardLeft,BoardTop,CellSize);}return b_canmove;}/* drop the block to the bottom! */ int DropBlock(Block *block){EraseBlock(block,BoardLeft,BoardTop,CellSize); while(CanMove(0,1)){curBlock.y++;}DrawBlock(block,BoardLeft,BoardTop,CellSize);return 0;/* return value is assign to the block's alive */}/* init the graphics mode, draw the board grid */ void InitGame(){int i,j,gdriver=DETECT,gmode; struct time sysTime; /* draw board cells */memset(Board,0,BoardWidth*BoardHeight*2); memset(nextBlock.c,0,16); strcpy(info_help,"P: Pause Game. --by hoodlum1980"); initgraph(&gdriver,&gmode,"");setcolor(BorderColor); for(i=0;i<=BoardWidth;i++) {line(BoardLeft+i*CellSize, BoardTop+ BoardHeight*CellSize); }for(i=0;i<=BoardHeight;i++){line(BoardLeft,BoardLeft+BoardWidth*CellSize,}/* draw board outer border rectangle(BoardLeft-CellSize/4,BoardLeft+BoardWidth*CellSize+CellSize/4, BoardTop+BoardHeight*CellSize+CellSize/4); /* draw next block grids */ for(i=0;i<=4;i++){line(NBBoardLeft+i*NBCellSize, NBBoardTop,NBBoardLeft+i*NBCellSize, NBBoardTop+4*NBCellSize);BoardTop, BoardLeft+i*CellSize,BoardTop+i*CellSizeBoardTop+ i*CellSize); rect */BoardTop-CellSize/4,line(NBBoardLeft, NBBoardTop+i*NBCellSize,NBBoardLeft+4*NBCellSize, NBBoardTop+i*NBCellSize);}/* draw score rect */rectangle(ScoreBoardLeft,ScoreBoardTop,ScoreBoardLeft+ScoreBoardWidth,S coreBoardTop+ScoreBoardHeight);DisplayScore();/* set new seed! */ gettime(&sysTime);srand(sysTime.ti_hour*3600+sysTime.ti_min*60+sysTime.ti_sec);GenerateBlock(&nextBlock);NextBlock(); /* create first block */setcolor(DARKGRAY);outtextxy(InfoLeft,InfoTop+20,"Up -rotate Space-drop");outtextxy(InfoLeft,InfoTop+35,"Left-left Right-right");outtextxy(InfoLeft,InfoTop+50,"Esc -exit");DisplayInfo(info_help);}/* set the isFilled and fillcolordata to the board */void _INNER_HELPEFRillBoardData(){int i,j;for(i=0;i<curBlock.size;i++){for(j=0;j<curBlock.size;j++){if(curBlock.c[i][j] && (curBlock.y+j)>=0){Board[curBlock.x+i][curBlock.y+j][0]=1;Board[curBlock.x+i][curBlock.y+j][1]=curBlock.color;}/* draw one line of the board */void _INNER_HELPEPRaintBoard(){int i,j,fillcolor; for(j=max((TopLine-4),0);j<BoardHeight;j++){for(i=0;i<BoardWidth;i++){ fillcolor=Board[i][j][0]? Board[i][j][1]:BkGndColor;setfillstyle(SOLID_FILL,fillcolor);floodfill(BoardLeft+i*CellSize+CellSize/2,BoardTop+j*CellSize+CellSize/2,BorderColor);}}}/* check if one line if filled full and increase the totalScore! */ void_INNER_HELPECRheckBoard(){int i,j,k,score=10,sum=0,topy,lines=0;/* we find the top empty line! */ j=topy=BoardHeight-1;do{sum=0;for(i=0;i< BoardWidth; i++){ sum+=Board[i][topy][0];}topy--;} while(sum>0 && topy>0);/* remove the full filled line (max remove lines count = 4) */ do{sum=0;for(i=0;i< BoardWidth; i++) sum+=Board[i][j][0];if(sum==BoardWidth)/* we find this line is full filled, remove it! */{/* move the cells data down one line */ for(k=j; k > topy;k--){ for(i=0;i<BoardWidth;i++) {Board[i][k][0]=Board[i][k-1][0];Board[i][k][1]=Board[i][k-1][1];}}/*make the top line empty! */ for(i=0;i<BoardWidth;i++) {Board[i][topy][0]=0;Board[i][topy][1]=0;}topy++; /* move the topline downward one line! */ lines++; /*lines <=4 */ TotalScore+=score;score*=2; /* adding: 10, 30, 70, 150 */}elsej--;} while(sum>0 && j>topy && lines<4);/* speed up the game when score is high, minimum is 400 */FrameTime=max(1200-100*(TotalScore/200), 400);TopLine=topy;/* update the top line *//* if no lines remove, only add 1: */if(lines==0)TotalScore++;}/* display the score */void _INNER_HELPEDRisplayScore(){setcolor(BkGndColor);outtextxy(ScoreBoardLeft+5,ScoreBoardTop+5,info_score);setcolor(ScoreColor);sprintf(info_score,"Score: %d",TotalScore);outtextxy(ScoreBoardLeft+5,ScoreBoardTop+5,info_score);}/* we call this function when a block is inactive. */ void UpdateBoard(){FillBoardData(); CheckBoard();PaintBoard();DisplayScore();}/* pause the game, and timer handler stop move down the block! */ int PauseGame(){int key=0;DisplayInfo("Press P to Start or Resume!"); while(key!=K_P && key!=K_ESC) { while(!(key=GetKeyCode())){}}DisplayInfo(info_help);return key;}/* quit the game and do cleaning work. */ void QuitGame(){ closegraph();}/* the entry point function. */void main(){int i,flag=1,j,key=0,tick=0;InitGame(); if(PauseGame()==K_ESC) goto GameOver;/* wait until a key pressed */ while(key!=K_ESC){/* wait until a key pressed */ while(!(key=GetKeyCode())) {tick++;if(tick>=FrameTime){/* our block has dead! (can't move down), we get nextblock */if(!MoveBlock(&curBlock,0,1)){UpdateBoard();NextBlock();if(!CanMove(0,1))goto GameOver;}tick=0;}delay(100);}switch(key){case K_LEFT:MoveBlock(&curBlock,-1,0);break;case K_RIGHT:MoveBlock(&curBlock,1,0);break;case K_DOWN:MoveBlock(&curBlock,0,1);break;case K_UP:RotateBlock(&curBlock);break;case K_SPACE:DropBlock(&curBlock);break;case K_P:PauseGame();break;}}GameOver:DisplayInfo("GAME OVER! Press any key to exit!"); getch(); /* wait the user Press any key. */ QuitGame();}测试计划1.1 测试方案本游戏的测试方法采用检查各个功能能否实现的方法1.2测试项目及功能控制区开始:实现游戏的开始暂停:实现游戏暂停继续:实现游戏继续提高级数: 提高级数增加游戏的难度降低级数:降低级数减小游戏的难度菜单区新游戏:游戏结束从新开始新一轮的游戏提高级数:提高游戏难度降低级数:减小游戏难度退出:退出游戏开始:开始游戏暂停:暂停正在进行的游戏从新开始:重新开始游戏停止:停止正在进行的游戏帮助信息:游戏控制键显示区:显示俄罗斯方块提前显示窗口:显示下一个方块的样式测试进度:本游戏在我和同组李帅同学的辛苦努力下用了半天的时间完成了1.3测试准备编写相应的驱动模块,并精心设计测试用例1.4测试机构测试人员: 王新勃职责:找出程序中的错误,实现游戏的功能1.5 测试项目说明测试1:名称:控制区功能测试目的:测试控制区各个功能的按钮。
——————数字电路与逻辑设计实验报告—————基于VHDL的简易俄罗斯方块实验名称简易俄罗斯方块姓名班级电信工程学院04107班学号辅导老师高英日期2006年11月6日◆摘要俄罗斯方块游戏是我们熟知的经典小游戏之一,本实验通过硬件编成实现了简易的俄罗斯方块游戏机。
VHDL是一种标准的,规范的硬件描述语言,在电子设计领域有着广泛的应用。
它具有很强的电路描述和建模能力,能从多个层次多电路进行描述和建模,从而大大简化了硬件设计任务,提高了设计效率和可靠性。
本实验基于VHDL语言,利用电路中心开发的实验板,用一个4×4点阵做为基本显示屏,一个发光点表示一个图形,完成俄罗斯方块游戏的基本功能:下落、左右移动、消行和显示得分情况,当某一列到顶时游戏结束。
关键字俄罗斯方块游戏VHDL 点阵◆设计任务利用电路中心开发的实验板,用点阵做为显示屏,一个发光点表示一个方块,完成下落、左右移动、消行和显示得分情况,当某一列到顶时游戏结束,数码管显示的分数保持不变。
◆设计思路由于实验中只用到了16个点来完成显示功能,所以选用一个16位的向量STATUS(0 TO 15)来存储各点状态,再用两个整型数分别控制当前点的坐标,但是这样控制会涉及到乘法运算,因此改为4个4位向量STAN(0 TO 3),每个向量代表一行点阵,这样做不仅使控制简单,而且在扫描显示的时候很方便,代码也很简洁。
设计包括2个大的元件,一个是RUSSIA,其功能是存储状态,分频,完成左右下移动以及计分等功能;另一个是RUSSIA_SCAN,主要完成点阵扫描和数码管译码。
具体设计是这样的:4个向量STA0,STA1,STA2,STA3记录游戏状态,点的坐标由COL 和ROW来控制。
设置两个指针FLAG和ROW4,如果四列中有一列都为1,表示游戏结束了,置FLAG为1,程序进入NULL;当最后一行及STA3=”1111”时,置ROW4=1,当ROW4=1时,表示要消行,加分,并且将上一行的值赋到下一行。
俄罗斯方块设计报告1.建立整个函数的流程图如下:NYYNY NY开始 随机出示方块, 并显示下个方块 实现方块的旋转,移动 判断是否到底 判断是否已满 游戏结束 判断是否消行 消行2.图形储存设置19中方块模型,储存在结构体数组struct pattern pat[NUM](NUM为宏定义,值为19)中,如下:struct pattern{int x1;int y1;int x2;int y2;int x3;int y3;int x4;int y4;int color;};struct pattern pat[NUM]={{5,0,5,1,5,2,5,3,11},{4,0,5,0,6,0,7,0,9},/*长条型*/{5,0,6,0,5,1,6,1,2},/*正方型*/{5,0,5,1,6,1,6,2,7},{4,1,5,0,5,1,6,0,8},/*反Z型*/{5,1,5,2,6,0,6,1,14},{4,0,5,0,5,1,6,1,10},/*正Z型*/{4,1,5,0,5,1,6,1,3},{5,0,5,1,5,2,6,1,9},{4,1,5,1,5,2,6,1,10},{4,1,5,0,5,1,5,2,11},/*T字型*/{5,0,5,1,5,2,6,2,6},{4,0,5,0,6,0,4,1,7},{4,0,5,0,5,1,5,2,8},{4,1,5,1,6,1,6,0,3},/*正L型*/{5,0,5,1,5,2,4,2,12},{4,0,4,1,5,1,6,1,13},{5,0,6,0,5,1,5,2,4},{4,0,5,0,6,0,6,1,5}};/*反L型*/3.界面处理设置int map[22][12]二维数组,对其进行初始化,使其的最外面的一圈全部为1,使其成为上下左右的界限,其他为0,使其内部成为10*20的操作区域,判断一个图形到底是其每落下一行,判断这四个格子的下面的四个格子有没有值为1的,如果有,则其到底,当判断一个图形到底后,其占的四个格子值赋为1。
海南师范大学软件设计模式课程报告( 2013 -- 2014年度第一学期)课程名称:软件设计模式题目:俄罗斯方块院系:信息科学技术学院班级:任课教师:成员:成绩评定分数一、任务分配二、指导教师评语目录目录 (3)摘要 (4)一、绪论 (5)1.1俄罗斯方块游戏简介 (5)1.2 俄罗斯方块游戏规则 (6)二、需求分析与游戏设计 (7)2.2 需求分析 (7)2.2.1 游戏界面需求 (7)2.2.2 方块控制需求 (7)2.2.3 图形显示需求 (7)2.3 游戏设计 (8)2.3.1 游戏流程图 (8)2.3.2 功能模块图 (9)2.3.3 用例模型 (10)2.3.4 开始游戏序列图 (11)三、设计模式的选择和设计原则的体现 (12)3.1工厂模式 (12)3.2 命令模式 (13)3.3 其他可能用到的设计模式 (15)3.3.1 观察者模式 (15)3.3.2 策略模式 (16)四、结论 (16)五、参考文献 (16)摘要设计模式(Design pattern)是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。
使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性。
设计模式根据其目的可分为三种类型:创建型模式、结构型模式和行为型模式,共有23种。
本文将结合其中的几个设计模式阐述俄罗斯方块游戏的基本设计思想。
俄罗斯方块(Tetris, 俄文:Тетрис)是一款风靡全球的电视游戏机和掌上游戏机游戏,它由俄罗斯人阿列克谢·帕基特诺夫发明,故得此名。
俄罗斯方块的基本规则是移动、旋转和摆放游戏自动输出的各种方块,使之排列成完整的一行或多行并且消除得分。
由于上手简单、老少皆宜,从而家喻户晓,风靡世界。
一、绪论1.1俄罗斯方块游戏简介原本是前苏联科学家阿列克谢·帕基特诺夫所开发的教育用软件,之后开始提供授权给各个游戏公司,造成各平台上软件大量发行的现象。
Game Boy版的俄罗斯方块在日本卖出424万套,是Game Boy 史上卖最好的游戏。
海湾战争时,也是前线美军最常拿消磨时间的游戏之一。
由于俄罗斯方块具有的数学性、动态性与知名度,也经常拿来作为游戏程序设计的练习题材。
俄罗斯方块曾经造成的轰动与带来的经济价值,可以说是世界游戏史上的一个奇迹。
它看似简单却又变化无穷,令人上瘾。
相信大多数用户都还记得为它痴迷得“茶不思饭不想”的那个俄罗斯方块时代。
俄罗斯方块上手极其简单,但是要熟练地掌握其中的操作与摆放技巧,难度却不低。
作为家喻户晓老少皆宜的大众游戏,其普及程度可以说是史上任何一款游戏都无法相比的。
1.2 俄罗斯方块游戏规则1.游戏主画面在一个用于摆放方块的面板上2.(1)一组由4个小型正方形组成的规则图形(即方块)共有7种形状,分别为一字形、田字形、7字形、反7形、Z形、反Z形、T形。
(2)一字形:一次最多消除四层田字形:消除一至二层7字形:最多消除三层,或消除二层反7形:最多消除三层,或消除二层Z形:最多二层,容易造成孔洞反Z形:最多二层,容易造成孔洞T形:最多二层3. 方块从区域上方开始下落,玩者可以按指定按钮左右移动方块、逆时针旋转方块,以及让方块加速落下。
4. 方块移到区域最下方或是着地到其他方块上无法移动时,就会固定在该处,而新的方块出现在区域上方开始落下。
5. 当区域中某一行横向格子全部由方块填满,则该列会消失,玩家得分。
6. 当固定的方块累积堆到一定层数(设计游戏时设置)时,游戏结束。
7. 游戏分为初级、中级、高级三关。
8. 游戏会提示下一个要落下的方块形状,并随着游戏的进行而加速提高难度。
二、需求分析与游戏设计2.2 需求分析2.2.1 游戏界面需求良好的用户界面设计。
本游戏主要有三个界面,一是主游戏区的面板,显示变化和下落的方块;二是用于放置按钮以及显现游戏信息的面板,三是双人对战时用以显示对方游戏信息的面板。
2.2.2 方块控制需求方块下落时,可通过特定按钮对该方块进行翻转、加速,以及向左、向右移动等操作。
2.2.3 图形显示需求随机给出不同的形状(一字形、田字形、7字形、反7形、Z形、反Z形、T形),下落填充给定的区域,填满一行则消掉记分,当达到一定的分数时过关,共设置三关——初级、中级、高级,每关方块下落的速度不同,方块累积到一定层数无法再消去行时游戏结束。
2.3 游戏设计2.3.1 游戏流程图很多俄罗斯方块游戏都是在方块到达顶部时游戏结束,于是我们设想,在方块到达顶部时,增加一个“复活”的步骤。
所谓“复活”,是指当方块堆积到顶部时,原本游戏是要结束的,但玩家可以用自己的积分或金币来换取满行方块的消除,从而有机会继续玩下去,即为“复活”,每复活一次,就要扣掉一定的积分或金币,并且规定游戏中的“复活”次数不超过三次。
2.3.2 功能模块图1. 游戏模式选择功能模块:分为单人游戏模式与双人对战模式;2. 游戏操作模块:(1)显示模块:a.由图形工厂产生7种不同图形并随机显示在游戏主画面上;b.显示玩家信息;(2)控制模块:控制方块下落、移动、翻转等;(3)设置模块:设置游戏难度、游戏背景等。
2.3.3 用例模型(1)玩家:玩家可以选择游戏模式(分为单人游戏模式与双人对战模式),之后进入游戏,可以控制游戏(如控制方块运动与翻转)和设置游戏(如设置游戏难度、游戏背景等)。
(2)计算机:在游戏开始后,计算机随机产生方块,控制方块下落并响应玩家操作,方块下落到底部后,能自动消除满行方块并更新分数,当方块累积到顶部时,报告游戏结束。
2.3.4 开始游戏序列图三、设计模式的选择和设计原则的体现设计模式是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结,使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性。
设计模式使得设计方案更加灵活,且易于修改。
很多设计模式中广泛使用了开闭原则、依赖倒转原则、迪米特法则等面向对象设计原则,使得系统具有较好的可维护性,真正实现可维护性的复用。
设计模式的使用将提高软件系统的开发效率和软件质量,且在一定程度上节约设计成本。
在本游戏设计中,主要可以使用创建型模式中的工厂模式,行为型模式中的命令模式,还有可能会用到观察者模式和策略模式。
在软件开发中使用面向对象设计原则可以提高软件的可维护性和可复用性,每一种设计模式都符合某一种或多种面向对象设计原则。
本游戏设计中,主要体现了单一职责原则、开闭原则和依赖倒转原则。
3.1工厂模式工厂模式又称为工厂方法模式,也叫多态工厂模式或虚拟构造器模式,它属于类创建型模式,满足“开闭原则”。
在俄罗斯方块的设计中,使用图形工厂产生7种不同的方块并在游戏中随机出现。
图形工厂接口:package test1;public interface ShapeFactory {public Block produceBlock();}方块接口:package test1;public interface Block {public void change();public void moveleft();public void moveright();public void fall();}7个具体的图形工厂实现图形工厂接口,实现produceBlock()方法,随机产生7种不同的方块显示在游戏界面上,7种具体的方块实现方块接口,实现change()、moveleft()、moveright()、fall()三种方法。
3.2 命令模式命令模式是指将一个请求封装为一个对象,从而使我们可用不同的请求对客户进行参数化;对请求排队或者记录请求日志,以及支持可撤销的操作。
命令模式是一种对象行为型模式,其别名为动作模式或事务模式。
新的命令容易加到系统中,满足“开闭原则”。
在俄罗斯方块游戏设计中,玩家可对方块进行控制,即玩家向图形类发出请求,在此,便要用到命令模式,将玩家对图形类的请求封装为对象,然后放在类中。
命令接口Command中定义了抽象方法execute():package test1;public interface Command {public void execute();}4个具体命令类BlockChangeCommand、BlockMoveleftCommand、BlockMoverightCommand、BlockFallCommand实现命令接口,实现方法execute()。
4个按钮为调用者,分别是moveleft、moveright、change、fall,它们各自调用具体命令中的方法execute()方块类为请求的接收者。
方块类实现具体的业务操作,如change()、moveleft()、moveright()、fall()等方法。
比如,Block1类实现Block接口:package test1;public class Block1 implements Block{public void change(){}public void moveleft(){}public void moveright(){}public void fall(){}}BlockChangeCommand类实现Command接口:package test1;public class BlockChangeCommand implements Command{private Block1 block1;public BlockChangeCommand(){block1=new Block1();}public void execute(){block1.change();}}调用者类Button(按钮类):package test1;public class Button {private Command changeCommand,moveleftCommand,moverightCommand,fallCommand;public Button(Command changeCommand,Command moveleftCommand, Command moverightCommand,Command fallCommand){this.changeCommand=changeCommand;this.moveCommand=moveleftCommand;this.moveCommand=moverightCommand;this.fallCommand=fallCommand;}public void change(){changeCommand.execute();}public void moveleft(){moveCommand.execute();}public void moveright(){moveCommand.execute();}public void fall(){fallCommand.execute();}}3.3 其他可能用到的设计模式3.3.1 观察者模式观察者模式是指定义对象间的一种一对多依赖关系,使得每当一个对象状态发生改变时,其相关依赖对象皆得到通知并被自动更新。