c语言俄罗斯方块实验报告_第1页
c语言俄罗斯方块实验报告_第2页
c语言俄罗斯方块实验报告_第3页
c语言俄罗斯方块实验报告_第4页
c语言俄罗斯方块实验报告_第5页
已阅读5页,还剩18页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

语言之游戏俄罗斯方块课程设计报告专 业: []学生姓名: []指导教师: []完成时间:1目录一、需求分析 错误!未定义书签。二、概要设计 错误!未定义书签。三、详细设计 错误!未定义书签。四、调试分析 19五、用户手册 20六、测试数据 错误!未定义书签。七、附录 错误!未定义书签。2一、需求分析该程序是完成一个简易的俄罗斯方块的任务,其要完成几个重要的功能:界面,方块下落,旋转,判断是否还能下落,左右移动,分数,速度设置,清楚满的每行,下个方块的预览等;可用#include<graphics.h>的头文件来实用几个函数来控制并完成游戏的界面;可用7个二维5*5数组去实现下落方块的全部类型,再用随机函数使其随机下落;用#include<conio.h>的头文件去使用按键的控制,以保证用户能够合理操作;并用#include<stdlib.h>的头文件来使用rand函数来随机出示七种方块;完成正常的显示和下个方块的预览;用#include<bios.h>来运用时针去控制时间;程序执行过程:然后加上几个基本的头文件来执行函数,首先设置按键操作,用:w,a,d,s控制,然后进行界面的初始化设置,启动,时针参数设置,开始新游戏,开始随机下落方块,显示下一个方块,再行旋转,移动,清除,加分,速度参数,最后判断是否已满,停止游戏,打出分数,结束的画面设置,游戏终止...二、概要设计该程序中的函数设置总体主要功能大致如下1.找到合适的方块盒子(7种)使其一一下落box[MAX_C][5][5]={/*MAX_C(7)种预定义的盒子*/这样用类似的7个5*5二维数组来实现每个盒子方块的形状,自此就引荐两个作为介绍,{{0,0,0,0,0},{0,0,0,0,0},{0,0,1,0,0},{0,1,1,1,0},{0,0,0,0,0},3{0,0,0,0,0}},{{0,0,0,0,0},{1,1,1,1,0},{0,0,0,0,0},{0,0,0,0,0}},如此中用1代表显示的格子,0代表空。设置时间指针,实现旋转,移动,消去,显示加分,改变速度分别用下面函数表示intsetTimer(Timer*t,unsignedintintv,BOOLen);/*设置时钟t,参数分别为时钟指针,时间间隔,是否活动*/voidrotateBox(intbox1[5][5],intbox2[5][5])/*旋转box1输出到box2*/intmove(intdir)/* 实现移动,返回成功与否 */voidclear()/* 清除掉满行*/voidprscore()/* 打印现在的分数*/voidspe()/* 显示速度的改变*/外部函数功能如下图益智游戏俄罗斯方块界面设置voidinitMap 函数和 voidrender 绘

随机显示方块,并建立下一个;用rand() 与void

方块的旋转和移动下落;用rorate()move()

判断是否能继续下落;用inttest()函数来完成;

分数的改变与速度设置;用prscore()与spe()

判断最后,游戏结束的 操作;用图函4.数建立整个函数的流程图如下rebuidNext

与drop()来实现开始界面4

来完成

prscore()和界面设置完成时间指针设定随机出示方块,并显示下个方块实现方块的旋转,移动判断是否到底 NY加分,速度设置Y判断是否已满打印分数,结束处理游戏结束

