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

上传人:b****6 文档编号:4152857 上传时间:2022-11-28 格式:DOCX 页数:18 大小:303.41KB
下载 相关 举报
C语言俄罗斯方块试验报告包括源程序.docx_第1页
第1页 / 共18页
C语言俄罗斯方块试验报告包括源程序.docx_第2页
第2页 / 共18页
C语言俄罗斯方块试验报告包括源程序.docx_第3页
第3页 / 共18页
C语言俄罗斯方块试验报告包括源程序.docx_第4页
第4页 / 共18页
C语言俄罗斯方块试验报告包括源程序.docx_第5页
第5页 / 共18页
点击查看更多>>
下载资源
资源描述

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

《C语言俄罗斯方块试验报告包括源程序.docx》由会员分享,可在线阅读,更多相关《C语言俄罗斯方块试验报告包括源程序.docx(18页珍藏版)》请在冰豆网上搜索。

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

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

1.实验题

设计完成俄罗斯方块游戏。

游戏开始后在游戏小窗口的顶部会随机产生一个方块并以一定的速度下

移,下移过程玩家作变换、左右移操作以使其摆放合适,当叠满一行时会自动消去并计10分,若不能

消行而叠到游戏小窗口的顶部则游戏失败,此时玩家可退出或重新开始。

二•实验要求与目的

游戏界面合理,进入游戏后应有操作说明。

要求:

⑴按任意键开始游戏,随机产生方块并自动下移

⑵用Esc键退出游戏,R键可重新开始游戏

⑶用f键变换方块

⑷用键和―键左右移动方块

⑸用J键使方块加速下移

⑹用空格键使方块直接下移

⑺能正确判断满行并消行、计分、定级别

⑻能正确计时

⑼设定游戏为五个级别,级别越高难度越大

目的是通过设计完成俄罗斯方块游戏,加深对计算机图形学的认识并在实践中加以应用,此外进一步熟

悉应用编程语言。

三.实验环境

硬件:

CPU

——AMDAthlonXP1800+

内存

-----DDR333256M

硬盘

-----40G

显示卡------

-----Max44064M128bit

显示器------

-----17寸彩显

软件:

OS

——WindowsXP

开发工具--

TuborC2.0

四•系统的设计思想

1.系统的体系结构

本系统主要由主函数、方块的产生与清除、方块的变换与移动、消行与计分、计时这五大模块组成,其中方块的变换与移动模块是本系统中的关键模块,也是最为复杂的模块。

详情请参考以下的结构图:

move()

clrLine()

turnUnit()、clrTurnUnit

coutTime()

俄罗斯方块的体系结构图

2.模块的功能

下面将具体介绍各模块的功能:

A.主函数模块

本模块主要是初始化图形显示模式,定义游戏说明窗口以及游戏窗口的界面,还有计分、计时、定

级别窗口的设定。

当然应有对其它子模块的调用,如:

方块的产生与清除、方块的变换与移动、消行与计分、计时等模块。

B•方块的产生与清除模块

本模块有两大功能:

产生方块、清除方块,分别由voidturnUnit(intx,inty,intn)、voidclrTurnUnit(intx,inty,intn)来完成。

它们的三个参数中的X与Y表示操作所在的位置,N决定方块的形状(X、Y、

N在以后出现的函数中意义相同,将不在重述)。

由于每个方块都是四个小方格组合而成,我编了小方

格的产生、清除子函数voidfangKuai(intx0,inty0)、voidclrfangKuai(intx0,inty0)来给上面两个函数调用。

x0、y0表示操作所在的位置。

C•方块的变换与移动模块

本模块负责方块自动下移,在下移过程中方块的变换、左右移动、加速下移、直接下移的操作,由

intmove(intx,inty,intn)来完成。

stopB()检测方块可下移时move()将循环检测有无键盘输入,若无输入方块自动下移一小格;否则判断输入是什么,向上方向键则方块顺时针旋转变换一次,向左方向键并且

stopL()检测方块可左移则方块向左移一小格,向右方向键并且stopR()检测方块可右移则方块向右移一

小格,向下方向键则方块向下移一小格,空格键则直接下移。

D•消行与计分模块

当一个方块不能移动时需调用本模块clrLine()。

本模块将从该方块的最下面小方格所在行开始到最

