热门搜索 :
考研考公
您的当前位置:首页正文

C语言课程设计报告 俄罗斯方块改进版

来源:伴沃教育
俄罗斯方块-古有禹制作

课程设计

设计题目 俄罗斯方块改进

学生姓名 学号 专业班级 指导教师

2016年4月20日

俄罗斯方块改进-古有禹制作

目录

1. 课程设计目的 ...................................................................................................................... 1 2. 功能分析 .............................................................................................................................. 1 3. 程序设计实现过程 .............................................................................................................. 2

3.1 程序总体设计结构 .................................................................................................... 2 3.2 界面设计 .................................................................................................................... 4 3.3 重要数据的数据结构设计 ........................................................................................ 5 3.4 函数设计 .................................................................................................................... 7 4. 运行效果 ............................................................................................................................ 13 5. 源代码详解 ........................................................................................................................ 14 6. 参考文献 ............................................................................................................................ 27

1

俄罗斯方块改进-古有禹制作

俄罗斯方块改进

1. 课程设计问题

据百度百科,俄罗斯方块(Tetris)是一款由俄罗斯人阿列克谢·帕基特诺夫于1984年6月发明的休闲游戏。游戏的基本规则是移动、旋转和摆放游戏自动输出的各种方块,使之排列成完整的一行或多行并且消除得分。

要求支持键盘操作和7种不同类型方块的旋转变换,并且界面上显示下一个方块的提示以及当前的玩家的得分,随着游戏的进行,等级越高,游戏难度越大,即方块的下落速度越快,相应的等级,等级越高,消去一行所得到的分数越高,为玩家提供了不同的选择。

2. 功能分析

俄罗斯方块游戏需要解决的问题包括:

⑴按任意键开始游戏,随机产生方块并自动下移 ⑵用Esc键退出游戏。 ⑶用 键变换方块

⑷用 键和 键左右移动方块 ⑸用 键使方块加速下移 ⑹用空格键使方块暂停

⑺能正确判断满行并消行、计分、定级别 ⑻设定游戏方块为不同形状重点: *游戏面包的数据结构:二维数组

*7种形状方块的数据结构:结构体保存每种形状方块的坐标

1

俄罗斯方块改进-古有禹制作

3. 程序设计实现过程

3.1 程序总体设计结构

首先初始化进入图形模式,进入欢迎界面,玩家按任意进入主菜单界面,按键进入游戏界面,键然后设置新的时钟中断。开始游戏后,进入该程序最核心的部分——处理和实现进行过程中的各种事件和函数。在处理中判断游戏是否结束,如果没有结束,则重新开始游戏,否则结束游戏。 详解如下:

(1)游戏方块预览功能。在游戏过程中,当在游戏底板中出现一个游戏方块时,必须在游戏方块预览区域中出现下一个游戏方块,这样有利于游戏玩家控制游戏的策略。由于在此游戏中存在19种不同的游戏方块,所以在游戏方块预览区域中需要显示随机生成的游戏方块。

(2)游戏方块控制功能。通过各种条件的判断,实现对游戏方块的左移、右移、快速下移、自由下落、旋转功能,以及行满消除行的功能。

俄罗斯方块游戏 初始化图形模式 (欢迎界面) 进入菜单选项

开游游 退始戏戏 出新帮说 游游助 明 戏 戏

2

游 戏排名 俄罗斯方块改进-古有禹制作

开始游戏 游戏方块控制功能 游戏方块预览功能 游戏显示更新功能 速度分数更新功能 游戏结束退出功能 游戏结束 是 恢复原有的时钟中断 关闭图形模式返回菜单 游戏执行主流程图

(3)游戏显示更新功能。在判断键值时,有左移VK_LEFT、右移VK_RIGHT、下移VK_DOWN、变形旋转VK_UP、退出VK_ESC键值的判断。当游戏方块左右移动、下落、旋转时,要清除先前的游戏方块,用新坐标重绘游戏方块。当消除满行时,要重绘游戏底板的当前状态。

(4)游戏速度分数更新功能。在游戏玩家进行游戏过程中,需要按照一定的游

3

俄罗斯方块改进-古有禹制作

