




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
俄罗斯方块实验报告编写“俄罗斯方块”游戏1、问题分析。 编写俄罗斯方块游戏,首先是界面问题,要有一个相对美观的游戏界面,可以有很多种解决的方法,可以用DOS的界面,也可以用MFC做。 界面做好后,最重要的就是七个方块如何存放,翻转,显示等等一系列问题,首先,我们要把这七个方块用一种数据结构存储起来;其次,在游戏中将这七个方块随机挑选出来并显示在屏幕上,根据键盘事件进行旋转;最后,判断到达底部的方块是简单叠加还是引发消除事件。 普通俄罗斯方块游戏中,只有七个基本方块:|,Z,N,L,7,|-,O,方块都可以画在一个4*4的方格中。于是就有两个方法:一个是只存储七个方块,在游戏运行的时候计算旋转后的方块形状;另一个是将所有的方块全部存储起来,在游戏运行的时候计算取其中的哪个方块。
另外,考虑到4*4是16,而一个int正好是16位(TC2是16位,其他的是32位),所以可以把一个方块存储在一个int数据中,取出的时候,判断它的每个bit位,为1处有小方块,为0处是空白。
所以可以分别用二维数组和bit的方法来表示这些方块。 对于二维数组而言,其控制旋转的操作会很简单,就是控制数组的行列以决定到底该取出哪一种方块,所以程序中我会采用这种方法。如何控制方块的下落速度,如何让实现左移,右移,下落,如何销行,如何计分,又如何加速等等都是需要考虑的问题。对于控制方块的下落速度,首先应该现弄明白方块是怎样下落的,目前最常用的就是每隔一定得时间进行重新绘图,就像动画片一样,当很多副相关的画面不断在人眼前播放,由于人眼的掩蔽效应就会形成动着的画面,看起来就是物体在那里移动,于此原理相同,当改变方块在画面上的位置,再以一定得时间间隔进行重新刷图,其效果看起来就是方块在移动;也就是说控制方块下落速度的其实就是控制重新绘图的时间间隔,控制时间的函数有以下几种:调用函数SetTimer()设置定时间隔,如SetTimer(0,200,NULL)即为设置200毫秒的时间间隔。在应用程序中增加定时响应函数OnTimer(),并在该函数中添加响应的处理语句,用来完成时间到时的操作。这种定时方法是非常简单的,但其定时功能如同Sleep()函数的延时功能一样,精度较低,只可以用来实现诸如位图的动态显示等对定时精度要求不高的情况,而在精度要求较高的条件下,这种方法应避免采用。精度时控函数,在要求误差不大于1毫秒的情况下,可以采用GetTickCount()函数,该函数的返回值是DWORD型,表示以毫秒为单位的计算机启动后经历的时间间隔。高精度时控函数对于一般的实时控制,使用GetTickCount()函数就可以满足精度要求,但要进一步提高计时精度,就要采用QueryPerformanceFrequency()函数和QueryPerformanceCounter()函数。这两个函数是VC提供的仅供Windows9X使用的高精度时间函数,并要求计算机从硬件上支持高精度计时器。接下来就应该考虑如何实现左移,右移,下移,触底,其实很简单就是将屏幕看成一个大的坐标轴,改变坐标的大小,即可控制方块的位置。销行,就是当一行中全是方块时,即这一行中存储的全是1,就符合销行条件,将这行删除,它之上的所有方块纵坐标下移一格,并且记录销行的次数,以此来控制得分情况,根据所得的分数制定相应的过关规则。对于如何决定下一个是怎样的方块,可以采用随机数,用随机数来决定的方块。rand函数是一个随机函数,可以产生从0到rand_max(32767)的随机数,但是每次运行程序产生的随机数都是一样的,这时给随机数产生一个随机种子(seed),函数原型是srand((unsigned)time(NULL));time的值每时每刻都不同。所以种子不同,所以,产生的随机数也不同。所以说,要想产生不同的随机数,在使用rand之前需要先调用srandsrand和rand函数都包含在stdlib.h的头文件里。由于rand产生的随机数是从0到rand_max的,而rand_max(32767)是一个很大的数,那么如何产生从X-Y的数呢?从X到Y,有Y-X+1个数,所以要产生从X到Y的数,只需要这样写:k=rand()%(Y-X+1)+X;这样,就可以产生你想要的任何范围内的随机数了。设计方案。定义一个类classConsole来控制窗口的大小,使窗口的大小适合玩家玩游戏。定义三种静态颜色变量以控制小格子的颜色,使界面更加美观。staticconstWORDCOLOR_A; //运动中的颜色staticconstWORDCOLOR_B; //固定不动的颜色 staticconstWORDCOLOR_C; //空白处的颜色这三种静态变量用户可以自己改变颜色来达到所期望的效果。需要引入头文件:windows.h下面是一些常用的颜色说明:AttributeMeaningFOREGROUND_BLUETextcolorcontainsblue.FOREGROUND_GREENTextcolorcontainsgreen.FOREGROUND_REDTextcolorcontainsred.FOREGROUND_INTENSITYTextcolorisintensified.BACKGROUND_BLUEBackgroundcolorcontainsblue.BACKGROUND_GREENBackgroundcolorcontainsgreen.BACKGROUND_REDBackgroundcolorcontainsred.BACKGROUND_INTENSITYBackgroundcolorisintensified.COLOR_A=FOREGROUND_RED|FOREGROUND_GREEN|FOREGROUND_INTENSITY;//这是运动中的颜色是黄色COLOR_B=FOREGROUND_GREEN;//固定不动的方块颜色是绿色COLOR_C=FOREGROUND_RED|FOREGROUND_GREEN|FOREGROUND_BLUE;//空白处的颜色是灰色这是我界面的颜色分布。将屏幕像像素块一样分成11*19的格子,灰色底。用4*4共16个格子来表示一个方块,用一个4*4的数组来存储七个方块,1代表有一个格子,0代表没有格子,例如:|-,可以用以下数组直观来表示:1000010001001110110011101100010010000000010000000000000000000000这些数组存储了七种方块,四个变换,于是我定义了一个4维数组bk[7][4][4][4]来存储这些数据,具体见附录2,当在游戏中进行一次旋转就是改变数组最后一维的数值,旋转是逆时针旋转。以屏幕左上角为原点,从左向右画x轴;从上向下画y轴,(x,y)就代表了在屏幕上的位置,通过控制x,y值来实现左移,右移,上移,下移。例如向左移的代码如下:voidMoveLeft(void) //向左移{if(IsFit(x-1,y,c,z)) //检查是否碰到墙壁{ //没有碰壁则继续VoiceBeep();Draw(COLOR_C); //先将空白处画出--x; //将横坐标减1Draw(COLOR_A); //绘出方块}}判断方块已经到达底部或是否碰到墙壁,“将会”指的是方块如果向左,向右,向下移动后就会碰到障碍物;“障碍物”指的是左右下墙壁和底部已经落下未被消除的小方块。用下列函数:boolIsFit(intx,inty,intc,intz)//给定的x,y,c,z是否可行{for(inti=0;i<4;++i) //用i,j来遍历16个小格子{for(intj=0;j<4;++j){if(bk[c][z][i][j]==1){if(y+i<0)continue;//方块还没有落下来//y+i>=19表示已经触底了,x+j<0表示触了最左边的墙,//x+j>=11表示触了最右边的墙,//data[y+i][x+j]==1表示底部已经存在了方块if(y+i>=19||x+j<0||x+j>=11||data[y+i][x+j]==1)returnfalse;} } } returntrue;}方块落下后,就开始检查是否有满足消除条件的行了。用chardata[19][11]来记录有小方块存在的地方,有为1,没有事0。销行的规则很简单:只要某行被小方块全部填充,该行就被消除,上面的小方块全部下移一行。所以,只要把原来的小方块全部擦去,计算完新方块位置后,再全部画出就可以了,计算的时候,遍历整个游戏区域,看有没有可以消除的行,即遍历chardata[19][11]看一行中是否全1,如果是,则开始将这行上面的所有行开始下移,并用intline-count来记录销行的次数,这与之后的计分和关数的计算有关系,销一行加100分,如果有连销行则分数相应增加,每10000分是一个等级,99999封顶。代码如下:voidRemoveRow(void) //消行函数{constcharFULLLINE[]={1,1,1,1,1,1,1,1,1,1,1};intlinecount=0; //记录连续销行的行数for(inti=0;i<19;++i) //开始对19*11的格子开始遍历{ //如果一行中11列均是1则满足销行条件if(0==memcmp(data[i],FULLLINE,11)){++linecount;for(intm=0;m<11++m){for(intn=i;n>1;--n){ //对这行以上的行进行下移,//就是销去了这一行data[n][m]=data[n-1][m]; win.Output(2+m*2,1+n,data[n][m]==1?COLOR_B:COLOR_C,"■",2);}data[0][m]=0; //最顶部赋值为0,既没有小方块win.Output(2+m*2,1,COLOR_C,"■",2);}}}chardata[19][11]={0};if(linecount==0)return;int_score=0;switch(linecount) //按照销行的行数来给分数{case1:_score=100;break;case2:_score=300;break;case3:_score=700;break;case4:_score=1500;break;}score+=_score;if(score>99999)score=99999;//最高分数是99999level=score/10000; //设置等级DrawScoreLevel(); //绘制得分框}用Sleep()函数来控制刷图的速度,程序中设定每55ms刷一次图,Sleep(55);用简单Beep(freq,dura)来控制声音,其中freq是频率,dura是持续时间;用随机函数srand(time(0));next=rand()%7来控制下一个方块类型。3、流程图。开开始显示界面显示界面按下结束按下结束 是按下开始 否按下开始 否 是开始游戏开始游戏输入指令输入指令根据指令调用不同的函数进行操作根据指令调用不同的函数进行操作按下结束 是按下结束 否GAMEOVER 否GAMEOVER 是结结束4、测试数据、测试结果、结果分析。 开始游戏右移方块旋转方块销一行得100分连销4行得1500分达到10000分,升一级游戏结束PS:由于打印需要,界面呈黑白画面5、相关运行界面。6、关键代码//只有部分代码,完整代码就是前面那个俄罗斯方块代码classConsole //控制台{friendclassWindow;public:voidOpen(constchar*title,COORDwl) //title:控制台标题{ //point:控制台宽度和高度assert(wl.X>0&&wl.Y>0);verify((hStdOutput=GetStdHandle(STD_OUTPUT_HANDLE))!=INVALID_HANDLE_VALUE); //获得输出句柄verify(SetConsoleTitle(title)); //设置标题CONSOLE_CURSOR_INFOcci={25,FALSE};verify(SetConsoleCursorInfo(hStdOutput,&cci));//去除光标SMALL_RECTwrt={0,0,wl.X-1,wl.Y-1};//设置窗体尺寸verify(SetConsoleWindowInfo(hStdOutput,TRUE,&wrt));coord=wl; //设置缓冲尺寸verify(SetConsoleScreenBufferSize(hStdOutput,coord));}private:HANDLEhStdOutput;COORDcoord;};classRussiaDiamonds //俄罗斯方块的类{public: //x:左上角坐标,RussiaDiamonds(Console&console,shortx,shorty){ //y:右下角坐标SMALL_RECTwrect={x,y,x+38,y+21};win.Open(console,wrect);}//分别是开始,暂停,声效,变形,左移,右移,下移,落地键的键码,//声效频率,延续时间//Example://A键为0x41,用0x00000041表示//F1键为0x00,0x3B,用0x00003800表示//F11键为0xE0,0x85,用0x000085E0表示voidOpen(intctrlkeys[8],charctrlkeydecs[8][5],DWORDfrequency,DWORDduration){memcpy(keys,ctrlkeys,sizeof(keys));memcpy(decs,ctrlkeydecs,sizeof(decs));freq=frequency,dura=duration; gameover=false; //分别对各个控制量初始化pause=true;voice=true;score=0,level=0;memset(data,0,sizeof(data));srand(time(0)); //设置随机种子数next=rand()%7; //产生随机数来控制下一个方块的产生x=4,y=-2,c=-1,z=0;} boolIsFit(intx,inty,intc,intz) //给定的x,y,c,z是否可行{for(inti=0;i<4;++i) //用i,j来遍历16个小格子{for(intj=0;j<4;++j){if(bk[c][z][i][j]==1){if(y+i<0)continue;//方块还没有落下来//y+i>=19表示已经触底了,x+j<0表示触了最左边的墙,//x+j>=11表示触了最右边的墙,//data[y+i][x+j]==1表示底部已经存在了方块if(y+i>=19||x+j<0||x+j>=11||data[y+i][x+j]==1)returnfalse;}}}returntrue;}voidRemoveRow(void) //消行函数{constcharFULLLINE[]={1,1,1,1,1,1,1,1,1,1,1};intlinecount=0; //记录连续销行的行数for(inti=0;i<19;++i) //开始对19*11的格子开始遍历{ //如果一行中11列均是1则满足销行条件if(0==memcmp(data[i],FULLLINE,11)){++linecount;for(intm=0;m<11++m){for(intn=i;n>1;--n){ //对这行以上的行进行下移,就是销去了这一行data[n][m]=data[n-1][m]; win.Output(2+m*2,1+n,data[n][m]==1?COLOR_B:COLOR_C,"■",2);}data[0][m]=0;//最顶部赋值为0,既没有小方块win.Output(2+m*2,1,COLOR_C,"■",2);}}}chardata[19][11]={0};if(linecount==0)return;int_score=0;switch(linecount) //按照销行的行数来给分数{case1:_score=100;break;case2:_score=300;break;case3:_score=700;break;case4:_score=1500;break;}score+=_score;if(score>99999)score=99999;//最高分数是99999level=score/10000; //设置等级DrawScoreLevel(); //绘制得分框} voidMoveTrans(void) //逆时针翻转{if(IsFit(x,y,c,(z+1)%4)) //每调用一次z改变一次{ //通过调用四维数组中//不同的矩阵来实现变换VoiceBeep();Draw(COLOR_C);z=(z+1)%4;Draw(COLOR_A);}}//部分代码省略private:staticconstcharbg[21*38+1];staticconstcharbk[7][4][4][4];staticconstWORDCOLOR_A; //运动中的颜色staticconstWORDCOLOR_B; //固定不动的颜色staticconstWORDCOLOR_C; //空白处的颜色private:DWORDfreq,dura; //声效频率,延续时间intkeys[8]; //8个控制键chardecs[8][5]; //8个控制键的描述boolgameover;boolpause; //暂停boolvoice; //声效开关intsc
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 抗菌药物分级管理培训
- 阳泉职业技术学院《语言教学法》2023-2024学年第二学期期末试卷
- 阿拉善职业技术学院《古代汉语Ⅰ(新闻)》2023-2024学年第一学期期末试卷
- 陇南师范高等专科学校《建筑设备施工技术》2023-2024学年第二学期期末试卷
- 陕西交通职业技术学院《专业外语暖通》2023-2024学年第二学期期末试卷
- 陕西国际商贸学院《应用回归分析》2023-2024学年第一学期期末试卷
- 陕西工业职业技术学院《水利工程施工》2023-2024学年第二学期期末试卷
- 陕西服装工程学院《水文与水资源学》2023-2024学年第二学期期末试卷
- 陕西电子信息职业技术学院《山西美食及地方文化》2023-2024学年第二学期期末试卷
- 陕西省咸阳市达标名校2025年中考摸底测试综合能力试题含解析
- 2024年H13-531云计算HCIE认证考试题库及答案
- 路灯安全培训
- DLDS-1214F电气装置技术方案(世赛KNX版)
- 电力行业电气工程师求职简历
- 2024中智集团总部公开招聘笔试参考题库附带答案详解
- 2025年吉林铁道职业技术学院单招职业技能测试题库带答案
- 《以哪吒精神照亮成长之路》开学家长会课件
- 全国公安移动警务视频应用建设指南(征求意见稿)-正式-来源广东
- 中国大唐集团公司基建工程质量标准及工艺要求(安装部分)
- 中国近现代史纲要学习心得体会与社会责任
- 【生物】人的生殖课件-+2024-2025学年人教版生物七年级下册
评论
0/150
提交评论