俄罗斯方块编程课程设计报告.docx
《俄罗斯方块编程课程设计报告.docx》由会员分享,可在线阅读,更多相关《俄罗斯方块编程课程设计报告.docx(35页珍藏版)》请在冰豆网上搜索。
俄罗斯方块编程课程设计报告
课程设计报告
题目:
俄罗斯方块设计
设计者:
**
专业班级:
**
学号:
**
指导教师:
**
所属系部:
**
**年**月**日
、
一.设计的目的和要求
加深对《C语言》课程所学知识的理解,进一步巩固C语言语法规则。
学会编制结构清晰、风格良好、数据结构适当的C语言程序,从而具备解决综合性实际问题的能力。
二.设计内容
在熟练掌握C语言的基本知识:
数据类型(整形、实型、字符型、指针、数组、结构等);运算类型(算术运算、逻辑运算、自增自减运算、赋值运算等);程序结构(顺序结构、判断选择结构、循环结构);大程序的功能分解方法(即函数的使用)等。
进一步掌握各种函数的应用,包括时间函数、绘图函数,以及文件的读写操作等。
三.设计任务
1.游戏欢迎界面。
2.游戏执行功能,包括计算得分。
3.游戏结束界面。
四.游戏基本规则
游戏共由7种不同形状的方块组成,游戏开始以后随机产生一个方块由屏幕的顶端开始向下落下,落到低端则固定到桌面,并开始下一个方块。
在游戏窗口的左边作为游戏的桌面,用宽度10和高度20的表格表示。
游戏桌面的右边靠上显示得分,最下边显示游戏帮助。
如果固定到游戏桌面的方块超出了顶端游戏结束。
方块固定以后如果桌面上已经固定了的方块满一行,则消除一行并将消除行之上的部分向下移动,消除一行得1分。
基本操作如下:
(1)方块落下的过程中可以用左右方向键移动方块的位置。
(2)上方向键用来旋转方块,即所谓的变形。
(3)下方向键用来加速方块下落。
(4)游戏中按下回车键暂停游戏。
再次按回车键继续游戏。
五.总体设计
游戏以Windows窗口的形式运行。
窗口的左边作为游戏的桌面,桌面的大小是10*20个单位。
随机出现一个方块从游戏桌面的上方开始向下移动,并随机生产一个向下方块显示到桌面的右边。
方块的颜色分为7种。
在显示下一个方块的上面显示玩家得分,下面显示游戏帮助。
当方块不能向下移动的时候,将方块固定到桌面上,固定的方法是将方块的每个部分所在的坐标的桌面数值设置为1.固定以后,判断桌面数值的每一行,如果一行的数值全部都是1的话,就将桌面上的这一行数值删除,并将这一行上面所有行向下移动一行。
删除一行的同时,玩家的得分加1。
上述操作完成以后,将下一个方块从桌面的顶部开始下落,重新生成下一个方块。
在固定方块到桌面的时候,还要判断方块的最顶端部分是否超出桌面范围,并以此作为游戏结束的依据。
六.详细设计与程序实现
一.方块设计
游戏的核心和重点在于7种方块的设计,这7种方块的形状分别为Z形、S形、线形、T形、方形、L形和反L形、其数据结构分别用相对坐标表示如下:
{{0,-1},{0,0},{-1,0},{-1,1}}
{{0,-1},{0,0},{1,0},{1,1}}
{{0,-1},{0,0},{0,1},{0,2}}
{{-1,0},{0,0},{1,0},{0,1}}
{{0,0},{1,0},{0,1},{1,1}}
{{-1,-1},{0,-1},{0,0},{0,1}}
{{1,-1},{0,-1},{0,0},{0,1}}
因为屏幕的左上角为原点,向右为*轴增加的方向,向下为y轴增加的方向,将上述坐标对号入座即可得到向对应的方块形状。
二.方块形状
①.Z形方块
Z形方块对号入座如下图所示:
{{0,-1},{0,0},{-1,0},{-1,1}}
Z形方块坐标图
②.S型方块
S形方块对号入座如下图所示:
{{0,-1},{0,0},{1,0},{1,1}}
S形方块坐标图
③.线形方块
线形方块对号入座如图所示:
{{0,-1},{0,0},{0,1},{0,2}}
线形方块坐标图
④.T型方块
T型方块对号入座如图所示:
{{-1,0},{0,0},{1,0},{0,1}}
T型方块坐标图
⑤.方形方
方形方块对号入座如图所示:
{{0,0},{1,0},{0,1},{1,1}}
方形方块坐标图
⑥.L形方块
L.L型方块对号入座如图所示:
{{-1,-1},{0,-1},{0,0},{0,1}}
.L型方块坐标图
⑦.反L形方块
反L形方块对号入座如图所示:
{{1,-1},{0,-1},{0,0},{0,1}}
L形方块坐标图
在方块相对坐标基础上加上*和y的偏移量,就可以在屏幕的不同位置得到相应的反面方块。
完成方块的向左,向右及向下移动。
将方块的相对坐标旋转90度得到的新坐标就算变形后的坐标。
顺时针操作的公式是:
*’=-y
y’=*
逆时针旋转操作的公式是:
*’=y
y’=*
其中,*和y代表旋转前方块的相对坐标,*和y代表旋转后方块的相对坐标。
唯一例外的是方形方块,在旋转处理的时候不做处理。
七.主要处理流程
游戏的主要流程图如下:
八.游戏设计源程序
//zhangdi
#include
#include
#include
#include"tetris.h"
#defineAPP_NAME"TETRIS"
#defineAPP_TITLE"TetrisGame"
#defineGAMEOVER"GAMEOVER"
#defineSHAPE_COUNT7
#defineBLOCK_COUNT4
#defineMA*_SPEED5
#defineCOLUMS10
#defineROWS20
#defineREDRGB(255,0,0)
#defineYELLOWRGB(255,255,0)
#defineGRAYRGB(128,128,128)
#defineBLACKRGB(0,0,0)
#defineWHITERGB(255,255,255)
#defineSTONERGB(192,192,192)
#defineCHARS_IN_LINE14
#defineSCORE"SCORE%4d"
//全局变量定义
charscore_char[CHARS_IN_LINE]={0};
char*press_enter="PressEnterkey...";
//帮助提示信息
char*help[]=
{
"Pressspaceorupkeytotransformshape.",
"Pressleftorrightkeytomoveshape.",
"Pressdownkeytospeedup.",
"Pressenterkeytopausegame.",
"Enjoyit.:
-)",
0
};
//枚举游戏的状态
enumgame_state
{
game_start,
game_run,
game_pause,
game_over
}state=game_start;
//定义方块的颜色
COLORREFshape_color[]=
{
RGB(255,0,0),
RGB(0,255,0),
RGB(0,0,255),
RGB(255,255,0),
RGB(0,255,255),
RGB(255,0,255),
RGB(255,255,255)
};
//定义方块的种类型
intshape_coordinate[SHAPE_COUNT][BLOCK_COUNT][2]=
{
{{0,-1},{0,0},{-1,0},{-1,1}},
{{0,-1},{0,0},{1,0},{1,1}},
{{0,-1},{0,0},{0,1},{0,2}},
{{-1,0},{0,0},{1,0},{0,1}},
{{0,0},{1,0},{0,1},{1,1}},
{{-1,-1},{0,-1},{0,0},{0,1}},
{{1,-1},{0,-1},{0,0},{0,1}}
};
intscore=0;//得分
shapene*t=0;//下一个方块
shapecurrent=0;//当前方块
intcurrent_coordinate[4][2]={0};//当前方块的每一部分坐标
inttable[ROWS][COLUMS]={0};//游戏桌面
intshape*=0;//当前方块的*坐标
intshapey=0;//当前方块的y坐标
intspeed=0;//方块下移速度
clock_tstart=0;//每一帧开始时间
clock_tfinish=0;//每一帧结束时间
/*windows绘图用变量*/
HWNDgameWND;/*window窗口句柄*/
HBITMAPmemBM;/*内存位图*/
HBITMAPmemBMOld;/*内存原始位图*/
HDCmemDC;/*内存DC*/
RECTclientRC;/*客户端矩形区域*/
HBRUSHblackBrush;/*黑色画笔*/
HBRUSHstoneBrush;/*深灰色画笔*/
HBRUSHshapeBrush[SHAPE_COUNT];/*方块画笔,种方块,每种一个*/
HPENgrayPen;/*灰色画笔*/
HFONTbigFont;/*大字体,用来显示游戏名字和GameOver*/
HFONTsmallFont;/*小字体用来显示帮助信息等*/
/*主要处理函数*/
intma**()/*取最大坐标,函数名称:
ma**;函数功能:
取得当前方块的最大*坐标*/
{
inti=0;/*取最大坐标,函数名称:
ma**;函数功能:
取得当前方块的最大*坐标*/
int*=current_coordinate[i][0];/*取最大坐标,函数名称:
ma**;函数功能:
取得当前方块的最大*坐标*/
intm=*;/*取最大坐标,函数名称:
ma**;函数功能:
取得当前方块的最大*坐标*/
for(i=1;ima**;函数功能:
取得当前方块的最大*坐标*/
{
*=current_coordinate[i][0];/*取最大坐标,函数名称:
ma**;函数功能:
取得当前方块的最大*坐标*/
if(m<*)/*取最大坐标,函数名称:
ma**;函数功能:
取得当前方块的最大*坐标*/
{
m=*;/*取最大坐标,函数名称:
ma**;函数功能:
取得当前方块的最大*坐标*/
}
}
returnm;/*取最大坐标,函数名称:
ma**;函数功能:
取得当前方块的最大*坐标*/
}
intmin*()/*取最小坐标,函数名称:
min*;函数功能:
取得当前方块的最小*坐标*/
{
inti=0;/*取最小坐标,函数名称:
min*;函数功能:
取得当前方块的最小*坐标*/
int*=current_coordinate[i][0];/*取最小坐标,函数名称:
min*;函数功能:
取得当前方块的最小*坐标*/
intm=*;/*取最小坐标,函数名称:
min*;函数功能:
取得当前方块的最小*坐标*/
for(i=1;imin*;函数功能:
取得当前方块的最小*坐标*/
{
*=current_coordinate[i][0];/*取最小坐标,函数名称:
min*;函数功能:
取得当前方块的最小*坐标*/
if(m>*)/*取最小坐标,函数名称:
min*;函数功能:
取得当前方块的最小*坐标*/
{
m=*;/*取最小坐标,函数名称:
min*;函数功能:
取得当前方块的最小*坐标*/
}
}
returnm;/*取最小坐标,函数名称:
min*;函数功能:
取得当前方块的最小*坐标*/
}
/*逆时针旋转方块*/
voidturn_left()/*函数名称:
turn_left;函数功能:
将当前方块逆时针旋转度*/
{
inti=0;/*函数名称:
turn_left;函数功能:
将当前方块逆时针旋转度*/
int*,y;/*函数名称:
turn_left;函数功能:
将当前方块逆时针旋转度*/
for(i=0;i<4;i++)/*函数名称:
turn_left;函数功能:
将当前方块逆时针旋转度*/
{
*=current_coordinate[i][0];/*函数名称:
turn_left;函数功能:
将当前方块逆时针旋转度*/
y=current_coordinate[i][1];/*函数名称:
turn_left;函数功能:
将当前方块逆时针旋转度*/
current_coordinate[i][0]=y;/*函数名称:
turn_left;函数功能:
将当前方块逆时针旋转度*/
current_coordinate[i][1]=-*;/*函数名称:
turn_left;函数功能:
将当前方块逆时针旋转度*/
}
}
/*顺时针旋转方块*/
voidturn_right()/*函数名称:
turn_right;函数功能:
将当前方块顺时针旋转度*/
{
inti=0;/*函数名称:
turn_right;函数功能:
将当前方块顺时针旋转度*/
int*,y;/*函数名称:
turn_right;函数功能:
将当前方块顺时针旋转度*/
for(i=0;i<4;i++)/*函数名称:
turn_right;函数功能:
将当前方块顺时针旋转度*/
{
*=current_coordinate[i][0];/*函数名称:
turn_right;函数功能:
将当前方块顺时针旋转度*/
y=current_coordinate[i][1];/*函数名称:
turn_right;函数功能:
将当前方块顺时针旋转度*/
current_coordinate[i][0]=-y;/*函数名称:
turn_right;函数功能:
将当前方块顺时针旋转度*/
current_coordinate[i][1]=*;/*函数名称:
turn_right;函数功能:
将当前方块顺时针旋转度*/
}
}
/*检查方块是否越界*/
intout_of_table()/*函数名称:
out_of_table;函数功能:
检查当前方块是否超出桌面范围*/
{
inti=0;/*函数名称:
out_of_table;函数功能:
检查当前方块是否超出桌面范围*/
int*,y;/*函数名称:
out_of_table;函数功能:
检查当前方块是否超出桌面范围*/
for(i=0;i<4;i++)/*函数名称:
out_of_table;函数功能:
检查当前方块是否超出桌面范围*/
{
*=shape*+current_coordinate[i][0];/*函数名称:
out_of_table;函数功能:
检查当前方块是否超出桌面范围*/
y=shapey+current_coordinate[i][1];/*函数名称:
out_of_table;函数功能:
检查当前方块是否超出桌面范围*/
if(*<0||*>(COLUMS-1)||y>(ROWS-1))/*函数名称:
out_of_table;函数功能:
检查当前方块是否超出桌面范围*/
{
return1;/*函数名称:
out_of_table;函数功能:
检查当前方块是否超出桌面范围*/
}
if(table[y][*])/*函数名称:
out_of_table;函数功能:
检查当前方块是否超出桌面范围*/
{
return1;/*函数名称:
out_of_table;函数功能:
检查当前方块是否超出桌面范围*/
}
}
return0;/*函数名称:
out_of_table;函数功能:
检查当前方块是否超出桌面范围*/
}
/*旋转方块*/
voidtransform()/*函数名称:
transform;函数功能:
旋转当前方块*/
{
if(current==SquareShape)/*函数名称:
transform;函数功能:
旋转当前方块*/
{
return;/*函数名称:
transform;函数功能:
旋转当前方块*/
}
turn_right();/*函数名称:
transform;函数功能:
旋转当前方块*/
if(out_of_table())/*函数名称:
transform;函数功能:
旋转当前方块*/
{
turn_left();/*函数名称:
transform;函数功能:
旋转当前方块*/
}
}
/*判断方块能否向左移动*/
intleftable()/*函数名称:
leftable;函数功能:
判断当前方块能否向左移动,能移动返回,否则返回*/
{
inti=0;/*函数名称:
leftable;函数功能:
判断当前方块能否向左移动,能移动返回,否则返回*/
int*,y;/*函数名称:
leftable;函数功能:
判断当前方块能否向左移动,能移动返回,否则返回*/
for(i=0;i<4;i++)/*函数名称:
leftable;函数功能:
判断当前方块能否向左移动,能移动返回,否则返回*/
{
*=shape*+current_coordinate[i][0];/*函数名称:
leftable;函数功能:
判断当前方块能否向左移动,能移动返回,否则返回*/
y=shapey+current_coordinate[i][1];/*函数名称:
leftable;函数功能:
判断当前方块能否向左移动,能移动返回,否则返回*/
if(*<=0||table[y][*-1]==1)/*函数名称:
leftable;函数功能:
判断当前方块能否向左移动,能移动返回,否则返回*/
{
return0;/*函数名称:
leftable;函数功能:
判断当前方块能否向左移动,能移动返回,否则返回*/
}
}
return1;/*函数名称:
leftable;函数功能:
判断当前方块能否向左移动,能移动返回,否则返回*/
}
/*判断方块能否向右移动*/
intrightable()/*函数名称:
rightable;函数功能:
判断当前方块能否向右移动,能移动返回,否则返回*/
{
inti=0;/*函数名称:
rightable;函数功能:
判断当前方块能否向右移动,能移动返回,否则返回*/
int*,y;/*函数名称:
rightable;函数功能:
判断当前方块能否向右移动,能移动返回,否则返回*/
for(i=0;i<4;i++)/*函数名称:
rightable;函数功能:
判断当前方块能否向右移动,能移动返回,否则返回*/
{
*=shape*+current_coordinate[i][0];/*函数名称:
rightable;函数功能:
判断当前方块能否向右移动,能移动返回,否则返回*/
y=shapey+current_coordinate[i][1];/*函数名称:
rightable;函数功能:
判断当前方块能否向右移动,能移动返回,否则返回*/
if(*>=(COLUMS-1)||table[y][*+1]==1)/*函数名称:
rightable;函数功能:
判断当前方块能否向右移动,能移动返回,否则返回*/
{
return0;/*函数名称:
rightable;函数功能:
判断当前方块能否向右移动,能移动返回,否则返回*/
}
}
return1;/*函数名称:
rightable;函数功能:
判断当前方块能否向右移动,能移动返回,否则返回*/
}
/*判断方块能否向下移动*/
intdownable()/*函数名称:
downable;函数功能:
判断当前方块能否向下移动,能移动返回,否则返回*/
{
inti=0;/*函数名称:
downable;函数功能:
判断当前方块能否向下移动,能移动返回,否则返回*/
int*,y;
for(i=0;i<4;i++)/*函数名称:
downable;函数功能:
判断当前方块能否向下移动,能移动返回,否则返回*/
{
*=shape*+current_coordinate[i][0];/*函数名称:
downable;函数功能:
判断当前方块能否向下移动,能移动返回,否则返回*/
y=shapey+current_coordinate[i][1];/*函数名称:
downable;函数功能:
判断当前方块能否向下移动,能移动返回,否则返回*/
if(y>=(ROWS-1)||table[y+1][*]==1)/*函数名称:
downable;函数功能:
判断当前方块能否向下移动,能移动返回,否则返回*/
{
return0;/*函数名称:
downable;函数功能:
判断当前方块能否向下移动,能移动返回,否则返回*/
}
}
return1;/*函数名称:
downable;函数功能:
判断当前方块能否向下移动,能移动返回,否则返回*/
}
/*向左移动当前方块*/
voidmove_left()/*函数名称:
move_left;函数功能:
向左移动当前方块*/
{
if(leftable())/*函数名称:
move_left;函数功能:
向左移动当前方块*/
{
shape*--;/*函数名称:
move_left;函数功能:
向左移动当前方块*/
}
}
/*向右移动当前方块*/
voidmove_right()/*函数名称:
move_right;函数功能:
向右移动方块*/
{
if(rightable())/*函数名称:
move_right;函数功能:
向右移动方块*/
{
shape*++;/*函数名称:
move_right;函数功能:
向右移动方块*/
}
}
/*向下移动当前方块*/
voidmove_down()/*函数名称:
move_down;函数功能:
向下移动当前方块*/
{
if(downable())/*函数名称:
move_down;函数功能:
向下移动当前方块*/
{
shapey++;/*函数名称:
move_down;函数功能:
向下移动当前方块*/
}
else
{
if(add_to_table())/*函数名称:
move_down;函数功能:
向下移动当前方块*/
{
remove_full();/*函数名称:
move_down;函数功能:
向下移动当前方块*/
ne*t_shape();/*函数名称:
move_down;函数功能:
向下移动当前方块*/
}
else
{
state=game_over;/*函数名称:
move_down;函数功能:
向下移动当前方块*/
}
}
}
/*将当前方块固定到桌面上*/
intadd_to_table()/*函数名称:
add_to_table;函数功能:
将当前方块固定到桌面上,若返回,表示游戏结束*/
{
inti=0;/*函数名称:
add_t