戏规则给玩家计算游戏分数。比如,消除一行加10分。当游戏分数达到一定数量之后,需要给游戏者进行等级的上升,每上升一个等级,游戏方块的下落速度将加快,游戏的难度将增加。

(5)游戏帮助功能。玩家进入游戏后,将有对本游戏如何操作的友情提示。

主函数: void main() {

InitializeGraph();

SetTimer(newtimer); /*设置新的时钟中断*/ while(1) {

StartGame(); ProcessInGame(); if(GameOver()) break; bOver = FALSE; }

KillTimer(); closegraph(); }

3.2 界面设计

分为左右两个部分: *左边为游戏面板

*右边有三部分:下一个形状提示框、速度框和计分框

4

俄罗斯方块改进-古有禹制作

3.3 重要数据的数据结构设计 1)定义方块形状:

定义如下的结构体来表示每一个形状:

struct block{ int arrXY[8]; int nColor; int nNext;

}; /*保存某一形状信息的结构体*/

Struct SHAPE shapes[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},

5

俄罗斯方块改进-古有禹制作

{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},

口 口口口口 口

6

俄罗斯方块改进-古有禹制作

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

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

口口 口口

{0xcc, 0x0, BLUE, 18), }

2)定义游戏的主界面:宽10、高20的游戏板

(1) 数据结构:全局数组Gameboard[12][22],1表示已有的方块,0表示这

个位置空着。在10*20基础上各自加2行、2列为了便于判断形状在移动时是否到边、到底。整个屏幕的坐标系原先为640*480。在此游戏中,将16个像素定义为一个方格的边长,所以坐标系转变成为了40*30(640/16=40,480/10=30)。 (2)玩家进行游戏时,需要对游戏界面进行初始化工作。此代码被main()函数调用。主要进行的工作如下:

① 循环调用line()函数绘制当前游戏板。

② 调用nScore()函数显示初始的成绩,初始成绩为0。 ③ 调用npeed()函数显示初始的速度(等级),初始速度1。 **************************************************** * 注:x,y为左上角坐标

* * m,n对应于Vertical_boxs,Horizontal_boxs * * 分别表示纵横方向上方块的个数(以方块为单位) ** BOARD_LEFT_X ,BOARD_LEFT_Y

*****************************************************

3.4 函数设计

1、本程序有主函数和个函数组成:本程序总共由24个函数组成。

2、函数相互作用关系见下图

7

俄罗斯方块改进-古有禹制作

初 始化模式进 入欢迎界 win() 主菜单 menu() 初始化图形模式 InitializeGraph() 否 设置新的时钟中断 SetTimer(* (void)) 是游戏介绍help () Interrupt() (*IntProc) (void) 开始游恢复原来的时钟 InitializeGameboard() 戏 中断 KillTimer() HandleLeft(int ,int *x, int *y) 关闭图形模型 HandleRight(int,int *x, int *y) 返回到主菜单 menu() HandleUp(int *,int *x, int *y) 处理在游戏中的 HandleDown(int,int*x, int *y) 各种事件 ProcessInGame() 退出程序 游戏是否结束 8 IsConflict(int,int,int) DrawBlock(int,int,int,int) DrawSquare(int,int) IsLineFull(int) KillLine(int) KillLine(int) IsGameOver() 俄罗斯方块改进-古有禹制作

四、 函数运用

函数原型 void interrupt newtimer(void) 函数功能 新的时钟中断处理函数 函数处理描述 调用(*oldtimer)()函数语句柄,计时器自动加1 void SetTimer(void 指向原来时 interrupt(*IntProc)(void)) 钟中断处理过程入口的中断处理函数(句柄) void KillTimer() 恢复原有的时钟中断处理过程 void InitializeGraph() 初始化图形模式 调用setvect()恢复原有的时钟中断处理过程 1、调用initgraph()切换到图形模式2、初始化若发生错误,则返回错误密码 void InitializeGameboard() 初始化游戏面板以及下一形状提示1、调用bar()\\rectangle()等库函数绘图函数绘制框、计分框和游戏界面2、调用难度框 9

outtextxy()函数显示俄罗斯方块改进-古有禹制作

