俄罗斯方块Word文档下载推荐.docx

上传人:b****2 文档编号:6060516 上传时间:2023-05-06 格式:DOCX 页数:34 大小:130.89KB
下载 相关 举报
俄罗斯方块Word文档下载推荐.docx_第1页
第1页 / 共34页
俄罗斯方块Word文档下载推荐.docx_第2页
第2页 / 共34页
俄罗斯方块Word文档下载推荐.docx_第3页
第3页 / 共34页
俄罗斯方块Word文档下载推荐.docx_第4页
第4页 / 共34页
俄罗斯方块Word文档下载推荐.docx_第5页
第5页 / 共34页
俄罗斯方块Word文档下载推荐.docx_第6页
第6页 / 共34页
俄罗斯方块Word文档下载推荐.docx_第7页
第7页 / 共34页
俄罗斯方块Word文档下载推荐.docx_第8页
第8页 / 共34页
俄罗斯方块Word文档下载推荐.docx_第9页
第9页 / 共34页
俄罗斯方块Word文档下载推荐.docx_第10页
第10页 / 共34页
俄罗斯方块Word文档下载推荐.docx_第11页
第11页 / 共34页
俄罗斯方块Word文档下载推荐.docx_第12页
第12页 / 共34页
俄罗斯方块Word文档下载推荐.docx_第13页
第13页 / 共34页
俄罗斯方块Word文档下载推荐.docx_第14页
第14页 / 共34页
俄罗斯方块Word文档下载推荐.docx_第15页
第15页 / 共34页
俄罗斯方块Word文档下载推荐.docx_第16页
第16页 / 共34页
俄罗斯方块Word文档下载推荐.docx_第17页
第17页 / 共34页
俄罗斯方块Word文档下载推荐.docx_第18页
第18页 / 共34页
俄罗斯方块Word文档下载推荐.docx_第19页
第19页 / 共34页
俄罗斯方块Word文档下载推荐.docx_第20页
第20页 / 共34页
亲,该文档总共34页,到这儿已超出免费预览范围,如果喜欢就下载吧!
下载资源
资源描述

俄罗斯方块Word文档下载推荐.docx

《俄罗斯方块Word文档下载推荐.docx》由会员分享,可在线阅读,更多相关《俄罗斯方块Word文档下载推荐.docx(34页珍藏版)》请在冰点文库上搜索。

俄罗斯方块Word文档下载推荐.docx

玩家进入游戏后,将有对本游戏如何操作的友情提示。

1.2系统的设计要求

(1)数据结构可以使用结构体数组或结构体链表实现,结构体的属性可进行扩充。

(2)上述功能是基本游戏功能,学生可增加功能,需编写若干函数来实现相应的功能模块。

(3)对于系统运行时,要求有相应的菜单,可用各种方法实现菜单选择。

2系统需求分析

2.1系统设计目标

用C语言来编写俄罗斯方块这个游戏有较大优势:

C语言具有各种各样的数据类型,并引入了指针概念,使得程序效率更高;

C语言还包含很广泛的运算符;

另外C语言具有强大的图形功能,支持多种显示器和驱动器,而且计算功能、逻辑判断能力也比较强大。

选择此论文题是旨在训练基本编程能力和游戏开发技巧,熟悉C语言图形模式下的编程。

本程序中涉及结构体、数组、时钟中断及绘图等方面的知识。

通过本程序的训练,能对C语言有一个深刻的了解,掌握俄罗斯方块游戏开发的基本原理,为将来开发出高质量的游戏软件打下坚实的基础。

2.2系统流程图

系统流程图如图2-1所示:

图2-1系统流程图

3系统的实现

这是此游戏开发的重点和难点部分。

下面分别介绍左移、右移、下移、旋转及满行判断的实现。

左移的实现过程如下:

(1)判断在当前的游戏底板中能否左移。

这一判断必须满足如下两条件:

游戏方块整体左移一位后,游戏方块不能超越游戏底板的左边线,否则越界;

并且在游戏方块有值(值为1)的位置,游戏底板必须是没有被占用的(占用时,值为1)。

若满足这两个条件,则执行下面的左移动作。

否则不执行左移动作。

(2)清除左移前的游戏方块。

(3)在左移一位的位置,重新显示此游戏方块。

右移的实现过程如下:

(1)判断在当前游戏底板中能否右移。

这一判断必须满足如下两个条件:

游戏方块整体右移一位后,游戏方块不能超越游戏底板的右边线,否则越界;

若满足这两个条件,则执行下面的右移动作。