上面小方格所在行结束,从左到右判断每一行是否满行;若满行则消行并且下移该行以上的已填充的小

方格,然后调用计分函数,计分函数将给全局变量f加1,此时游戏所得的分数sc为fX10。

由于文本

输出函数outtextxy()是输出字符串而不支持变量输出,但分数sc是变量,于是用间接的办法:

把分数sc的值sprintf()函数存到字符数组buf[3]所在的地址中,由于字符数组中的值相当于字符串,于是用

outtextxy()输出便可,字体颜色是红色RED。

其实在输出新的分数之前要先把旧的分数擦去,方法也很

简单:

用刚才说的办法把旧分数再输出一次,不过这次字体的颜色是背景色GREEN。

计分函数还有一

个与分数紧密相关的操作定游戏的级别,共分为6个级别:

0分到300分为0级,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)秒,把它转换成分秒形式后显示出来(用计分显示的方法)。

五.关键技术的研究

1•界面的设计

运行系统后,在屏幕中央将产生一个窗口,它的四周空间为蓝色,它分为上面、左下、右下三个小窗口,见右边的示意图。

上面的小窗口绿色为背景显示了游戏的名称"RussiaTarten”操作说明"Pressanykeytostart.

PressEsctoquit.PressBlanktobottom.Press卓*亠*tochangethe

directionandshape."。

左下的小窗口为灰色DARKGRAY,是游戏主窗口

(以下简称窗口M),高为210像素,宽为120像素,即由252(21x12)个10X10的小方格组成。

右下的小窗口为绿色,主要显示游戏所用的时间、所得分数、所属级别。

2•方块的实现

首先说一下函数fangKuai()与函数clrFangKuai()。

函数fangKuai()在指定位置产生边框为蓝色用白色WHITE填充的小方格。

函数clrFangKuai()在指定位置产生边框与填充色都是窗口M的背景色

DARKGRAY的小方格。

其次说方块的产生与清除。

各方块及其顺时针旋转变换而来的方块统一在16(=4X4)个小方格的

窗口(以下简称窗口L)中用4个小方格表示,建立基于窗口L的坐标系:

窗口L左上角的小方格为

(—1,—2),每个小方格长和宽都为1,X方向从左到右,Y方向从上到下。

用数组xy[8]存储方块

的4个小方格在窗口L的坐标参数。

具体如下图:

 

xy[8]={-1,0,0,0,1,0,0,1}

19种,在此仅列出六个方块以说明,剩余方块用类似方法求出它

们的xy[8]具体数组。

为了便于调用各方块,定义如下数据结构:

structbx{

intxy[8];

structbx*next;

}xyh[19];

结构有两个成员,第一个成员xy[8]存储方块在窗口L中的坐标参数,第二个成员*next为指向该方块顺时针旋转变换而来的方块的地址指针。

在此用同时该结构定义了xyh[19],该数组把19种方块封装在一起,并在游戏开始时完成初始化。

另外定义了全局变量n,它每次取值为0到18,由随机函数产生;游戏中需要产生方块时,调用xyh[n],

把方块在窗口L坐标参数转换到窗口M下,再依据参数把方块的四个小方格用函数fangKuai()画出来便

可显示所要的方块。

清除方块时与产生方块时大部份一样,所不同的是函数fangKuai()变成了函数

clrFangKuai()。

3•方块移动的综合设计根本思想是:

1、用stopB()判断方块能否下移,不能则跳出move()。

2、判断有无键盘输入,有则跳到3,无则跳到5。

3、判断输入是什么:

向上方向键则方块顺时针旋转变换一次;

向左方向键并且stopL()检测方块可左移则方块向左移一小格,不可左移跳到1;向右方向键并且stopR()检测方块可右移则方块向右移一小格,不可右移跳到1;向下方向键则方块向下移一小格;空格键则直接下移。

4、跳到1。

5、自动下移一小格,延时半秒,跳到1。

实现移动的办法是把原来的方块清除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"

intf=-1,bgtime,utime[4]={0},bg[21][12]={0};/*backgrounddefineandinitial*/doublej=4990000;

structbx

{

intxy[8];

structbx*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]}

};

voidcoutTime();

voidscore();

intgetN(structbx*t1);

voidfangKuai(intx0,inty0);