文字 void DrawSquare(int x, int 在坐标(x,y)调用库函数bar()绘y) void DrawBlock(int BlockIndex, int sx, int sy,int color) 处画方块 在坐标制方块 调用DrawSqueare()(sx,sy)处绘函数绘制形状 制颜色为color的形状 int IsConflict(int BlockIndex, int x, int y) 判断形状是否存在于坐标(x,y)处 无冲突返回0,有冲突返回1 void HandleLeft(int 按下左方向调用IsConflic()函数判断形状是否可以左移, 调用IsConflic()函数判断形状是否可以右移, 调用IsConflic()函数BlockIndex,int *x, int *y) 键时的处理函数 void HandleRight(int 按下右方向BlockIndex,int *x, int *y) 键时的处理函数 void HandleUp(int *BlockIndex,int *x, int *y) 按下上方向键(旋转键)判断形状是否可以时的处理函数 旋转, int HandleDown(int 按下向下方形状在自由下落返回0,无法下落了返BlockIndex,int *x, int *y) 向键或者自10

俄罗斯方块改进-古有禹制作

由下落时的处理函数 int IsLineFull(int y) 回1,并做相应处理 判断y行是否填满返回1,否则返已被填满 回0 函数用于处理删除一满行的情况。Y指明具体哪一行为满行,并将消去的行置为背景色 void KillLine(int y) 消去第y行 int KillLines(int y) 消去第y行以返回消去的行数 及与第y行连续的上面被填满的行 int IsGameOver() 判断游戏是否结束 游戏结束返回1,否则返回0 退出游戏返回1,否则返回0 int GameOver() 在界面上输出游戏结束的信息,并根据用户按键选择决定是否退出游戏 void StartGame()

游戏开始时11

1、绘制界面需要调俄罗斯方块改进-古有禹制作

调用的函数 用函数InitializeGameboard()2、接下来初始化游戏面板的各个方块和一些全局变量的初值。 void ProcessInGame() 核心函数,主调用HandleUpO、要用于处理在游戏中的HandleDown()、HandleLeft()、各种事件(如HandleRight()等事件按下各种按键) Void main() 主流程函数 主函数入口,整个游戏的主控部分 处理函数 12

俄罗斯方块改进-古有禹制作

4. 运行效果

13

俄罗斯方块改进-古有禹制作

5. 源代码详解

#include #include #include #include //游戏窗口

#define FrameX 4 //游戏窗口左上角的X轴坐标 #define FrameY 4 //游戏窗口左上角的Y轴坐标 #define Frame_height 20 //游戏窗口的高度 #define Frame_width 18 //游戏窗口的宽度 //定义全局变量

int i,j,temp,temp1,temp2; //temp,temp1,temp2用于记住和转换方块变量的值

int a[80][80]={0}; //标记游戏屏幕的图案:2,1,0分别表示该位置为游戏边框、方块、无图案;初始化为无图案

int b[4]; //标记4个\"口\"方块:1表示有方块,0表示无方块