否则不只执行右移动作。

(2)清除右移前的游戏方块。

(3)在右移一位的位置,重新显示此游戏方块。

下移的实现过程如下:

(1)判断在当前游戏底板中能否下移。

游戏方块整体下移一位后,游戏方块不能超越游戏底板的底边线,否则越界;

若满足这两个条件,则执行下面的下移动作。

否则,将flag_newbox标志置1,主循环中会判断此标志,若为1,则会生成下一个游戏方块,并更新预览游戏方块。

(2)清除下移前的游戏方块。

(3)在下移一位的位置,重新显示此游戏方块。

旋转的实现过程如下:

(1)判断在当前游戏底板中能否旋转。

这一判断必须满足如下条件:

游戏方块整旋转后,游戏方块不能超越游戏底板的左边线、右边线和底边线,否则越界;

若满足这些条件,则执行下面的旋转动作。

否则不执行旋转动作。

(2)清除旋转前的游戏方块。

(3)在游戏方块显示区域(4×

4)不变的位置,利用保存当前游戏方块的数据结构中的next值作为旋转后形成的新游戏方块的编号,并重新显示这个编号的游戏方块。

当生成新的游戏方块前,执行行满的检查,判断行满的过程为:

一次从下到上扫描游戏底板中的各行,若某行中1的个数等于游戏底板水平方向上的小方块的个数,则表示此行是满的。

找到满行后,立即将游戏底板中的数据往下顺移一行,直到游戏底板逐行扫描完毕。

当用户刚进入游戏时,如图3-1所示。

此时,分数初始化为0,等级默认为1。

游戏当前设置为成绩每增加30分等级就升一级,升级后游戏方块在原来基础上下落速度有所加快,这主要是变化了定时器的时间间隔的缘故。

用户可使用键盘左移键、右移键、上移键和下移键,分别进行左移、右移、旋转和下落操作。

图3-1游戏初始状态

图3-2为游戏等级提升了一级后的状态,级别越高,游戏方块下落速度越快。

图3-2游戏进行状态

4程序调试

当判断出一行满时,score变量一固定值,可以吧等级level看作是速度speed,因为速度speed是根据计分score值不断上升的,所以我们定义level=speed==score/speed_step,其中speed_step是每升一级所需要的分数。

方块下落速度加快,这是不断修改了定时计数器变量TimerCounter判断条件的结果。

速度越快,时间中断的间隔就越短。

清除方块的过程为:

用先画轮廓再填充的方式,使用背景色填充小方块,然后使用前景色画一个游戏底板中的小方块。

循环此过程,变化当前坐标,填充及画出共16个这样的小方块。

这样在游戏底板中,清除了此游戏方块。

在调试过程中出现了一些错误,比如说漏了分号,将%d误写成%s。

这些都可以根据程序执行过程中下边的提示来加以改正。

5总结

5.1系统特色

系统功能齐全,包括游戏方块预览功能、游戏方块控制功能、游戏显示更新功能、游戏速度分数更新功能和游戏帮助功能。

玩家可以在这些功能的基础上畅快的进行游戏。

尤其是游戏帮助功能,是本系统最具特色的功能,可以让第一次接触本系统的玩家对这款游戏快速上手。

5.2心得体会

通过两个星期的折腾,总算把课程设计给完成了,这是一个坚苦而又漫长的过程。

是啊,读了那么多年的书,课程设计可是第一次。

看着劳动成果,很欣慰!

虽然这不是我一个人做的,是大家的共同努力得来的。

“也许完成不了!

”两个星期前我们这样说,“完成他没问题!

”一个星期前我们这样说,现在我们可以说:

“哈哈,完成啦”!

刚开始,可以说是没有头绪,于是就去图书馆找资料,找到了一些关于画图方面的,可是这点小进展远远不够,这只是一个小小的开始。

下一步是上网查,找到了些与我们题目相似的,那时我们每个人都很高兴,可是那还不是我们要的,于是又上网查到了些有关的函数等等,终于在我们大家的努力下,完成了这个程序。

虽然对着电脑做程序,有点累有点热,可是当看到劳动成果时,真是别有一番滋味在心头啊!

世上无难事,只怕有心人,的确如此。

做完这个程序最大的收获就是感受到了集体的力量,当然个人的智慧也是很重要的哦!

做完这个课程设计,我们的自信一下子提高了,我们也会写程序了;

尽管对于有些人这种程序会很简单,可对我们C语言初学者来说,已经很不容易了。

这次体验为以后的学习计算机的我们增强了信心。