voidclrfangKuai(intx0,inty0);

intmove(intx,inty,intn);

intc72(intx,inty,intn);

intc75(intx,inty,intn);

intc77(intx,inty,intn);

intc80(intx,inty,intn);

voidturnUnit(intx,inty,intn);

voidclrTurnUnit(intx,inty,intn);

voidclrLine(inty);

intstopL(intx,inty,intn);

intstopR(intx,inty,intn);

intstopB(intx,inty,intn);

main()

{

inti,j,k,n=0,x=50,y=20,quit=0;

intgraphdriver,graphmode;

chardbuf[4]={24,25,26,27};

graphdriver=DETECT;initgraph(&graphdriver,&graphmode,"c:

\\tc2");

setviewport(240,50,460,170,1);/*definethetoptextwindow*/clearviewport();

setbkcolor(BLUE);setfillstyle(SOLID_FILL,GREEN);

bar(0,0,219,119);

setcolor(WHITE);rectangle(0,1,219,119);

outtextxy(50,6,"RussiaTarten");

outtextxy(5,16,"Pressanykeytostart".);

outtextxy(5,36,"PressEsctoquit".);

outtextxy(5,56,"PressBlanktobottom.");outtextxy(50,76,dbuf);

setcolor(GREEN);outtextxy(82,76,(dbuf+4));

setcolor(WHITE);outtextxy(5,76,"Presstochangethe");outtextxy(5,86,"directionandshape".);

setcolor(YELLOW);outtextxy(5,106,"Copyright(2004-2006)");

setviewport(240,170,460,380,1);/*definethebottomgamewindow*/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,"UsedTime:

");outtextxy(175,66,"ms");outtextxy(130,86,"Score:

");outtextxy(130,116,"Level:

");/*1,2,3,4,5*/

setcolor(YELLOW);

outtextxy(125,180,"Gevon.Huang");

getch();/*pressanykeytostartthegame*/loop:

bgtime=time(0);

coutTime();

score();

for(k=0;k<990;k++)

{

srand(time(NULL));

n=rand()%19;/*nisrandom*/

turnUnit(x,y,n);

quit=move(x,y,n);

if(k==989)

{/*arriveatthetoplevel*/

outtextxy(2,85,"Gameover!

");outtextxy(2,100,"PressRto");outtextxy(2,110,"replay!

!

!

!

");

}

if(quit==1)

{k=990;/*quitorreplay*/outtextxy(2,85,"PressRto");outtextxy(2,95,"replay!

!

!

!

");

}

}

while(quit!

=27)

{/*press"escape"toquit*/

if(kbhit()!

=0)

quit=getch();

if(quit==114)

{/*press"r"toreplay*/

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;gotoloop;

}

}

closegraph();

voidcoutTime()

{

intntime;

charbufs[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];/*savelast*/

utime[3]=utime[2];/*savelast*/utime[0]=ntime-bgtime;/*getnow-used*/utime[2]=utime[0]/60;/*getnow-usedminute*/utime[0]=utime[0]%60;/*getnow-usedsecond*/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);

}

voidscore()

{

intsc,lsc;

charbuf[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);/*writeandchangethespeedofmovingdown*/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);

}

voidfangKuai(intx0,inty0){/*definethemin-unittarten*/inti;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);

}

voidclrfangKuai(intx0,inty0){/*clearthemin-unittarten*/bg[y0/10][x0/10]=0;setfillstyle(SOLID_FILL,DARKGRAY);bar(x0,y0,x0+9,y0+9);

}

intmove(intx,inty,intn)

{

intkey=-1;doublei;

while(stopB(x,y,n)!

=1)

{/*whenitisatbottomorthereisothertartenbelowgotoquit*/if(kbhit()!

=0)key=getch();

elsekey=-1;

if(key==0)continue;

if(key==27)return

(1);

switch(key)

{

case72:

/*"upkey"meansturning*/clrTurnUnit(x,y,n);n=c72(x,y,n);for(i=0;i

case75:

/*"leftkey"meanstomoveleft*/if(stopL(x,y,n)!

=0)break;clrTurnUnit(x,y,n);x=c75(x,y,n);for(i=0;i

case77:

/*"rightkey"meanstomoveright*/if(stopR(x,y,n)!

=0)break;

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 初中教育 > 政史地

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1