char shape[10][4]={\"□\■\○\●\☆\★\◇\◆\△\▲\ int ss=0;

//声明俄罗斯方块的结构体 struct Tetris {

int x; //中心方块的x轴坐标 int y; //中心方块的y轴坐标 int flag; //标记方块类型的序号

int next; //下一个俄罗斯方块类型的序号 int speed; //俄罗斯方块移动的速度 int count; //产生俄罗斯方块的个数 int score; //游戏的分数 int level; //游戏的等级 };

//函数原型声明 //光标移到指定位置

void gotoxy(HANDLE hOut, int x, int y); //制作游戏窗口 void make_frame();

//随机产生方块类型的序号 void get_flag(struct Tetris *); //制作俄罗斯方块

void make_tetris(struct Tetris *); //打印俄罗斯方块

void print_tetris(HANDLE hOut,struct Tetris *); //清除俄罗斯方块的痕迹

void clear_tetris(HANDLE hOut,struct Tetris *);

14

俄罗斯方块改进-古有禹制作

//判断是否能移动,返回值为1,能移动,否则,不动 int if_moveable(struct Tetris *);

//判断是否满行,并删除满行的俄罗斯方块 void del_full(HANDLE hOut,struct Tetris *); //开始游戏

void start_game();

void main() { int t;

for ( t=0; t<10; t++) {

printf(\"%s\ }

printf(\"\\n0 1 2 3 4 5 6 7 8 9\\n\"); printf(\"请输入形状编号\");

scanf(\"%d\

//制作游戏窗口

make_frame(); //开始游戏 start_game(); }

/******光标移到指定位**************************************************************/ void gotoxy(HANDLE hOut, int x, int y) {

COORD pos;

pos.X = x; //横坐标 pos.Y = y; //纵坐标

SetConsoleCursorPosition(hOut, pos); }

/******制作游戏窗******************************************************************/ void make_frame() {

HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE); //定义显示器句柄变量 gotoxy(hOut,FrameX+Frame_width-5,FrameY-2); //打印游戏名称 printf(\"俄罗斯方块\");

gotoxy(hOut,FrameX+2*Frame_width+3,FrameY+7); //打印选择菜单

15

俄罗斯方块改进-古有禹制作

printf(\"**********下一个方块:\");

gotoxy(hOut,FrameX+2*Frame_width+3,FrameY+13); printf(\"**********\");

gotoxy(hOut,FrameX+2*Frame_width+3,FrameY+17); printf(\"↑键:变体\");

gotoxy(hOut,FrameX+2*Frame_width+3,FrameY+19); printf(\"空格:暂停游戏\");

gotoxy(hOut,FrameX+2*Frame_width+3,FrameY+15); printf(\"Esc :退出游戏\");

gotoxy(hOut,FrameX,FrameY); //打印框角并记住该处已有图案 printf(\"╔\");

gotoxy(hOut,FrameX+2*Frame_width-2,FrameY); printf(\"╗\");

gotoxy(hOut,FrameX,FrameY+Frame_height); printf(\"╚\");

gotoxy(hOut,FrameX+2*Frame_width-2,FrameY+Frame_height); printf(\"╝\");

a[FrameX][FrameY+Frame_height]=2;

a[FrameX+2*Frame_width-2][FrameY+Frame_height]=2; for(i=2;i<2*Frame_width-2;i+=2) {

gotoxy(hOut,FrameX+i,FrameY); printf(\"═\"); //打印上横框 }

for(i=2;i<2*Frame_width-2;i+=2) {

gotoxy(hOut,FrameX+i,FrameY+Frame_height); printf(\"═\"); //打印下横框

a[FrameX+i][FrameY+Frame_height]=2; //记住下横框有图案 }

for(i=1;igotoxy(hOut,FrameX,FrameY+i); printf(\"║\"); //打印左竖框

a[FrameX][FrameY+i]=2; //记住左竖框有图案 }

for(i=1;igotoxy(hOut,FrameX+2*Frame_width-2,FrameY+i); printf(\"║\"); //打印右竖框

a[FrameX+2*Frame_width-2][FrameY+i]=2; //记住右竖框有图案 } }

/******制作俄罗斯

方16

俄罗斯方块改进-古有禹制作

********************************************************************/ void make_tetris(struct Tetris *tetris) {

a[tetris->x][tetris->y]=b[0]; //中心方块位置的图形状态:1-有,0-无 switch(tetris->flag) //共6大类,19种类型 {

case 1: //田字方块 {

a[tetris->x][tetris->y-1]=b[1]; a[tetris->x+2][tetris->y-1]=b[2]; a[tetris->x+2][tetris->y]=b[3]; break; }

case 2: //直线方块:---- {

a[tetris->x-2][tetris->y]=b[1]; a[tetris->x+2][tetris->y]=b[2]; a[tetris->x+4][tetris->y]=b[3]; break; }

case 3: //直线方块: | {

a[tetris->x][tetris->y-1]=b[1]; a[tetris->x][tetris->y-2]=b[2]; a[tetris->x][tetris->y+1]=b[3]; break; }

case 4: //T字方块 {

a[tetris->x-2][tetris->y]=b[1]; a[tetris->x+2][tetris->y]=b[2]; a[tetris->x][tetris->y+1]=b[3]; break; }

case 5: //T字顺时针转90度方块 {

a[tetris->x][tetris->y-1]=b[1]; a[tetris->x][tetris->y+1]=b[2]; a[tetris->x-2][tetris->y]=b[3]; break; }

case 6: //T字顺时针转180度方块 {

a[tetris->x][tetris->y-1]=b[1];

17

俄罗斯方块改进-古有禹制作

a[tetris->x-2][tetris->y]=b[2]; a[tetris->x+2][tetris->y]=b[3]; break; }

case 7: //T字顺时针转270度方块 {

a[tetris->x][tetris->y-1]=b[1]; a[tetris->x][tetris->y+1]=b[2]; a[tetris->x+2][tetris->y]=b[3]; break; }

case 8: //Z字方块 {

a[tetris->x][tetris->y+1]=b[1]; a[tetris->x-2][tetris->y]=b[2]; a[tetris->x+2][tetris->y+1]=b[3]; break; }

case 9: //Z字顺时针转90度方块 {

a[tetris->x][tetris->y-1]=b[1]; a[tetris->x-2][tetris->y]=b[2]; a[tetris->x-2][tetris->y+1]=b[3]; break; }

case 10: //Z字顺时针转180度方块 {

a[tetris->x][tetris->y-1]=b[1]; a[tetris->x-2][tetris->y-1]=b[2]; a[tetris->x+2][tetris->y]=b[3]; break; }

case 11: //Z字顺时针转270度方块 {

a[tetris->x][tetris->y+1]=b[1]; a[tetris->x+2][tetris->y-1]=b[2]; a[tetris->x+2][tetris->y]=b[3]; break; }

case 12: //7字方块 {

a[tetris->x][tetris->y-1]=b[1]; a[tetris->x][tetris->y+1]=b[2]; a[tetris->x-2][tetris->y-1]=b[3];

18

俄罗斯方块改进-古有禹制作

break; }

case 13: //7字顺时针转90度方块 {

a[tetris->x-2][tetris->y]=b[1]; a[tetris->x-2][tetris->y+1]=b[2]; a[tetris->x+2][tetris->y]=b[3]; break; }

case 14: //7字顺时针转180度方块 {

a[tetris->x][tetris->y-1]=b[1]; a[tetris->x][tetris->y+1]=b[2]; a[tetris->x+2][tetris->y+1]=b[3]; break; }

case 15: //7字顺时针转270度方块 {

a[tetris->x-2][tetris->y]=b[1]; a[tetris->x+2][tetris->y-1]=b[2]; a[tetris->x+2][tetris->y]=b[3]; break; }

case 16: //倒7字方块 {

a[tetris->x][tetris->y+1]=b[1]; a[tetris->x][tetris->y-1]=b[2]; a[tetris->x+2][tetris->y-1]=b[3]; break; }

case 17: //倒7字顺指针转90度方块 {

a[tetris->x-2][tetris->y]=b[1]; a[tetris->x-2][tetris->y-1]=b[2]; a[tetris->x+2][tetris->y]=b[3]; break; }

case 18: //倒7字顺时针转180度方块 {

a[tetris->x][tetris->y-1]=b[1]; a[tetris->x][tetris->y+1]=b[2]; a[tetris->x-2][tetris->y+1]=b[3]; break; }

19

俄罗斯方块改进-古有禹制作

case 19: //倒7字顺时针转270度方块 {

a[tetris->x-2][tetris->y]=b[1]; a[tetris->x+2][tetris->y+1]=b[2]; a[tetris->x+2][tetris->y]=b[3]; break; } } }

//******判断是否可动*************************************************************************/ int if_moveable(struct Tetris *tetris) {

if(a[tetris->x][tetris->y]!=0)//当中心方块位置上有图案时,返回值为0,即不可移动 {

return 0; } else {

if( //当为田字方块且除中心方块位置外,其他\"口\"字方块位置上无图案时,返回值为1,即可移动

( tetris->flag==1 && ( a[tetris->x][tetris->y-1]==0 &&

a[tetris->x+2][tetris->y-1]==0 && a[tetris->x+2][tetris->y]==0 ) ) ||

//或为直线方块且除中心方块位置外,其他\"口\"字方块位置上无图案时,返回值为1,即可移动

( tetris->flag==2 && ( a[tetris->x-2][tetris->y]==0 &&

a[tetris->x+2][tetris->y]==0 && a[tetris->x+4][tetris->y]==0 ) ) || ( tetris->flag==3 && ( a[tetris->x][tetris->y-1]==0 &&

a[tetris->x][tetris->y-2]==0 && a[tetris->x][tetris->y+1]==0 ) ) || ( tetris->flag==4 && ( a[tetris->x-2][tetris->y]==0 &&

a[tetris->x+2][tetris->y]==0 && a[tetris->x][tetris->y+1]==0 ) ) || ( tetris->flag==5 && ( a[tetris->x][tetris->y-1]==0 &&

a[tetris->x][tetris->y+1]==0 && a[tetris->x-2][tetris->y]==0 ) ) || ( tetris->flag==6 && ( a[tetris->x][tetris->y-1]==0 &&

a[tetris->x-2][tetris->y]==0 && a[tetris->x+2][tetris->y]==0 ) ) || ( tetris->flag==7 && ( a[tetris->x][tetris->y-1]==0 &&

a[tetris->x][tetris->y+1]==0 && a[tetris->x+2][tetris->y]==0 ) ) || ( tetris->flag==8 && ( a[tetris->x][tetris->y+1]==0 &&

a[tetris->x-2][tetris->y]==0 && a[tetris->x+2][tetris->y+1]==0 ) ) || ( tetris->flag==9 && ( a[tetris->x][tetris->y-1]==0 &&

a[tetris->x-2][tetris->y]==0 && a[tetris->x-2][tetris->y+1]==0 ) ) || ( tetris->flag==10 && ( a[tetris->x][tetris->y-1]==0 &&

a[tetris->x-2][tetris->y-1]==0 && a[tetris->x+2][tetris->y]==0 ) ) || ( tetris->flag==11 && ( a[tetris->x][tetris->y+1]==0 &&

20

俄罗斯方块改进-古有禹制作

a[tetris->x+2][tetris->y-1]==0 && a[tetris->x+2][tetris->y]==0 ) ) || ( tetris->flag==12 && ( a[tetris->x][tetris->y-1]==0 &&

a[tetris->x][tetris->y+1]==0 && a[tetris->x-2][tetris->y-1]==0 ) ) || ( tetris->flag==13 && ( a[tetris->x-2][tetris->y]==0 &&

a[tetris->x-2][tetris->y+1]==0 && a[tetris->x+2][tetris->y]==0 ) ) || ( tetris->flag==14 && ( a[tetris->x][tetris->y-1]==0 &&

a[tetris->x][tetris->y+1]==0 && a[tetris->x+2][tetris->y+1]==0 ) ) || ( tetris->flag==15 && ( a[tetris->x-2][tetris->y]==0 &&

a[tetris->x+2][tetris->y-1]==0 && a[tetris->x+2][tetris->y]==0 ) ) || ( tetris->flag==16 && ( a[tetris->x][tetris->y+1]==0 &&

a[tetris->x][tetris->y-1]==0 && a[tetris->x+2][tetris->y-1]==0 ) ) || ( tetris->flag==17 && ( a[tetris->x-2][tetris->y]==0 &&

a[tetris->x-2][tetris->y-1]==0 && a[tetris->x+2][tetris->y]==0 ) ) || ( tetris->flag==18 && ( a[tetris->x][tetris->y-1]==0 &&

a[tetris->x][tetris->y+1]==0 && a[tetris->x-2][tetris->y+1]==0 ) ) || ( tetris->flag==19 && ( a[tetris->x-2][tetris->y]==0 &&

a[tetris->x+2][tetris->y+1]==0 && a[tetris->x+2][tetris->y]==0 ) ) ) {

return 1; } }

return 0; }