享受劳动成果的滋味实在很美妙啊!

源程序清单

程序预处理

/*加载头文件*/

#include<

stdio.h>

stdlib.h>

dos.h>

graphics.h>

/*图形函数库*/

/*定义按键码*/

#defineVK_LEFT0x4b00

#defineVK_RIGHT0x4d00

#defineVK_DOWN0x5000

#defineVK_UP0x4800

#defineVK_ESC0x011b

#defineTIMER0x1c/*设置中断号*/

/*定义常量*/

#defineMAX_BOX19/*总共有19种各形态的方块*/

#defineBSIZE20/*方块的边长是20个象素*/

#defineSys_x160/*显示方块界面的左上角x座标*/

#defineSys_y25/*显示方块界面的左上角y座标*/

#defineHorizontal_boxs10/*水平的方向以方块为单位的长度*/

#defineVertical_boxs15/*垂直的方向以方块为单位的长度*/

#defineBegin_boxs_xHorizontal_boxs/2/*产生第一个方块时出现的起始位置*/

#defineFgColor3/*前景颜色,如文字.2-green*/

#defineBgColor0/*背景颜色.0-blac*/

#defineLeftWin_xSys_x+Horizontal_boxs*BSIZE+46/*右边状态栏的x座标*/

#definefalse0

#definetrue1

/*移动的方向*/

#defineMoveLeft1

#defineMoveRight2

#defineMoveDown3

#defineMoveRoll4

/*以后坐标的每个方块可以看作是像素点是BSIZE*BSIZE的正方形*/

/*定义全局变量*/

intcurrent_box_numb;

/*保存当前方块编号*/

intCurbox_x=Sys_x+Begin_boxs_x*BSIZE,Curbox_y=Sys_y;

/*x,y是保存方块的当前坐标的*/

intflag_newbox=false;

/*是否要产生新方块的标记0*/

intspeed=0;

/*下落速度*/

intscore=0;

/*总分*/

intspeed_step=30;

/*每等级所需要分数*/

voidinterrupt(*oldtimer)(void);

/*指向原来时钟中断处理过程入口的中断处理函数指针*/

structBOARD/*游戏底板结构,表示每个点所具有的属性*/

{

intvar;

/*当前状态只有0和1,1表示此点已被占用*/

intcolor;

/*颜色,游戏底板的每个点可以拥有不同的颜色.增强美观*/

}Table_board[Vertical_boxs][Horizontal_boxs];

/*方块结构*/

structSHAPE

charbox[2];

/*一个字节等于8位,每4位来表示一个方块的一行

如:

box[0]="

0x88"

box[1]="

0xc0"

表示的是:

1000

1100

0000*/

/*每个方块的颜色*/

intnext;

/*下个方块的编号*/

};

/*初始化方块内容.即定义MAX_BOX个SHAPE类型的结构数组,并初始化*/

structSHAPEshapes[MAX_BOX]=

/*

*口口口口口口口

*口口口口口口

*口口口

*/

{0x88,0xc0,CYAN,1},

{0xe8,0x0,CYAN,2},

{0xc4,0x40,CYAN,3},

{0x2e,0x0,CYAN,0},

*口口口口口口

*口口口口

*口口口口口口

{0x44,0xc0,MAGENTA,5},

{0x8e,0x0,MAGENTA,6},

{0xc8,0x80,MAGENTA,7},

{0xe2,0x0,MAGENTA,4},

*口

*口口口口

*口口口

{0x8c,0x40,YELLOW,9},

{0x6c,0x0,YELLOW,8},

{0x4c,0x80,BROWN,11},

{0xc6,0x0,BROWN,10},

*口口口

*口口口口口口口口口口

{0x4e,0x0,WHITE,13},

{0x8c,0x80,WHITE,14},

{0xe4,0x0,WHITE,15},

{0x4c,0x40,WHITE,12},

/*口

*口口口口口

{0x88,0x88,RED,17},

{0xf0,0x0,RED,16},

*口口

{0xcc,0x0,BLUE,18}

unsignedintTimerCounter=0;

/*定时计数器变量*/

主函数main()

voidmain()

intGameOver=0;

intkey,nextbox;

intCurrentaction=0;

/*标记当前动作状态*/

intgd=VGA,gm=VGAHI,errorcode;

initgraph(&

gd,&

gm,"

"

);

errorcode=graphresult();

if(errorcode!

=grOk)

{

printf("

\nNotice:

Graphicserror:

%s\n"

grapherrormsg(errorcode));

Pressanykeytoquit!

getch();

exit

(1);

}