N5流程简介:玩家定义游戏开始,游戏显示开始界面,时针已经设定好,然后随机出示方块,玩家进行方块的旋转,左右移动,和下落控制,然后在旁边的表格中出示另一个表格显示下一个即将下落的方块, 然后判断是否到达底部,若到,继续出示方块,若没,则可继续变换,下落到低端后在进行判断,是否可以消除该行,再进行分数的变换,速度的调整,然后判断是否已经满,若未满,则继续出示下一个方块,若满,则结束游戏,打印分数,出示结束界面,游戏终止。三、详细设计1.设置七种方块:这个用 intbox[MAX_C][5][5]=/*MAX_C(7) 种预定义的盒子*/ 来实现;即七个 5*5的盒子数组,方块实体用 1表示,0表示空;七种如下所示,细心就会发现{{0,0,0,0,0},{0,0,0,0,0},{1,1,1,1,0},{0,0,0,0,0},{0,0,0,0,0}},{{0,0,0,0,0},{0,0,1,0,0},{0,1,1,1,0},{0,0,0,0,0},{0,0,0,0,0}},{{0,0,0,0,0},{0,1,1,0,0},6{0,0,1,1,0},{0,0,0,0,0},{0,0,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,0}},{{0,0,0,0,0},{0,1,1,0,0},{0,0,1,0,0},{0,0,1,0,0},{0,0,0,0,0}},{{0,0,0,0,0},{0,0,1,1,0},{0,0,1,0,0},{0,0,1,0,0},{0,0,0,0,0}},{7{0,0,0,0,0},{0,0,1,1,0},{0,0,1,1,0},{0,0,0,0,0},{0,0,0,0,0}}}; 这样七种盒子的方块就被清楚的展现在你们面 前。用来保证方块不会出来2.我们要进行按键的设置#defineKEY_UP'w'/* 定义上下左右按按键*/#defineKEY_DOWN's'#defineKEY_LEFT'a'#defineKEY_RIGHT'd'#defineKEY_ESC27/* 退出*/时钟的控制,用来控制方块的下落间隔时间及速度/*时钟结构控制*/typedefstruct{/* 时钟结构*/BOOLenabled;/* 时钟是否开启*/unsignedintintervel;/* 定时间隔*/unsignedintlasttime;/* 这个属于内部使用变量*/}Timer;4.intGetTickCount(){/* 读取BIOS时钟*/intret;ret=peek(0x0,0x46e);/* 实际上读取了内存 0:046e处的内容*/ret<<=8;/* 这个地方是$%#$^$%&^*/ret+=peek(0x0,0x46c);/* 太多新的东西了,找点书看一看吧*/return(ret);}intsetTimer(Timer*t,unsignedintintv,BOOLen){t->enabled=en;/* 设置一个时钟罗*/8t->intervel=intv;t->lasttime=GetTickCount();/*lasttime 记录的是上一个*//*tickcount 返回的东西*//*这样当再一次测试时间时新的 tickcount 产生了它来减去上一次的 tickcount 就得出了一个时间 间隔,这个就可以和intervel比较从而得出是否激活了*/return0;}实现了以上的操作后,接下来要实现界面的设置一方便盒子在界面上的显示和操作;5.voidinitMap(void){/* 初始化地图*//*我们须要一圈卫兵呵呵,全是 1...用来保证方块不会出来*/intx,y;for(y=0;y<MAX_Y;y++){for(x=0;x<MAX_X;x++){if(x<2||x>MAX_X-3||y>MAX_Y-3)map[y][x]=1;elsemap[y][x]=0;}}/*这里初始化出这个形状*/}/*当然是无盖的...*/voidrender(void)/* 这里唯一的绘图函数*/intx,y;staticintcPage=0;/* 当前页,换页用*/#defineSTARTX50/* 定义几个常量*/#defineSTARTY0/* 数值根据自己的需要可以自己设置 */#defineLEN189setactivepage(cPage=(cPage==0?1:0));/* 选择页*/cleardevice();/* 清屏*/setcolor(12);/* 前景颜色*/prscore();setcolor(15);rectangle(STARTX+LEN*2-2,STARTY+LEN*3-2,STARTX+LEN*(MAX_X-2)+2,STARTY+LEN*(MAX_Y-2)+2);/*用白色画一个外框*/setfillstyle(SOLID_FILL,5);for(y=3;y<MAX_Y-2;y++){/* 画地图*/for(x=2;x<MAX_X-2;x++){if(map[y][x]){rectangle(x *LEN+STARTX,y*LEN+STARTY,x*LEN+STARTX+LEN,y*LEN+STARTY+LEN);bar(x*LEN+STARTX+1,y*LEN+STARTY+1,x*LEN+STARTX+LEN-2,y*LEN+STARTY+LEN-2);}}}/*绘图操作就不要作太复杂的介绍了 ,这只写作用*//*以上段,根据地图上的点阵情况将地图反映到屏幕上 */for(y=0;y<5;y++){/* 画下落物*/for(x=0;x<5;x++){if(curbox[y][x]){10if(y+cury>2){rectangle((x+curx)*LEN+STARTX,(y+cury)*LEN+STARTY,(x+curx)*LEN+STARTX+LEN,(y+cury)*LEN+STARTY+LEN);bar((x+curx)*LEN+STARTX+1,(y+cury)*LEN+STARTY+1,(x+curx)*LEN+STARTX+LEN-2,(y+cury)*LEN+STARTY+LEN-2);}}}}/*以上将下落的盒子按昭它在地图上的坐标 ,画到对应的区域里*/for(y=0;y<5;y++){/* 画下一个*/for(x=0;x<5;x++){if(nextbox[y][x]){rectangle(x*LEN+320,y*LEN+10,x*LEN+338,y*LEN+28);bar(x*LEN+321,y*LEN+11,x*LEN+336,y*LEN+26);}}}11/*这个画出下一个盒子的预览 */setvisualpage(cPage);/* 确认在cPage页里画好了*//*将它显示出来*/}这样我们的初始化界面和盒子在图上的意义显示已经完成;接下里我们要对即将出现的方块的形状进行预览即建立一个新的函数用来显示下一个下落的盒子;voidrebuidNext(){/*新建下一个形状并放到nextbox中*/inti,x,y;i=random(MAX_C);/*从几种方块里面选一种*/for(y=0;y<5;y++)/*并复制过来*/for(x=0;x<5;x++)nextbox[y][x]=box[i][y][x];/*复制*/}voidputBox(){/*将curbox填充到地图上*/intx,y;for(y=0;y<5;y++)/*这个也简单,主要是要根*/for(x=0;x<5;x++)/*据curx,cury指出位置*/if(curbox[y][x])map[y+cury][x+curx]=curbox[y][x];}intnewfall(){/*创建下落元素失败返回0*/intx,y;curx=MAX_X/2-2;/*重新指定小盒位置*/cury=0;for(y=0;y<5;y++)for(x=0;x<5;x++)curbox[y][x]=nextbox[y][x];/*将nextBox复制过来*/rebuidNext();/*重建nextBox*/12returntest(curx,cury,curbox);}这样一来,我们的预览盒子也就完成了。完成以后,我们要进行下落的控制,这个在开始的控制指针已经做好的下落间隔设置,然后开始随机出示方块,玩家应开始进行旋转,移动的操作,下落的过程;voidrotateBox(intbox1[5][5],intbox2[5][5]){/*旋转box1输出到box2*/intx,y;for(x=0;x<5;x++)/* 这个函数可以须要实际*/for(y=4;y>=0;y--)/* 编写一下才能印像深刻*/box2[y][x]=box1[x][4-y];}introtate()/*整个旋转的操作并将盒子打印到屏幕上*/{intx,y;intnewbox[5][5];/*我们必须将当前盒子转动到新的盒子*//*再对这个新的盒子的冲突作测试*/rotateBox(curbox,newbox);/*转动到新的盒子*/if(test(curx,cury,newbox)){/*并且新的盒子能放到地图上而不冲突 */for(y=0;y<5;y++)for(x=0;x<5;x++)curbox[y][x]=newbox[y][x];/* 复制进来*/return1;}elsereturn0;}intmove(intdir){/* 返回成功与否*/intnewx;13if(dir)newx=curx+1;/*与drop一样,准备移动后的坐标*/elsenewx=curx-1;if(test(newx,cury,curbox)){/*测试是否冲突*/curx=newx;/*可以的话切换curx*/return1;}return0;}这个就完成了左右移动的操作;intdrop(){/* 下落,返回成功与否*/intnewy;/* 盒子要下落的新位置*/newy=cury+1;/* 为当前Y位置+1*/if(test(curx,newy,curbox)){cury=newy;/* 测试下落盒在这个位置*/return1;/* 上是否有冲突,没有的话*/}/*直接设置cury*/return0;}inttest(intmx,intmy,intbox[5][5]){/*测试box在map里mx,my位置上是否能着陆*//*这个是最关键的一个函数 ,它判断是否产生非空冲突 *//*但算法还是很简单的*/intx,y;for(y=0;y<5;y++)for(x=0;x<5;x++)if(map[y+my][x+mx]&&box[y][x])return0;return1;}14这样就完成了旋转,移动,测试并下落的功能。接下来我们要完成下落后的分数的改变速度的重新设定;voidclear(){/* 清除掉满行*//* 具体的算法为:从第0行开始到最后一行,测试地图点阵是否为满,如果是的话从当前行算起,之上的地图向下掉一行*/intx,y;intdx,dy;intfullflag;for(y=0;y<MAX_Y-2;y++){/* 最后两行保留行*/fullflag=1;/* 假设为满*/for(x=2;x<MAX_X-2;x++){/* 保留列~*/if(!map[y][x]){fullflag=0;break;}}if(fullflag){/* 向下移动一行*/for(dy=y;dy>0;dy--)for(dx=2;dx<MAX_X-2;dx++)map[dy][dx]=map[dy-1][dx];for(dx=2;dx<MAX_X-2;dx++)map[0][dx]=0;score+=10;/* 输出新得分*//*并清除掉第一行*/}}}voidprscore()/* 输出分数*/{charstr[10];setfillstyle(SOLID_FILL,YELLOW);15rectangle(90,15,260,35);setcolor(6);settextstyle(0,0,2);sprintf(str,"score:%d",score);outtextxy(115,20,str);}voidspe()/* 显示速度的改变*/{if(score%50==0&&score!=0)setTimer(&tDown,speed--,1);}然后在主函数之前中定义以下的操作,这个应该会很容易理解intmap[MAX_Y+4][MAX_X+4];/*地图大盒子...MAX_X,Y是可见面积*//*我已说过需要在外面布两圈"卫兵"*/intcurbox[5][5];/* 当前下落的盒子*/intcurx,cury;/* 保存着当前活动盒子在地图上的位置 */intnextbox[5][5];/* 保存着下一个形状的盒子 */接下俩用newgame函数将其串联起来,实现函数的内嵌;voidnewGame(){/* 新建游戏*/intx,y;initMap();/* 初始化地图*/srand(GetTickCount());/* 初始化随机发生器*/rebuidNext();/* 建立下一个*/setTimer(&tDown,speed,1);/* 启动时钟(快慢两个)*/setTimer(&tFast,FAST_INTV,1);newfall();/* 对下落的盒子操作一下*//*这样第一个下落的方块就在地图顶部准备好了*/}接下来最为重要的主函数将要开始;intmain(){charkey;/* 记录当前按键*/inti;intgd=VGA,gm=VGAMED;/*初始化的图形模式*/Timer*ptDown;/*下落所指向的时钟(有快慢)*/16Timertrender;/*为了避免渲染给程序造成过大的负担*//*用一个时钟来控制渲染速度*//*把它设置interval=1,*//*这样就是18FPS了,当然无法达到标*//*准的60FPS...毕竟这是DOS...*/setTimer(&trender,1,1);initgraph(&gd,&gm,"");/* 初始化图形*/newGame();/* 新游戏...*/prscore();while(1){/* 主游戏循环*/if(kbhit()){/* 如果键盘有按下*/key=getch();/* 读取一个按键值到 key*/}elsekey=0;switch(key){/* 对读到的key进行判断*/caseKEY_UP:rotate();/* 上,旋转下落盒子*/break;caseKEY_DOWN:ptDown=&tFast;/* 使用tFast 时钟*/break;caseKEY_LEFT:move(0);/* 左移*/break;caseKEY_RIGHT:move(1);/* 右移*/break;17caseKEY_ESC:closegraph();/* 结束游戏*/exit(0);default:ptDown=&tDown;/* 使用原来速度*/}if(testTimer(ptDown)){/* 在上面已设置了下落要使用的时钟在ptDown里*/if(!drop()){/* 下落,失败返回0*/putBox();/* 写到地图里*/clear();prscore();spe();setcolor(6);/* 清除满行*/if(!newfall()){/* 新建下落,失败则游戏结束*/setcolor(14);settextstyle(0,0,2);outtextxy(100,200,"GAMEOVER");/* 游戏结束,在屏幕上打印字符串 */outtextxy(100,240,"THANKYOU");sleep(3);exit(0);}}}if(testTimer(&trender))/* 最后... 渲染...*/render();}}最后main函数已经介绍完毕,只需在开始加上程序所需的头文件和值的宏定义后整个程序就全部完毕#include<stdio.h>18#include<stdlib.h>#include<bios.h>/* 这里须要读取系统运行时间来作为定时器 */#include<graphics.h>/* 很不幸,TC2的简单图形,让我放弃了用*/#include<conio.h>/*win32+openGL 来讲解.*/#defineMAX_X14/* 可见最大X*/#defineMAX_Y21/* 可见最大Y*//*我们定义了最大的可见 X和Y,那么即还有不可见的部分 ,事实上地图(大盒子)里的左右两侧和底部各两行都被1填充,这样大大简化出界的判断,事实上,在本例中没有这样的代码,因为旁边有一圈1阻止小盒子越出大盒子的按制范围*/#defineMAX_C7/* 最大种类,这个无须解释*/#defineFALSE0#defineTRUE1到此为止,整个程序全部结束,详解到此完毕。四、调试分析19开始第一次

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论