/******随机产生俄罗斯方块类型的序**********************************************************/ void get_flag(struct Tetris *tetris) {

tetris->count++; //记住产生方块的个数 srand((unsigned)time(NULL)); //初始化随机数 if(tetris->count==1) {

tetris->flag = rand()%19+1; //记住第一个方块的序号 }

tetris->next = rand()%19+1; //记住下一个方块的序号 }

/******打印俄罗斯方**********************************************************************/ void print_tetris(HANDLE hOut,struct Tetris *tetris) {

for(i=0;i<4;i++) {

b[i]=1; //数组b[4]的每个元素的值都为1 }

make_tetris(tetris); //制作俄罗斯方块

21

俄罗斯方块改进-古有禹制作

for( i=tetris->x-2; i<=tetris->x+4; i+=2 ) {

for(j=tetris->y-2;j<=tetris->y+1;j++) {

if( a[i][j]==1 && j>FrameY ) {

gotoxy(hOut,i,j);

printf(\"%s\ //打印边框内的方块□ } } }

//打印菜单信息

gotoxy(hOut,FrameX+2*Frame_width+3,FrameY+1); printf(\"level : %d\->level);

gotoxy(hOut,FrameX+2*Frame_width+3,FrameY+3); printf(\"score : %d\->score);

gotoxy(hOut,FrameX+2*Frame_width+3,FrameY+5); printf(\"speed : %dms\->speed); }

/******清除俄罗斯方块的痕****************************************************************/ void clear_tetris(HANDLE hOut,struct Tetris *tetris) {

for(i=0;i<4;i++) {

b[i]=0; //数组b[4]的每个元素的值都为0 }

make_tetris(tetris); //制作俄罗斯方块 for( i=tetris->x-2; i<=tetris->x+4; i+=2 ) {

for(j=tetris->y-2;j<=tetris->y+1;j++) {

if( a[i][j]==0 && j>FrameY ) {

gotoxy(hOut,i,j);

printf(\" \"); //清除方块 } } } }

/******判断是否满行并删除满行的俄罗斯方****************************************************/ void del_full(HANDLE hOut,struct Tetris *tetris)

{ //当某行有Frame_width-2个方块时,则满行

22

俄罗斯方块改进-古有禹制作

int k,del_count=0; //分别用于记录某行方块的个数和删除方块的行数的变量 for(j=FrameY+Frame_height-1;j>=FrameY+1;j--) { k=0;

for(i=FrameX+2;iif(a[i][j]==1) //竖坐标依次从下往上,横坐标依次由左至右判断是否满行 {

k++; //记录此行方块的个数 if(k==Frame_width-2) {

for(k=FrameX+2;kgotoxy(hOut,k,j); printf(\" \"); Sleep(1); }

for(k=j-1;k>FrameY;k--)

{ //如果删除行以上的位置有方块,则先清除,再将方块下移一个位置 for(i=FrameX+2;iif(a[i][k]==1) {

a[i][k]=0;

gotoxy(hOut,i,k); printf(\" \"); a[i][k+1]=1;

gotoxy(hOut,i,k+1); printf(\"%s\ } } }

j++; //方块下移后,重新判断删除行是否满行 del_count++; //记录删除方块的行数 } } } }

tetris->score+=100*del_count; //每删除一行,得100分

if( del_count>0 && ( tetris->score%1000==0 || tetris->score/1000>tetris->level-1 ) ) { //如果得1000分即累计删除10行,速度加快20ms并升一级 tetris->speed-=20; tetris->level++;

23

俄罗斯方块改进-古有禹制作

} }

/******开始游戏******************************************************************************/ void start_game() {

HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE); //定义显示器句柄变量 struct Tetris t,*tetris=&t; //定义结构体的指针并指向结构体变量 unsigned char ch; //定义接收键盘输入的变量 tetris->count=0; //初始化俄罗斯方块数为0个 tetris->speed=300; //初始移动速度为300ms tetris->score=0; //初始游戏的分数为0分 tetris->level=1; //初始游戏为第1关 while(1)

{//循环产生方块,直至游戏结束

get_flag(tetris); //得到产生俄罗斯方块类型的序号 temp=tetris->flag; //记住当前俄罗斯方块序号 //打印下一个俄罗斯方块的图形(右边窗口) tetris->x=FrameX+2*Frame_width+6; tetris->y=FrameY+10; tetris->flag = tetris->next; print_tetris(hOut,tetris);

tetris->x=FrameX+Frame_width; //初始中心方块x坐标 tetris->y=FrameY-1; //初始中心方块y坐标 tetris->flag=temp; //取出当前的俄罗斯方块序号 while(1)

{//控制方块方向,直至方块不再下移

label:print_tetris(hOut,tetris);//打印俄罗斯方块 Sleep(tetris->speed); //延缓时间 clear_tetris(hOut,tetris); //清除痕迹

temp1=tetris->x; //记住中心方块横坐标的值 temp2=tetris->flag; //记住当前俄罗斯方块序号 if(kbhit())

{ //判断是否有键盘输入,有则用ch↓接收 ch=getch();

if(ch==75) //按←键则向左动,中心横坐标减2 {

tetris->x-=2; }

if(ch==77) //按→键则向右动,中心横坐标加2 {

tetris->x+=2; }

if(ch==72) //按↑键则变体即当前方块顺时针转90度

24

俄罗斯方块改进-古有禹制作

{

if( tetris->flag>=2 && tetris->flag<=3 ) {

tetris->flag++; tetris->flag%=2; tetris->flag+=2; }

if( tetris->flag>=4 && tetris->flag<=7 ) {

tetris->flag++; tetris->flag%=4; tetris->flag+=4; }

if( tetris->flag>=8 && tetris->flag<=11 ) {

tetris->flag++; tetris->flag%=4; tetris->flag+=8; }

if( tetris->flag>=12 && tetris->flag<=15 ) {

tetris->flag++; tetris->flag%=4; tetris->flag+=12; }

if( tetris->flag>=16 && tetris->flag<=19 ) {

tetris->flag++; tetris->flag%=4; tetris->flag+=16; } }

if(ch==32) //按空格键,暂停 {

print_tetris(hOut,tetris); while(1) {

if(kbhit()) //再按空格键,继续游戏 {

ch=getch();

if(ch==32) {

goto label;

25

俄罗斯方块改进-古有禹制作

} } } }

if(if_moveable(tetris)==0) //如果不可动,上面操作无效 {

tetris->x=temp1; tetris->flag=temp2; }

else //如果可动,执行操作 {

goto label; } }

tetris->y++; //如果没有操作指令,方块向下移动

if(if_moveable(tetris)==0) //如果向下移动且不可动,方块放在此处 {

tetris->y--;

print_tetris(hOut,tetris); del_full(hOut,tetris); break; } }

for(i=tetris->y-2;iy+2;i++) {//游戏结束条件:方块触到框顶位置 if(i==FrameY) {

j=0; //如果游戏结束,j=0 } }

if(j==0) {

system(\"cls\"); getch(); break; }

//清除下一个俄罗斯方块的图形(右边窗口) tetris->flag = tetris->next;

tetris->x=FrameX+2*Frame_width+6; tetris->y=FrameY+10; clear_tetris(hOut,tetris); } }

26

俄罗斯方块改进-古有禹制作

6. 参考文献

《C程序设计》第四版 谭浩强著 清华大学出版社出版 《C语言程序设计》 刘国成 科学出版社 《从问题到程序》 裘宗燕 北京大学出版社 《计算机二级教程》 刘瑞挺 南开大学出版社

《C语言程序设计基础教程》 陈朔鹰,兵器工业出版社 [5] C语言程序设计 姜仲秋 南京大学出版社

27

俄罗斯方块改进-古有禹制作

设计 俄罗斯方块的改进 题目 成绩 设计首先对游戏UI进行的草图的绘制,设计出游戏UI的大小和方位。通过合理的设置游戏UI界面,会给游戏体验着带来更加愉悦的游戏体验,并留下深刻的印象。UI初步绘制完成之后就是结构化程序比较重要的一步了,那就是算法的合理选择,一个程序的好坏不能单单课 程 设 计 主 要 内 容 对其UI的评价,而是算法是否合理,程序资源调配时否达到最优化的程度等。本程序采用数组与UI界面相结合的方法进行游戏规则判断。由于采用TC编译平台。不能提供丰富的预定义函数。所以所有函数除部分头文件均由后期编写。这样一来相比使用方便的VC++编译平台,更具有实际操作能力。更具有意义。但同时要牺牲开发效率。UI后期游戏中的绘制是根据数组中值的不断变化而绘制。UI和算法均设计完毕后。便进入了最后的调试阶段。在调试阶段,通过对程序的调试,发现了很多严重的问题,经过不计其数的修改,最后程序还是比较接近预期设计效果。由于设计能力有限 部分游戏功能没有得以体现这是设计者表示比较遗憾的。在以后的学习中会不断完善,谢谢。 指 导 老 师 评 语 签名: 20 年 月 日

28

因篇幅问题不能全部显示,请点此查看更多更全内容

Top