C语言俄罗斯方块试验报告,包括源程序.doc_第1页
C语言俄罗斯方块试验报告,包括源程序.doc_第2页
C语言俄罗斯方块试验报告,包括源程序.doc_第3页
C语言俄罗斯方块试验报告,包括源程序.doc_第4页
C语言俄罗斯方块试验报告,包括源程序.doc_第5页
已阅读5页,还剩12页未读 继续免费阅读

下载本文档

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

文档简介

实验内容 游戏程序-俄罗斯方块 指导老师 李陶深一 实验题目设计完成俄罗斯方块游戏。游戏开始后在游戏小窗口的顶部会随机产生一个方块并以一定的速度下移,下移过程玩家作变换、左右移操作以使其摆放合适,当叠满一行时会自动消去并计10分,若不能消行而叠到游戏小窗口的顶部则游戏失败,此时玩家可退出或重新开始。二 实验要求与目的游戏界面合理,进入游戏后应有操作说明。要求:按任意键开始游戏,随机产生方块并自动下移用Esc键退出游戏,键可重新开始游戏用键变换方块用键和 键左右移动方块用键使方块加速下移用空格键使方块直接下移能正确判断满行并消行、计分、定级别能正确计时设定游戏为五个级别,级别越高难度越大目的是通过设计完成俄罗斯方块游戏,加深对计算机图形学的认识并在实践中加以应用,此外进一步熟悉应用编程语言。三 实验环境硬件:CPU-AMD AthlonXP 1800+ 内存-DDR333 256M 硬盘-40G 显示卡-Max440 64M 128bit 显示器-17寸彩显软件:OS-Windows XP开发工具-Tubor C 2.0四 系统的设计思想1 系统的体系结构本系统主要由主函数、方块的产生与清除、方块的变换与移动、消行与计分、计时这五大模块组成,其中方块的变换与移动模块是本系统中的关键模块,也是最为复杂的模块。详情请参考以下的结构图:主函数Main( )方块的产生与清除 turnUnit()、clrTurnUnit()方块的变换与移动move()消行与计分clrLine()小方格的产生fangKuai()、小方格 的清除clrFangKuai()方块的变换c72()、getN()方块的下移与左右移c75()、c77()方块左、右、下的停止stopL()、stopR()、stopB()计分score()计时coutTime() 俄罗斯方块的体系结构图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为f10。由于文本输出函数outtextxy()是输出字符串而不支持变量输出,但分数sc是变量,于是用间接的办法:把分数sc的值sprintf()函数存到字符数组buf3所在的地址中,由于字符数组中的值相当于字符串,于是用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中,游戏所用的时间为(ntimebgtime)秒,把它转换成分秒形式后显示出来(用计分显示的方法)。五 关键技术的研究 界面的设计运行系统后,在屏幕中央将产生一个窗口,它的四周空间为蓝色,它分为上面、左下、右下三个小窗口,见右边的示意图。上面的小窗口绿色为背景显示了游戏的名称“Russia Tarten”,操作说明“Press any key to start.Press Esc to quit. Press Blank to bottom. Press to change thedirection and shape.“。左下的小窗口为灰色DARKGRAY,是游戏主窗口(以下简称窗口),高为210像素,宽为120像素,即由252(21x12)个10X10的小方格组成。右下的小窗口为绿色,主要显示游戏所用的时间、所得分数、所属级别。 方块的实现首先说一下函数fangKuai()与函数clrFangKuai()。函数fangKuai()在指定位置产生边框为蓝色用白色WHITE填充的小方格。函数clrFangKuai()在指定位置产生边框与填充色都是窗口的背景色DARKGRAY的小方格。其次说方块的产生与清除。各方块及其顺时针旋转变换而来的方块统一在16(4X4)个小方格的窗口(以下简称窗口)中用个小方格表示,建立基于窗口的坐标系:窗口左上角的小方格为(,),每个小方格长和宽都为,方向从左到右,方向从上到下。用数组xy8存储方块的4个小方格在窗口的坐标参数。具体如下图:xy8= 0,-2,0,-1,0,0,0,1 xy8=-1,1,0,1,1,1,2,1 xy8= -1,0,0,0,0,1,1,1 xy8=0,0,-1,1,0,1,1,1 xy8= -1,-1,-1,0,0,0,-1,1 xy8= -1,0,0,0,1,0,0,1由于方块(种)及其变换共有19种,在此仅列出六个方块以说明,剩余方块用类似方法求出它们的xy8具体数组。为了便于调用各方块,定义如下数据结构:struct bx int xy8; struct bx *next; xyh19;结构有两个成员,第一个成员xy8存储方块在窗口中的坐标参数,第二个成员*next为指向该方块顺时针旋转变换而来的方块的地址指针。在此用同时该结构定义了xyh19,该数组把19种方块封装在一起,并在游戏开始时完成初始化。另外定义了全局变量n,它每次取值为0到18,由随机函数产生;游戏中需要产生方块时,调用xyhn,把方块在窗口坐标参数转换到窗口下,再依据参数把方块的四个小方格用函数fangKuai()画出来便可显示所要的方块。清除方块时与产生方块时大部份一样,所不同的是函数fangKuai()变成了函数clrFangKuai()。 方块移动的综合设计根本思想是:、用stopB()判断方块能否下移,不能则跳出move()。、判断有无键盘输入,有则跳到,无则跳到。、判断输入是什么:向上方向键则方块顺时针旋转变换一次;向左方向键并且stopL()检测方块可左移则方块向左移一小格,不可左移跳到;向右方向键并且stopR()检测方块可右移则方块向右移一小格,不可右移跳到;向下方向键则方块向下移一小格;空格键则直接下移。、跳到。、自动下移一小格,延时半秒,跳到。实现移动的办法是把原来的方块清除clrTurnUnit(),在新位置重新画方块TurnUnit()。stopB()、stopL()、stopR()三个函数极为相似,现以stopL()来说明:依次判断方块的四个小方格所在位置左边的有无填充,若有,则判断是不是自己填充的,不是自己填充的便返回“不可移动”;否则四个小方格都检测完后,返回“可移动”。六 结束语本次实验历时两周多,是我花时间最多的实验,因为整个实验都在磕磕碰碰中前进,有了问题首先自己想办法解决,不行再找书,再不行找老师,一波三折地走到了现在。这其中好多次甚至有了放弃的念头,哪怕有一次自己没有坚持下来,也就没有这份报告了。下面想说几点编程过程的体会:一、建议编一段代码后调试一次,不要过长也不要太短,我的经验是完成一两小功能后调试一次。因为过长,给找错误点增加了难度;过短,反复调试的次数太多,令编程效率低下,频繁地切换显示模式对显示器也不好。二、调试程序发现有一时难以找出的错误时,不要急,要沉着思考,自己在脑中从头开始模拟程序运行,推出错误可能点后,在该点加一些判断标志(如pintf(“OK”)),运行程序,证实出错点,并设法改正。加判断标志要清楚加多少个标志,在哪里加,这也是编程者的编程水平高低的表现。标志多了,在屏幕上看不到,当然你可以在另一个文档中输出来看,不过有点不方便;少了,不能成功判断出错点。三、当想用一个系统函数,而对其功能只是略知一二时,可以先编一个模拟函数调用该系统函数模拟你所需的功能,看是否符合,合适则采用,否则另谋它法。在实验中我多次用到了这种办法,如:随机函数、键盘操作的相关函数等等。四、善于请教他人。我每完成一个大的功能都与室友交流,征求他们对该功能的看法,往往有不小的收获,对程序的改进起很大作用,而且也有了不少新思路。附本实验的源程序:RussiaTarten.C#includegraphics.h#includeconio.h#includestdio.h#includetime.h#includestdlib.hint f=-1,bgtime,utime4=0,bg2112=0;/*background define and initial*/double j=4990000;struct bxint xy8;struct bx *next;t,xyh19=0,-2,0,-1,0,0,0,1,&xyh1,-1,1,0,1,1,1,2,1,&xyh0,0,0,1,0,0,1,1,1,&xyh2,-1,0,0,0,0,1,1,1,&xyh4,1,-1,0,0,1,0,0,1,&xyh3,0,0,1,0,-1,1,0,1,&xyh6,0,-1,0,0,1,0,1,1,&xyh5,0,0,-1,1,0,1,1,1,&xyh8,-1,-1,-1,0,0,0,-1,1,&xyh9,-1,0,0,0,1,0,0,1,&xyh10,0,-1,-1,0,0,0,0,1,&xyh7,1,-1,1,0,0,1,1,1,&xyh12,0,0,0,1,1,1,2,1,&xyh13,0,-1,1,-1,0,0,0,1,&xyh14,0,0,1,0,2,0,2,1,&xyh11,0,-1,0,0,0,1,1,1,&xyh16,0,0,1,0,2,0,0,1,&xyh17,0,-1,1,-1,1,0,1,1,&xyh18,2,0,0,1,1,1,2,1,&xyh15;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 dbuf4=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;k990;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;i21;i+)for(j=0;j12;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 bufs3=0,0,0,lbufs3=0,0,0,bufm3=0,0,0,lbufm3=0,0,0; ntime=time(0); utime1=utime0;/*save last*/ utime3=utime2;/*save last*/ utime0=ntime-bgtime;/*get now-used*/ utime2=utime0/60;/*get now-used minute*/ utime0=utime0%60;/*get now-used second*/ setcolor(GREEN);/*clear*/ sprintf(lbufs,%d,utime1); outtextxy(190,66,lbufs); sprintf(lbufm,%d,utime3); outtextxy(160,66,lbufm); setcolor(RED);/*write*/ sprintf(bufs,%d,utime0); outtextxy(190,66,bufs); sprintf(bufm,%d,utime2); outtextxy(160,66,bufm);void score() int sc,lsc; char buf3=0,0,0,lbuf3=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; bgy0/10x0/10=1; for(i=0;i10;i+) putpixel(x0+i,y0,0); putpixel(x0+i,y0+9,0); y0=y0+1; for(i=0;i8;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*/bgy0/10x0/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;ij;i+);break;case 75:/*left key means to move left*/if(stopL(x,y,n)!=0)break;clrTurnUnit(x,y,n);x=c75(x,y,n);for(i=0;ij;i+);break;case 77:/*right key means to move right*/if(stopR(x,y,n)!=0)break; clrTurnUnit(x,y,n);x=c77(x,y,n);for(i=0;ij;i+);break;case 80:/*down key means to move down faster*/ clrTurnUnit(x,y,n);y=c80(x,y,n);for(i=0;ij;i+);break;case 32:/*move derectly to bottom*/ while(stopB(x,y,n)!=1)clrTurnUnit(x,y,n); y=c80(x,y,n);for(i=0;ij;i+);break;case -1:/*auto to move down*/for(i=0;ij+3000000;i+);clrTurnUnit(x,y,n);y=c80(x,y,n);for(i=0;ij+3000000;i+);coutTime();break;/*switch*/*while*/clrLine(y);return(0);int c72(int x,int y,int n)if(y=190)/*bottom*/turnUnit(x,y,n);return(n);else if(n=0)&(x=0)|(x=100)|(x=110)/*the special tarten*/turnUnit(x,y,n);return(n);else if(n=8)|(n=10)&(x=110)/*right*/turnUnit(x,y,n);return(n);else if(n=2)|(n=3)|(n=4)|(n=5)|(n=6)|(n=7)|(n=9)|(n=11)|(n=13)|(n=15)|(n=17)&(x=100)/*right*/turnUnit(x,y,n);return(n);else if(n=2)|(n=4)|(n=6)|(n=11)|(n=12)|(n=13)|(n=14)|(n=15)|(n=16)|(n=17)|(n=18)&(x=0)/*left*/turnUnit(x,y,n);return(n);else /*go turning*/n=getN(&xyhn); turnUnit(x,y,n);return(n);int c75(int x,int y,int n)if(y=190)/*bottom*/turnUnit(x,y,n);return(x);if(n=1)|(n=3)|(n=5)|(n=7)|(n=8)|(n=9)|(n=10)x=(x=10)?10:x-10;turnUnit(x,y,n); return(x);x=(x=0)?0:x-10;turnUnit(x,y,n);return(x);int c77(int x,int y,int n)if(y=190)/*bottom*/turnUnit(x,y,n);return(x);else if(n=0)|(n=8)|(n=10)x=(x=110)?110:x+10; turnUnit(x,y,n); return(x);else if(n=1)|(n=12)|(n=14)|(n=16)|(n=18)x=(x=90)?90:x+10; turnUnit(x,y,n); return(x);else x=(x=100)?100:x+10; turnUnit(x,y,n);return(x);int c80(int x,int y,int n)if(0=stopB(x,y,n)y=y+10;turnUnit(x,y,n);return(y);turnUnit(x,y,n);return(y);void turnUnit(int x,int y,int n)/*transfer coordinate system to game window and draw the model*/int i,x0,y0;for(i=0;i4;i+)x0=x+xyhn.xy2*i*10;y0=y+xyhn.xy2*i+1*10;fangKuai(x0,y0);void clrTurnUnit(int x,int y,int n)/*transfer coordinate system to game window and clear the model*/int i,x0,y0;for(i=0;iy0-3;i-)for(j=0;j12;j+)if(bgij=0)j=13;/*there is null,go to next i*/if(j=11)/*it is full,clear one line*/for(i2=0;i25;i2+)/*blink and clear*/for(k=0;k3000000;k+);for(k=0;k-1;i2-)for(j2=0;j212;j2+)/*the up tart

温馨提示

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

评论

0/150

提交评论