setbkcolor(BgColor);

setcolor(FgColor);

randomize();

SetTimer(newtimer);

initialize(Sys_x,Sys_y,Horizontal_boxs,Vertical_boxs);

/*初始化*/

nextbox=MkNextBox(-1);

show_box(Curbox_x,Curbox_y,current_box_numb,shapes[current_box_numb].color);

show_box(LeftWin_x,Curbox_y+200,nextbox,shapes[nextbox].color);

show_intro(Sys_x,Curbox_y+320);

while

(1)

/*Currentaction=0;

flag_newbox=false;

检测是否有按键*/

if(bioskey

(1)){key=bioskey(0);

else{key=0;

switch(key)

caseVK_LEFT:

if(MoveAble(Curbox_x,Curbox_y,current_box_numb,MoveLeft))

{EraseBox(Curbox_x,Curbox_y,current_box_numb);

Curbox_x-=BSIZE;

Currentaction=MoveLeft;

}

break;

caseVK_RIGHT:

if(MoveAble(Curbox_x,Curbox_y,current_box_numb,MoveRight))

Curbox_x+=BSIZE;

Currentaction=MoveRight;

caseVK_DOWN:

if(MoveAble(Curbox_x,Curbox_y,current_box_numb,MoveDown))

Curbox_y+=BSIZE;

Currentaction=MoveDown;

elseflag_newbox=true;

caseVK_UP:

/*旋转方块*/

if(MoveAble(Curbox_x,Curbox_y,shapes[current_box_numb].next,MoveRoll))

current_box_numb=shapes[current_box_numb].next;

Currentaction=MoveRoll;

caseVK_ESC:

GameOver=1;

default:

if(Currentaction)

{/*表示当前有动作,移动或转动*/

Currentaction=0;

/*按了往下键,但不能下移,就产生新方块*/

if(flag_newbox)

/*这时相当于方块到底部了,把其中出现点满一行的清去,置0*/

ErasePreBox(LeftWin_x,Sys_y+200,nextbox);

nextbox=MkNextBox(nextbox);

if(!

MoveAble(Curbox_x,Curbox_y,current_box_numb,MoveDown))/*刚一开始,游戏结束*/

else

else/*自由下落*/

if(Currentaction==MoveDown||TimerCounter>

(20-speed*2))

EraseBox(Curbox_x,Curbox_y,current_box_numb);

TimerCounter=0;

if(GameOver)/*||flag_newbox==-1*/

gameover,thankyou!

yourscoreis%d"

score);

KillTimer();

closegraph();

初始化界面

/**********初始化界面*******

*参数说明:

*x,y为左上角坐标

*m,n对应于Vertical_boxs,Horizontal_boxs

*分别表示纵横方向上方块的个数(以方块为单位)

*BSIZESys_xSys_y

**********************************/

voidinitialize(intx,inty,intm,intn)

inti,j,oldx;

oldx=x;

for(j=0;

j<

n;

j++)

for(i=0;

i<

m;

i++)

Table_board[j][i].var=0;

Table_board[j][i].color=BgColor;

line(x,y,x+BSIZE,y);

line(x,y,x,y+BSIZE);

line(x,y+BSIZE,x+BSIZE,y+BSIZE);

line(x+BSIZE,y,x+BSIZE,y+BSIZE);

x+=BSIZE;

y+=BSIZE;

x=oldx;

Curbox_x=x;

Curbox_y=y;

/*x,y是保存方块的当前坐标的*/

speed=0;

score=0;

ShowScore(score);

ShowSpeed(speed);

时钟中断处理

voidinterruptnewtimer(void)

(*oldtimer)();

/*calltheoldroutine*/

TimerCounter++;

/*increasetheglobalcounter*/

/*设置新的时钟中断处理过程*/

voidSetTimer(voidinterrupt(*IntProc)(void))

oldtimer=getvect(TIMER);

/*获取中断号为TIMER的中断处理函数的入口地址*/

disable();

/*设置新的时钟中断处理过程时,禁止所有中断*/

setvect(TIMER,IntProc);

/*将中断号为TIMER的中断处理函数的入口地址改为IntProc()函数的入口地址

即中断发生时,将调用IntProc()函数。

*/

enable();

/*开启中断*/

/*恢复原有的时钟中断处理过程*/

voidKillTimer()

setvect(TIMER,oldtimer);

成绩、速度及帮助的显示

/*显示分数*/

voidShowScor

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

当前位置:首页 > 总结汇报 > 学习总结

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2