为了正常的体验网站,请在浏览器设置里面开启Javascript功能!

C语言俄罗斯方块试验报告,包括源程序

2017-11-13 27页 doc 56KB 32阅读

用户头像

is_954223

暂无简介

举报
C语言俄罗斯方块试验报告,包括源程序C语言俄罗斯方块试验报告,包括源程序 实验内容 游戏程序----俄罗斯方块 指导老师 李陶深 一(实验题目 设计完成俄罗斯方块游戏。游戏开始后在游戏小窗口的顶部会随机产生一个方块并以一定的速度下移,下移过程玩家作变换、左右移操作以使其摆放合适,当叠满一行时会自动消去并计10分,若不能消行而叠到游戏小窗口的顶部则游戏失败,此时玩家可退出或重新开始。 二(实验要求与目的 游戏界面合理,进入游戏后应有操作说明。要求: ?按任意键开始游戏,随机产生方块并自动下移 ?用Esc键退出游戏,,键可重新开始游戏 ?用 键变换方块...
C语言俄罗斯方块试验报告,包括源程序
C语言俄罗斯方块试验,包括源程序 实验内容 游戏程序----俄罗斯方块 指导老师 李陶深 一(实验目 设计完成俄罗斯方块游戏。游戏开始后在游戏小窗口的顶部会随机产生一个方块并以一定的速度下移,下移过程玩家作变换、左右移操作以使其摆放合适,当叠满一行时会自动消去并计10分,若不能消行而叠到游戏小窗口的顶部则游戏失败,此时玩家可退出或重新开始。 二(实验要求与目的 游戏界面合理,进入游戏后应有操作说明。要求: ?按任意键开始游戏,随机产生方块并自动下移 ?用Esc键退出游戏,,键可重新开始游戏 ?用 键变换方块 ?用 键和 键左右移动方块 ?用 键使方块加速下移 ?用空格键使方块直接下移 ?能正确判断满行并消行、计分、定级别 ?能正确计时 ?设定游戏为五个级别,级别越高难度越大 目的是通过设计完成俄罗斯方块游戏,加深对计算机图形学的认识并在实践中加以应用,此外进一步熟悉应用编程语言。 三(实验环境 硬件:CPU--------------AMD AthlonXP 1800+ 内存--------------DDR333 256M 硬盘--------------40G 显示卡-----------Max440 64M 128bit 显示器-----------17寸彩显 软件:OS----------------Windows XP 开发工具--------Tubor C 2.0 四(系统的设计思想 1( 系统的体系结构 本系统主要由主函数、方块的产生与清除、方块的变换与移动、消行与计分、计时这五大模块组成,其中方块的变换与移动模块是本系统中的关键模块,也是最为复杂的模块。详情请参考以下的结构图: 主函数 Main( ) 方块的产方块的变消行与计时 生与清除 换与移动 计分 coutTime() turnUnit()、 clrTurnUnitclrLine() () move() 小方格小方格 方块的方块左、计分 方块的 的产生 的清除 下移与右、下的变换 fangKuai()、 clrFangKuaic72()、 score() 左右移 停止 () getN() c75()、 stopL()、 c77() stopR()、 stopB() 俄罗斯方块的体系结构图 2( 模块的功能 下面将具体介绍各模块的功能: A( 主函数模块 本模块主要是初始化图形显示模式,定义游戏说明窗口以及游戏窗口的界面,还有计分、计时、定 级别窗口的设定。当然应有对其它子模块的调用,如:方块的产生与清除、方块的变换与移动、消行与计分、计时等模块。 B( 方块的产生与清除模块 本模块有两大功能:产生方块、清除方块,分别由void turnUnit(int x,int y,int n)、void clrTurnUnit(int x,int y,int n) 来完成。它们的三个参数中的,与,示操作所在的位置,,决定方块的形状(,、,、,在以后出现的函数中意义相同,将不在重述)。由于每个方块都是四个小方格组合而成,我编了小方格的产生、清除子函数void fangKuai(int x0,int y0)、void clrfangKuai(int x0,int y0)来给上面两个函数调用。x0、y0 表示操作所在的位置。 C( 方块的变换与移动模块 本模块负责方块自动下移,在下移过程中方块的变换、左右移动、加速下移、直接下移的操作,由int move(int x,int y,int n)来完成。 stopB()检测方块可下移时move()将循环检测有无键盘输入,若无输入方块自动下移一小格;否则判断输入是什么,向上方向键则方块顺时针旋转变换一次,向左方向键并且stopL()检测方块可左移则方块向左移一小格,向右方向键并且stopR()检测方块可右移则方块向右移一小格,向下方向键则方块向下移一小格,空格键则直接下移。 D( 消行与计分模块 当一个方块不能移动时需调用本模块clrLine()。本模块将从该方块的最下面小方格所在行开始到最上面小方格所在行结束,从左到右判断每一行是否满行;若满行则消行并且下移该行以上的已填充的小方格,然后调用计分函数,计分函数将给全局变量f加,,此时游戏所得的分数sc为f,10。由于文本输出函数outtextxy()是输出字符串而不支持变量输出,但分数sc是变量,于是用间接的办法:把分数sc的值sprintf()函数存到字符数组buf[3]所在的地址中,由于字符数组中的值相当于字符串,于是用outtextxy()输出便可,字体颜色是红色RED。其实在输出新的分数之前要先把旧的分数擦去,也很简单:用刚才说的办法把旧分数再输出一次,不过这次字体的颜色是背景色GREEN。计分函数还有一个与分数紧密相关的操作定游戏的级别,共分为6个级别:,分到300分为0级,,分到300分为0级,300分到700分为1级,依此类推,1800分到2500分为4级,超过2500分为5级。可以看到,除了每一级要求的分数都比上一级多100分外,方块的自动下移速度也加快(0级的1/13)以增加游戏的挑战性。 E( 计时模块 本模块主要是计算游戏所用的时间,由函数coutTime()完成。游戏开始后,首先用time(0)取得当前时间存在全局变量bgtime中,以后每次调用coutTime()按以下进行:用time(0)取得当时时间存在ntime中,游戏所用的时间为(ntime,bgtime)秒,把它转换成分秒形式后显示出来(用计分显示的方法)。 五(关键技术的研究 ,(界面的设计 运行系统后,在屏幕中央将产生一个窗口,它的四周空间为蓝色,它分 为上面、左下、右下三个小窗口,见右边的示意图。上面的小窗口绿色 为背景显示了游戏的名称“Russia Tarten”,操作说明“Press any key to start. Press Esc to quit. Press Blank to bottom. Press to change the direction and shape.“。左下的小窗口为灰色DARKGRAY,是游戏主窗口 (以下简称窗口,),高为210像素,宽为120像素,即由252(21x12)个10X10的小方格组成。右下的小窗口为绿色,主要显示游戏所用的时间、所得分数、所属级别。 ,(方块的实现 首先说一下函数fangKuai()与函数clrFangKuai()。函数fangKuai()在指定位置产生边框为蓝色用白色WHITE填充的小方格。函数clrFangKuai()在指定位置产生边框与填充色都是窗口,的背景色DARKGRAY的小方格。 其次说方块的产生与清除。各方块及其顺时针旋转变换而来的方块统一在16(,4X4)个小方格的 以下简称窗口,)中用,个小方格表示,建立基于窗口,的坐标系:窗口,左上角的小方格为窗口( (,,,,,),每个小方格长和宽都为,,,方向从左到右,,方向从上到下。用数组xy[8]存储方块的4个小方格在窗口,的坐标参数。具体如下图: ,, , , , ,, ,, , , xy[8]={ 0,-2,0,-1,0,0,0,1} xy[8]={-1,1,0,1,1,1,2,1} ,, ,, , , , ,, , , xy[8]= {-1,0,0,0,0,1,1,1} xy[8]={0,0,-1,1,0,1,1,1} ,, , , , ,, , , , xy[8]={ -1,-1,-1,0,0,0,-1,1} xy[8]={ -1,0,0,0,1,0,0,1} 由于方块(,种)及其变换共有19种,在此仅列出六个方块以说明,剩余方块用类似方法求出它们的xy[8]具体数组。为了便于调用各方块,定义如下数据结构: struct bx { int xy[8]; struct bx *next; } xyh[19]; 结构有两个成员,第一个成员xy[8]存储方块在窗口,中的坐标参数,第二个成员*next为指向该方块顺时针旋转变换而来的方块的地址指针。 在此用同时该结构定义了xyh[19],该数组把19种方块封装在一起,并在游戏开始时完成初始化。 另外定义了全局变量n,它每次取值为0到18,由随机函数产生;游戏中需要产生方块时,调用xyh[n],把方块在窗口,坐标参数转换到窗口,下,再依据参数把方块的四个小方格用函数fangKuai()画出来便可显示所要的方块。清除方块时与产生方块时大部份一样,所不同的是函数fangKuai()变成了函数clrFangKuai()。 ,(方块移动的综合设计 根本思想是: ,、用stopB()判断方块能否下移,不能则跳出move()。 ,、判断有无键盘输入,有则跳到,,无则跳到,。 ,、判断输入是什么: 向上方向键则方块顺时针旋转变换一次; 向左方向键并且stopL()检测方块可左移则方块向左移一小格,不可左移跳到,; 向右方向键并且stopR()检测方块可右移则方块向右移一小格,不可右移跳到,; 向下方向键则方块向下移一小格; 空格键则直接下移。 ,、跳到,。 ,、自动下移一小格,延时半秒,跳到,。 实现移动的办法是把原来的方块清除clrTurnUnit(),在新位置重新画方块TurnUnit()。stopB()、 stopL()、stopR()三个函数极为相似,现以stopL()来说明: 依次判断方块的四个小方格所在位置左边的有无填充,若有,则判断是不是自己填充的,不是自己 填充的便返回“不可移动”;否则四个小方格都检测完后,返回“可移动”。 六(结束语 本次实验历时两周多,是我花时间最多的实验,因为整个实验都在磕磕碰碰中前进,有了问题首先自己想办法解决,不行再找,再不行找老师,一波三折地走到了现在。这其中好多次甚至有了放弃的念头,哪怕有一次自己没有坚持下来,也就没有这份报告了。 下面想说几点编程过程的体会: 一、建议编一段代码后调试一次,不要过长也不要太短,我的经验是完成一两小功能后调试一次。因为过长,给找错误点增加了难度;过短,反复调试的次数太多,令编程效率低下,频繁地切换显示模式对显示器也不好。 二、调试程序发现有一时难以找出的错误时,不要急,要沉着思考,自己在脑中从头开始模拟程序运行,推出错误可能点后,在该点加一些判断标志(如pintf(“OK”)),运行程序,证实出错点,并设法改正。加判断标志要清楚加多少个标志,在哪里加,这也是编程者的编程水平高低的表现。标志多了,在屏幕上看不到,当然你可以在另一个文档中输出来看,不过有点不方便;少了,不能成功判断出错点。 三、当想用一个系统函数,而对其功能只是略知一二时,可以先编一个模拟函数调用该系统函数模拟你所需的功能,看是否符合,合适则采用,否则另谋它法。在实验中我多次用到了这种办法,如:随机函数、键盘操作的相关函数等等。 四、善于请教他人。我每完成一个大的功能都与室友交流,征求他们对该功能的看法,往往有不小的收获,对程序的改进起很大作用,而且也有了不少新思路。 附本实验的源程序:RussiaTarten.C <完> #include"graphics.h" #include"conio.h" #include"stdio.h" #include"time.h" #include"stdlib.h" int f=-1,bgtime,utime[4]={0},bg[21][12]={0};/*background define and initial*/ double j=4990000; struct bx { int xy[8]; struct bx *next; }t,xyh[19]={ {{0,-2,0,-1,0,0,0,1},&xyh[1]}, {{-1,1,0,1,1,1,2,1},&xyh[0]}, {{0,0,1,0,0,1,1,1},&xyh[2]}, {{-1,0,0,0,0,1,1,1},&xyh[4]}, {{1,-1,0,0,1,0,0,1},&xyh[3]}, {{0,0,1,0,-1,1,0,1},&xyh[6]}, {{0,-1,0,0,1,0,1,1},&xyh[5]}, {{0,0,-1,1,0,1,1,1},&xyh[8]}, {{-1,-1,-1,0,0,0,-1,1},&xyh[9]}, {{-1,0,0,0,1,0,0,1},&xyh[10]}, {{0,-1,-1,0,0,0,0,1},&xyh[7]}, {{1,-1,1,0,0,1,1,1},&xyh[12]}, {{0,0,0,1,1,1,2,1},&xyh[13]}, {{0,-1,1,-1,0,0,0,1},&xyh[14]}, {{0,0,1,0,2,0,2,1},&xyh[11]}, {{0,-1,0,0,0,1,1,1},&xyh[16]}, {{0,0,1,0,2,0,0,1},&xyh[17]}, {{0,-1,1,-1,1,0,1,1},&xyh[18]}, {{2,0,0,1,1,1,2,1},&xyh[15]} }; void coutTime(); void score(); int getN(struct bx *t1); void fangKuai(int x0,int y0); void clrfangKuai(int x0,int y0); int move(int x,int y,int n); int c72(int x,int y,int n); int c75(int x,int y,int n); int c77(int x,int y,int n); int c80(int x,int y,int n); void turnUnit(int x,int y,int n); void clrTurnUnit(int x,int y,int n); void clrLine(int y); int stopL(int x,int y,int n); int stopR(int x,int y,int n); int stopB(int x,int y,int n); main() { int i,j,k,n=0,x=50,y=20,quit=0; int graphdriver,graphmode; char dbuf[4]={24,25,26,27}; graphdriver=DETECT; initgraph(&graphdriver,&graphmode,"c:\\tc2"); setviewport(240,50,460,170,1);/*define the top text window*/ clearviewport(); setbkcolor(BLUE); setfillstyle(SOLID_FILL,GREEN); bar(0,0,219,119); setcolor(WHITE); rectangle(0,1,219,119); outtextxy(50,6,"Russia Tarten"); outtextxy(5,16,"Press any key to start."); outtextxy(5,36,"Press Esc to quit."); outtextxy(5,56,"Press Blank to bottom."); outtextxy(50,76,dbuf); setcolor(GREEN); outtextxy(82,76,(dbuf+4)); setcolor(WHITE); outtextxy(5,76,"Press to change the"); outtextxy(5,86,"direction and shape."); setcolor(YELLOW); outtextxy(5,106,"Copyright (2004-2006)"); setviewport(240,170,460,380,1);/*define the bottom game window*/ clearviewport(); setcolor(WHITE); rectangle(120,0,219,209); setcolor(BLUE); setfillstyle(SOLID_FILL,DARKGRAY); bar(0,0,119,209); setfillstyle(SOLID_FILL,GREEN); bar(121,1,218,208); outtextxy(130,56,"Used Time:"); outtextxy(175,66,"m s"); outtextxy(130,86,"Score:"); outtextxy(130,116,"Level:");/*1,2,3,4,5*/ setcolor(YELLOW); outtextxy(125,180,"Gevon.Huang"); getch();/*press any key to start the game*/ loop: bgtime=time(0); coutTime(); score(); for(k=0;k<990;k++) { srand(time(NULL)); n=rand()%19;/*n is random*/ turnUnit(x,y,n); quit=move(x,y,n); if(k==989) {/*arrive at the top level*/ outtextxy(2,85,"Game over!"); outtextxy(2,100,"Press R to"); outtextxy(2,110,"replay!!!!"); } if(quit==1) { k=990;/*quit or replay*/ outtextxy(2,85,"Press R to"); outtextxy(2,95,"replay!!!!"); } } while(quit!=27) {/*press "escape" to quit*/ if(kbhit()!=0) quit=getch(); if(quit==114) {/*press "r" to replay*/ for(i=0;i<21;i++) for(j=0;j<12;j++) clrfangKuai(j*10,i*10); setfillstyle(SOLID_FILL,GREEN); bar(175,96,217,136); f=-1; goto loop; } } closegraph(); } void coutTime() { int ntime; char bufs[3]={'0','0','0'},lbufs[3]={'0','0','0'},bufm[3]={'0','0','0'},lbufm[3]={'0','0','0'}; ntime=time(0); utime[1]=utime[0];/*save last*/ utime[3]=utime[2];/*save last*/ utime[0]=ntime-bgtime;/*get now-used*/ utime[2]=utime[0]/60;/*get now-used minute*/ utime[0]=utime[0]%60;/*get now-used second*/ setcolor(GREEN);/*clear*/ sprintf(lbufs,"%d",utime[1]); outtextxy(190,66,lbufs); sprintf(lbufm,"%d",utime[3]); outtextxy(160,66,lbufm); setcolor(RED);/*write*/ sprintf(bufs,"%d",utime[0]); outtextxy(190,66,bufs); sprintf(bufm,"%d",utime[2]); outtextxy(160,66,bufm); } void score() { int sc,lsc; char buf[3]={'0','0','0'},lbuf[3]={'0','0','0'}; f=f+1; sc=10*f; lsc=sc-10; sprintf(buf,"%d",sc); sprintf(lbuf,"%d",lsc); setcolor(GREEN);/*clear*/ if(f==30) outtextxy(175,116,"0"); if(f==70) outtextxy(175,116,"1"); if(f==120) outtextxy(175,116,"2"); if(f==180) outtextxy(175,116,"3"); if(f==250) outtextxy(175,116,"4"); outtextxy(175,96,lbuf); setcolor(RED);/*write and change the speed of moving down*/ if(f==0) outtextxy(175,116,"0"); if(f==30) {outtextxy(175,116,"1"); j=j-500000;} if(f==70) {outtextxy(175,116,"2"); j=j-500000;} if(f==120) {outtextxy(175,116,"3"); j=j-500000;} if(f==180) {outtextxy(175,116,"4"); j=j-500000;} if(f==250) {outtextxy(175,116,"5"); j=j-500000;} outtextxy(175,96,buf); } void fangKuai(int x0,int y0) {/*define the min-unit tarten*/ int i; bg[y0/10][x0/10]=1; for(i=0;i<10;i++) {putpixel(x0+i,y0,0); putpixel(x0+i,y0+9,0); } y0=y0+1; for(i=0;i<8;i++) {putpixel(x0,y0+i,0); putpixel(x0+9,y0+i,0); } setfillstyle(SOLID_FILL,WHITE); bar(x0+1,y0,x0+8,y0+7); } void clrfangKuai(int x0,int y0) {/*clear the min-unit tarten*/ bg[y0/10][x0/10]=0; setfillstyle(SOLID_FILL,DARKGRAY); bar(x0,y0,x0+9,y0+9); } int move(int x,int y,int n) { int key=-1; double i; while(stopB(x,y,n)!=1) {/* when it is at bottom or there is other tarten below go to quit */ if(kbhit()!=0) key=getch(); else key=-1; if(key==0) continue; if(key==27) return(1); switch(key) { case 72:/*"up key" means turning*/ clrTurnUnit(x,y,n); n=c72(x,y,n); for(i=0;iy0-3;i--) for(j=0;j<12;j++) { if(bg[i][j]==0) j=13;/*there is null,go to next i*/ if(j==11)/*it is full,clear one line*/ { for(i2=0;i2<5;i2++) {/*blink and clear*/ for(k=0;k<3000000;k++); for(k=0;k<12;k++) { if(i2==0||i2==2||i2==4) clrfangKuai(k*10,i*10); if(i2==1||i2==3) fangKuai(k*10,i*10); } } for(i2=i-1;i2>-1;i2--) for(j2=0;j2<12;j2++) {/*the up tartens move down once*/ if(bg[i2][j2]==1) { clrfangKuai(j2*10,i2*10); fangKuai(j2*10,(i2+1)*10); } } score(); i=i+1; y0=y0+1; } } } int stopL(int x,int y,int n) {/*test when should stop on left side*/ int i0,i,j,i1,x0=x/10,y0=y/10,dx=-1,dy=0; for(i0=0;i0<4;i0++) { j=x0+xyh[n].xy[2*i0]+dx; i=y0+xyh[n].xy[2*i0+1]+dy; i1=i0+dx;/*to its left tarten*/ if(bg[i][j]==1) {/*there is tarten on left side*/ if((j==(x0+xyh[n].xy[2*i1]))&&(i==(y0+xyh[n].xy[2*i1+1]))&&(i0!=0)) continue;/*the tarten is one of its tartens*/ return(1);/*the tarten is other's,return "stop"*/ } } return(0);/*return "move"*/ } int stopR(int x,int y,int n) {/*test when should stop on right side*/ int i0,i,j,i1,x0=x/10,y0=y/10,dx=1,dy=0; for(i0=0;i0<4;i0++) { j=x0+xyh[n].xy[2*i0]+dx; i=y0+xyh[n].xy[2*i0+1]+dy; i1=i0+dx;/*to its right tarten*/ if(bg[i][j]==1) {/*there is tarten on right side*/ if((j==(x0+xyh[n].xy[2*i1]))&&(i==(y0+xyh[n].xy[2*i1+1]))&&(i0!=3)) continue;/*the tarten is one of its tartens*/ return(1);/*the tarten is other's,return "stop"*/ } } return(0);/*return "move"*/ } int stopB(int x,int y,int n) {/*test when should stop on bottom*/ int i0=-1,i,j,i1,bj,x0=x/10,y0=y/10; if(y==190) return(1);/*arrive bottom,return "stop"*/ loop: if((i0=i0+1)<4) { j=x0+xyh[n].xy[2*i0]; i=y0+xyh[n].xy[2*i0+1]+1; if(bg[i][j]==1) {/*there is a tarten on bottom*/ i1=i0+1;/*to its next tarten*/ while(i1<4) { if((j==(x0+xyh[n].xy[2*i1]))&&(i==(y0+xyh[n].xy[2*i1+1]))&&(i0!=3)==1) goto loop;/*the tarten is one of its tartens,complete this loop*/ i1++; } return(1);/*the tarten is other's,return "stop"*/ } goto loop; } return(0);/*there isn't any tarten on bottom,return "move"*/ } int getN(struct bx *t1) {/*get next n*/ int n; n=t1->next-&xyh[0]; return (n); } _
/
本文档为【C语言俄罗斯方块试验报告,包括源程序】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。 本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。 网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。

历史搜索

    清空历史搜索