俄罗斯方块游戏论文终搞.docx
- 文档编号:17670702
- 上传时间:2023-04-24
- 格式:DOCX
- 页数:46
- 大小:122.15KB
俄罗斯方块游戏论文终搞.docx
《俄罗斯方块游戏论文终搞.docx》由会员分享,可在线阅读,更多相关《俄罗斯方块游戏论文终搞.docx(46页珍藏版)》请在冰豆网上搜索。
俄罗斯方块游戏论文终搞
中国石油大学(北京)现代远程教育
毕业设计(论文)
俄罗斯方块游戏
姓名:
XXX
学号:
XXX
性别:
男
专业:
计算机科学与技术
批次:
0903
电子邮箱:
XXX
联系方式:
XXX
学习中心:
昌平学习中心
指导教师:
张秀美
2011年05月09日
俄罗斯方块游戏
摘要
俄罗斯方块是一款风靡全球的掌上游戏机和PC机游戏,它造成的轰动与创造的经济价值可以说是游戏史上的一件大事。
它由俄罗斯人阿列克谢·帕基特诺夫发明,故得此名。
俄罗斯方块的基本规则是移动、旋转和摆放游戏自动输出的各种方块,使之排列成完整的一行或多行并且消除得分。
它看似简单却变化无穷,俄罗斯方块上手极其简单,但是要熟练地掌握其中的操作与摆放技巧,难度却不低。
作为家喻户晓老少皆宜的大众游戏,其普及程度可以说是史上任何一款游戏都无法相比的。
相信大多数人都还记得为它痴迷得茶不思饭不想的那个俄罗斯方块时代。
由于俄罗斯方块具有的数学性、动态性与知名度,也经常拿来作为游戏程序设计的练习题材。
关键词:
俄罗斯方块开发;游戏编程;程序开发
目录
1.前言1
2.功能描述2
3.总体设计3
3.1功能模块设计3
3.1.1游戏执行主流程3
3.1.2游戏方块预览3
3.1.3游戏方块控制5
3.1.4游戏显示更新6
3.1.5游戏速度分数更新7
3.1.6游戏帮助7
3.2数据结构设计7
3.2.1游戏底板BOARD结构体7
3.2.2游戏方块SHAPE结构体7
3.2.3SHAPE结构数组8
3.3函数功能描述11
4.程序实现12
4.1源码分析12
4.1.1程序预处理12
4.1.2主函数main()16
4.1.3初始化界面21
4.1.4时钟中断处理22
4.1.5成绩、速度及帮助的显示24
4.1.6满行处理25
4.1.7游戏方块的显示和清除29
4.1.8游戏方块操作判断处理34
4.2运行结果40
4.2.1游戏初始状态40
4.2.2游戏进行状态41
5.结论42
致谢43
参考文献44
1.前言
俄罗斯方块(Tetris)原本是前苏联科学家阿列克谢·帕吉特洛夫在1984年6月利用空闲时间所编写的游戏程序,据说游戏的作者最喜欢网球(Tennis)运动,于是,它把来源于希腊语的tetra(意为“四”)与其结合,造了“tetris”一词,之后开始提供授权给各个游戏公司,造成各平台上俄罗斯游戏软件大量
发行的现象。
俄罗斯方块由于上手简单、老少皆宜,从而成为了家喻户晓款风靡全球的一款电视游戏机和掌上游戏机游戏。
C语言则是目前国际上比较流行的计算机高级编程语言之一,因其简洁、使用方便且具备强大的功能而受到编程人员的普遍青睐。
它既适合作为系统描述语言,也可以用来编写系统软件,还可以来编写应用软件。
用C语言来编写俄罗斯方块这个游戏有较大优势:
C语言具有各种各样的数据类型,并引入了指针概念,使得程序效率更高;C语言还包含很广泛的运算符;另外C语言具有强大的图形功能,支持多种显示器和驱动器,而且计算功能、逻辑判断能力也比较强大。
选择此论文题是旨在训练基本编程能力和游戏开发技巧,熟悉C语言图形模式下的编程。
本程序中涉及结构体、数组、时钟中断及绘图等方面的知识。
通过本程序的训练,能对C语言有一个更深刻的了解,掌握俄罗斯方块游戏开发的基本原理,为将来开发出高质量的游戏软件打下坚实的基础。
2.功能描述
如图2.1所示,本游戏主要实现一下几种功能:
图2.1俄罗斯方块游戏功能描述图
(1)游戏方块预览功能。
在游戏过程中,当在游戏底板中出现一个游戏方块时,必须在游戏方块预览区域中出现下一个游戏方块,这样有利于游戏玩家控制游戏的策略。
由于在此游戏中存在19种不同的游戏方块,所以在游戏方块预览区域中需要显示随机生成的游戏方块。
(2)游戏方块控制功能。
通过各种条件的判断,实现对游戏方块的左移、右移、快速下移、自由下落、旋转功能,以及行满消除行的功能。
(3)游戏显示更新功能。
当游戏方块左右移动、下落、旋转时,要清除先前的游戏方块,用新坐标重绘游戏方块。
当消除满行时,要重绘游戏底板的当前状态。
(4)游戏速度分数更新功能。
在游戏玩家进行游戏过程中,需要按照一定的游戏规则给玩家计算游戏分数。
比如,消除一行加10分。
当游戏分数达到一定数量之后,需要给游戏者进行等级的上升,每上升一个等级,游戏方块的下落速度将加快,游戏的难度将增加。
(5)游戏帮助功能。
玩家进入游戏后,将有对本游戏如何操作的友情提示。
3.总体设计
3.1功能模块设计
3.1.1游戏执行主流程
本俄罗斯方块游戏执行主流程图3.1所示。
在判断键值时,有左移VK_LEFT、右移VK_RIGHT、下移VK_DOWN、变形旋转VK_UP、退出VK_ESC键值的判断。
3.1.2游戏方块预览
新游戏方块将在如图3.2所示的4×4的正方形小方块中预览。
使用随机函数rand()来产生1~19之间的游戏方块编号,并作为预览的方块编号。
其中的正方形小方块的大小为BSIZE×BSIZE。
BSIZE为设定的像素大小。
图3.2游戏方块预览图
图3.1游戏执行主流程图
3.1.3游戏方块控制
这是此游戏开发的重点和难点部分。
下面分别较少左移、右移、下移、旋转及满行判断的实现。
左移的实现过程如下:
(1)判断在当前的游戏底板中能否左移。
这一判断必须满足如下两条件:
游戏方块整体左移一位后,游戏方块不能超越游戏底板的左边线,否则越界;并且在游戏方块有值(值为1)的位置,游戏底板必须是没有被占用的(占用时,值为1)。
若满足这两个条件,则执行下面的左移动作。
否则不执行左移动作。
(2)清除左移前的游戏方块。
(3)在左移一位的位置,重新显示此游戏方块。
右移的实现过程如下:
(1)判断在当前游戏底板中能否右移。
这一判断必须满足如下两个条件:
游戏方块整体右移一位后,游戏方块不能超越游戏底板的右边线,否则越界;并且在游戏方块有值(值为1)的位置,游戏底板必须是没有被占用的(占用时,值为1)。
若满足这两个条件,则执行下面的右移动作。
否则不只执行右移动作。
(2)清除右移前的游戏方块。
(3)在右移一位的位置,重新显示此游戏方块。
下移的实现过程如下:
(1)判断在当前游戏底板中能否下移。
这一判断必须满足如下两个条件:
游戏方块整体下移一位后,游戏方块不能超越游戏底板的底边线,否则越界;并且在游戏方块有值(值为1)的位置,游戏底板必须是没有被占用的(占用时,值为1)。
若满足这两个条件,则执行下面的下移动作。
否则,将flag_newbox标志置1,主循环中会判断此标志,若为1,则会生成下一个游戏方块,并更新预览游戏方块。
(2)清除下移前的游戏方块。
(3)在下移一位的位置,重新显示此游戏方块。
旋转的实现过程如下:
(1)判断在当前游戏底板中能否旋转。
这一判断必须满足如下条件:
游戏方块整旋转后,游戏方块不能超越游戏底板的左边线、右边线和底边线,否则越界;并且在游戏方块有值(值为1)的位置,游戏底板必须是没有被占用的(占用时,值为1)。
若满足这些条件,则执行下面的旋转动作。
否则不只执行旋转动作。
(2)清除旋转前的游戏方块。
(3)在游戏方块显示区域(4×4)不变的位置,利用保存当前游戏方块的数据结构中的next值作为旋转后形成的新游戏方块的编号,并重新显示这个编号的游戏方块。
当生成新的游戏方块前,执行行满的检查,判断行满的过程为:
一次从下到上扫描游戏底板中的各行,若某行中1的个数等于游戏底板水平方向上的小方块的个数,则表示此行是满的。
找到满行后,立即将游戏底板中的数据往下顺移一行,直到游戏底板逐行扫描完毕。
3.1.4游戏显示更新
当游戏方块左右移动、下落、旋转时,要清除先前的游戏方块,用新坐标重绘游戏方块。
当消除满行时,要重绘游戏底板的当前状态。
清除方块的过程为:
用先画轮廓再填充的方式,使用背景色填充小方块,然后使用前景色画一个游戏底板中的小方块。
循环此过程,变化当前坐标,填充及画出共16个这样的小方块。
这样在游戏底板中,清除了此游戏方块。
3.1.5游戏速度分数更新
当判断出一行满时,score变量一固定值(如10),可以吧等级level看作是速度speed,因为速度speed是根据计分score值不断上升的,所以我们定义level=speed==score/speed_step,其中speed_step是每升一级所需要的分数。
方块下落速度加快,这是不断修改了定时计数器变量TimerCounter判断条件的结果。
速度越快,时间中断的间隔就越短。
3.1.6游戏帮助
实现比较简单,使用outtextxy()函数实现。
3.2数据结构设计
3.2.1游戏底板BOARD结构体
StructBOARD
{
Intvar;
Intcolor;
}Table_board[Vertical_boxs][Horizontal_boxs];
BOARD结构体表示游戏底板中每个小方块所具有的属性。
其中var表示小方块当前状态,只有0与1两个值,表示此小方块已被占用,0表示未被占用。
Color表示小方块的颜色,游戏底板的每个小方块可以拥有不同的颜色,以增强美观。
Vertical_boxs为游戏底板上垂直的方向上小方块的个数,Horizontal_boxs为游戏底板上水平的方向上小方块的个数。
3.2.2游戏方块SHAPE结构体
structSHAPE
{
charbox[2];
intcolor;/*每个方块的颜色*/
intnext;/*下个方块的编号*/
};
SHAPE结构体表示某个游戏方块具有的属性。
其中,charbox[2]表示用2个字节来表示这个游戏方块的形状。
每4位来表示一个游戏方块的一行。
Color表示每个游戏方块的颜色,颜色可设为BLACK、BLUE、GREEN、CYAN、RE、MAGENTA、BROWN、LIGHTGRAY、DARKGRAY、LIGHTBLUE、LIGHTCYAN、LIGHTRED、LIGHTMAGENTA、YELLOW和WHITE。
next表示下个游戏方块的编号,在旋转时需要用到此编号。
如box[0]="0x88",box[1]="0xc0",其中0x88和0xc0为十六进制表示形式,具体表现的含义如图3.3所示。
图3.3SHAPE结构示意图
3.2.3SHAPE结构数组
初始化游戏方块内容,即定义MAX_BOX个SHAPE类型的结构数组,并初始化。
MAX_BOX为19。
应为一共有19种不同形状的俄罗斯方块。
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}
}
3.3函数功能描述
(1)newtimer()
函数原型:
voidinterruptnewtimer(void)
Newtimer()函数用于为新的时钟中断处理函数。
(2)SetTimer()
函数原型:
voidSetTimer(voidinterrupt(*IntProc)(void))
SetTimer()函数用于设置新的时钟中断处理过程。
(3)KillTimer()
函数原型:
voidKillTimer()
KillTimer()函数用于恢复原有的时钟中断处理过程。
(4)initialize()
函数原型:
voidinitialize(intx,inty,intm,intn)
Initialize()函数用于初始化界面,具体为在传入参数x、y指明位置上画m行n列小方块,并显示积分、等级、帮助及预览游戏方块等。
(5)DelFullRow()
函数原型:
intDelFullRow(inty)
DelFullRow()函数用于处理删除一满行的情况。
Y指明具体哪一行为满行。
(6)setFullRow()
函数原型:
voidsetFullRow(intt_boardy)
setFullRow()函数用于找到满行,并调用DelFullRow()函数来处理满行。
t_boardy为在游戏底板中的垂直方向的坐标值。
(7)MkNextBox()
函数原型:
intMkNextBox(intbox_numb)
MkNextBox()函数用于生成下一个游戏方块,并返回方块号。
Box_numb表示当前的游戏方块号。
(8)EraseBox()
函数原型:
voidEraseBox(intx,inty,intbox_numb)
EraseBox()函数用于清除(x,y)位置开始的编号为box_numb的游戏方块。
(9)show_box()
函数原型:
voidshow_box(intx,inty,intbox_numb,intcolor)
show_box()函数用于显示(x,y)位置开始的编号为box_numb的、颜色值为color的游戏方块。
(10)MoveAble()
函数原型:
intMoveAble(intx,inty,intbox_numb,intdirection)
MoveAble()函数判断是否可以移动。
(x,y)为当前方块位置,box_numb为方块号,direction为方向标志,返回true和false。
(11)主函数main()
整个游戏的主控部分。
4.程序实现
4.1源码分析
4.1.1程序预处理
包括加载头文件,定义结构体、常量和变量,并对它们进行初始化工作。
/*加载头文件*/
#include
#include
#include
#include
/*定义按键码*/
#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
1000
1100
0000*/
intcolor;/*每个方块的颜色*/
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;/*定时计数器变量*/
4.1.2主函数main()
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));
printf("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);
getch();
while
(1)
{
/*Currentaction=0;
flag_newbox=false;
检测是否有按键*/
if(bioskey
(1)){key=bioskey(0);}
else{key=0;}
switch(key)
{
caseVK_LEFT:
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 俄罗斯方块 游戏 论文