资源描述
课程设计报告题 目:俄罗斯方块设计设 计 者:* *专业班级:* *学 号:* *指导教师:* *所属系部:* * * *年* *月* *日、目录目录2一设计的目的和要求3二设计内容3三设计任务3四游戏基本规则3五总体设计4六详细设计与程序实现4七.主要处理流程8八.游戏设计源程序10九.截图30十 心得体会31十一 参考文献31一设计的目的和要求加深对C语言课程所学知识的理解,进一步巩固C语言语法规则。学会编制结构清晰、风格良好、数据结构适当的语言程序,从而具备解决综合性实际问题的能力。二设计内容在熟练掌握C语言的基本知识:数据类型(整形、实型、字符型、指针、数组、结构等);运算类型(算术运算、逻辑运算、自增自减运算、赋值运算等);程序结构(顺序结构、判断选择结构、循环结构);大程序的功能分解方法(即函数的使用)等。进一步掌握各种函数的应用,包括时间函数、绘图函数,以及文件的读写操作等。三设计任务1.游戏欢迎界面。2.游戏执行功能,包括计算得分。3.游戏结束界面。四游戏基本规则 游戏共由7种不同形状的方块组成,游戏开始以后随机产生一个方块由屏幕的顶端开始向下落下,落到低端则固定到桌面,并开始下一个方块。在游戏窗口的左边作为游戏的桌面,用宽度10和高度20的表格表示。游戏桌面的右边靠上显示得分,最下边显示游戏帮助。如果固定到游戏桌面的方块超出了顶端游戏结束。方块固定以后如果桌面上已经固定了的方块满一行,则消除一行并将消除行之上的部分向下移动,消除一行得1分。基本操作如下: (1) 方块落下的过程中可以用左右方向键移动方块的位置。(2) 上方向键用来旋转方块,即所谓的变形。(3) 下方向键用来加速方块下落。(4) 游戏中按下回车键暂停游戏。再次按回车键继续游戏。五总体设计 游戏以Windows窗口的形式运行。窗口的左边作为游戏的桌面,桌面的大小是10X20个单位。随机出现一个方块从游戏桌面的上方开始向下移动,并随机生产一个向下方块显示到桌面的右边。方块的颜色分为7种。在显示下一个方块的上面显示玩家得分,下面显示游戏帮助。当方块不能向下移动的时候,将方块固定到桌面上,固定的方法是将方块的每个部分所在的坐标的桌面数值设置为1.固定以后,判断桌面数值的每一行,如果一行的数值全部都是1的话,就将桌面上的这一行数值删除,并将这一行上面所有行向下移动一行。删除一行的同时,玩家的得分加1。上述操作完成以后,将下一个方块从桌面的顶部开始下落,重新生成下一个方块。在固定方块到桌面的时候,还要判断方块的最顶端部分是否超出桌面范围,并以此作为游戏结束的依据。六详细设计与程序实现一.方块设计 游戏的核心和重点在于7种方块的设计,这7种方块的形状分别为Z形、S形、线形、T形、方形、L形和反L形、其数据结构分别用相对坐标表示如下:0,-1,0,0,-1,0,-1,10,-1,0,0,1,0,1,10,-1,0,0,0,1,0,2-1,0,0,0,1,0,0,10,0,1,0,0,1,1,1-1,-1,0,-1,0,0,0,11,-1,0,-1,0,0,0,1 因为屏幕的左上角为原点,向右为x轴增加的方向,向下为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形方块LL型方块对号入座如图所示:-1,-1,0,-1,0,0,0,1L型方块坐标图反L形方块反L形方块对号入座如图所示:1,-1,0,-1,0,0,0,1 L形方块坐标图在方块相对坐标基础上加上x和y的偏移量,就可以在屏幕的不同位置得到相应的反面方块。完成方块的向左,向右及向下移动。将方块的相对坐标旋转90度得到的新坐标就算变形后的坐标。顺时针操作的公式是:x=-yy=x逆时针旋转操作的公式是:x=yy=x其中,x和y代表旋转前方块的相对坐标,x和y代表旋转后方块的相对坐标。 唯一例外的是方形方块,在旋转处理的时候不做处理。七.主要处理流程 游戏的主要流程图如下: 左键 上键下键当前方块能够左移向左移动当前方块当前方块能够右移向右移动当前方块当前方块能够旋转当前方块能够下移旋转当前方块向下移动当前方块右键否八.游戏设计源程序/zhangdi#include#include#include#includetetris.h#define APP_NAME TETRIS#define APP_TITLE Tetris Game#define GAMEOVER GAME OVER#define SHAPE_COUNT 7#define BLOCK_COUNT 4#define MAX_SPEED 5#define COLUMS 10#define ROWS 20#define RED RGB(255,0,0)#define YELLOW RGB(255,255,0)#define GRAY RGB(128,128,128)#define BLACK RGB(0,0,0)#define WHITE RGB(255,255,255)#define STONE RGB(192,192,192)#define CHARS_IN_LINE 14#define SCORE SCORE %4d/全局变量定义char score_charCHARS_IN_LINE=0;char*press_enter=Press Enter key.;/帮助提示信息char*help= Press space or up key to transform shape., Press left or right key to move shape., Press down key to speed up., Press enter key to pause game., Enjoy it. :-), 0;/枚举游戏的状态enum game_state game_start, game_run, game_pause, game_overstate= game_start;/定义方块的颜色COLORREF shape_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);/定义方块的种类型int shape_coordinateSHAPE_COUNTBLOCK_COUNT2=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;int score=0;/得分shape next=0;/下一个方块shape current=0;/当前方块int current_coordinate42=0;/当前方块的每一部分坐标int tableROWSCOLUMS=0;/游戏桌面int shapex=0;/当前方块的x坐标int shapey=0;/当前方块的y坐标int speed=0;/方块下移速度clock_t start=0;/每一帧开始时间clock_t finish=0;/每一帧结束时间/*windows 绘图用变量*/HWND gameWND; /*window 窗口句柄*/HBITMAP memBM; /*内存位图*/HBITMAP memBMOld; /*内存原始位图*/HDC memDC; /*内存DC*/RECT clientRC; /*客户端矩形区域*/HBRUSH blackBrush; /*黑色画笔*/HBRUSH stoneBrush; /*深灰色画笔*/HBRUSH shapeBrushSHAPE_COUNT; /*方块画笔,种方块,每种一个*/HPEN grayPen; /*灰色画笔*/HFONT bigFont; /*大字体,用来显示游戏名字和Game Over*/HFONT smallFont; /*小字体用来显示帮助信息等*/*主要处理函数*/int maxX() /*取最大坐标,函数名称:maxX;函数功能:取得当前方块的最大x坐标*/ int i=0; /*取最大坐标,函数名称:maxX;函数功能:取得当前方块的最大x坐标*/ int x=current_coordinatei0; /*取最大坐标,函数名称:maxX;函数功能:取得当前方块的最大x坐标*/ int m=x; /*取最大坐标,函数名称:maxX;函数功能:取得当前方块的最大x坐标*/ for (i=1; iBLOCK_COUNT;i+) /*取最大坐标,函数名称:maxX;函数功能:取得当前方块的最大x坐标*/ x=current_coordinatei0; /*取最大坐标,函数名称:maxX;函数功能:取得当前方块的最大x坐标*/ if (mx) /*取最大坐标,函数名称:maxX;函数功能:取得当前方块的最大x坐标*/ m=x; /*取最大坐标,函数名称:maxX;函数功能:取得当前方块的最大x坐标*/ return m; /*取最大坐标,函数名称:maxX;函数功能:取得当前方块的最大x坐标*/ int minX() /*取最小坐标,函数名称:minX;函数功能:取得当前方块的最小x坐标*/ int i=0; /*取最小坐标,函数名称:minX;函数功能:取得当前方块的最小x坐标*/ int x=current_coordinatei0; /*取最小坐标,函数名称:minX;函数功能:取得当前方块的最小x坐标*/ int m=x; /*取最小坐标,函数名称:minX;函数功能:取得当前方块的最小x坐标*/ for (i=1; ix) /*取最小坐标,函数名称:minX;函数功能:取得当前方块的最小x坐标*/ m=x; /*取最小坐标,函数名称:minX;函数功能:取得当前方块的最小x坐标*/ return m; /*取最小坐标,函数名称:minX;函数功能:取得当前方块的最小x坐标*/ /*逆时针旋转方块*/void turn_left() /*函数名称:turn_left ;函数功能:将当前方块逆时针旋转度*/ int i=0; /*函数名称:turn_left ;函数功能:将当前方块逆时针旋转度*/ int x,y; /*函数名称:turn_left ;函数功能:将当前方块逆时针旋转度*/ for (i=0;i4;i+) /*函数名称:turn_left ;函数功能:将当前方块逆时针旋转度*/ x=current_coordinatei0; /*函数名称:turn_left ;函数功能:将当前方块逆时针旋转度*/ y=current_coordinatei1; /*函数名称:turn_left ;函数功能:将当前方块逆时针旋转度*/ current_coordinatei0=y; /*函数名称:turn_left ;函数功能:将当前方块逆时针旋转度*/ current_coordinatei1=-x; /*函数名称:turn_left ;函数功能:将当前方块逆时针旋转度*/ /*顺时针旋转方块*/void turn_right() /*函数名称:turn_right ;函数功能:将当前方块顺时针旋转度*/ int i=0; /*函数名称:turn_right ;函数功能:将当前方块顺时针旋转度*/ int x,y; /*函数名称:turn_right ;函数功能:将当前方块顺时针旋转度*/ for (i=0;i4;i+) /*函数名称:turn_right ;函数功能:将当前方块顺时针旋转度*/ x=current_coordinatei0; /*函数名称:turn_right ;函数功能:将当前方块顺时针旋转度*/y=current_coordinatei1; /*函数名称:turn_right ;函数功能:将当前方块顺时针旋转度*/current_coordinatei0=-y; /*函数名称:turn_right ;函数功能:将当前方块顺时针旋转度*/current_coordinatei1=x; /*函数名称:turn_right ;函数功能:将当前方块顺时针旋转度*/ /*检查方块是否越界*/int out_of_table() /*函数名称:out_of_table;函数功能:检查当前方块是否超出桌面范围*/ int i=0; /*函数名称:out_of_table;函数功能:检查当前方块是否超出桌面范围*/ int x,y; /*函数名称:out_of_table;函数功能:检查当前方块是否超出桌面范围*/ for (i=0;i4;i+) /*函数名称:out_of_table;函数功能:检查当前方块是否超出桌面范围*/ x=shapex+current_coordinatei0; /*函数名称:out_of_table;函数功能:检查当前方块是否超出桌面范围*/y=shapey+current_coordinatei1; /*函数名称:out_of_table;函数功能:检查当前方块是否超出桌面范围*/if (x(COLUMS-1)|y(ROWS-1) /*函数名称:out_of_table;函数功能:检查当前方块是否超出桌面范围*/ return 1; /*函数名称:out_of_table;函数功能:检查当前方块是否超出桌面范围*/ if (tableyx) /*函数名称:out_of_table;函数功能:检查当前方块是否超出桌面范围*/ return 1; /*函数名称:out_of_table;函数功能:检查当前方块是否超出桌面范围*/ return 0; /*函数名称:out_of_table;函数功能:检查当前方块是否超出桌面范围*/*旋转方块*/void transform() /*函数名称:transform; 函数功能:旋转当前方块*/ if (current=SquareShape) /*函数名称:transform; 函数功能:旋转当前方块*/ return; /*函数名称:transform; 函数功能:旋转当前方块*/ turn_right(); /*函数名称:transform; 函数功能:旋转当前方块*/ if (out_of_table() /*函数名称:transform; 函数功能:旋转当前方块*/ turn_left(); /*函数名称:transform; 函数功能:旋转当前方块*/ /*判断方块能否向左移动*/int leftable() /*函数名称:leftable;函数功能:判断当前方块能否向左移动,能移动返回,否则返回*/ int i=0; /*函数名称:leftable;函数功能:判断当前方块能否向左移动,能移动返回,否则返回*/ int x,y; /*函数名称:leftable;函数功能:判断当前方块能否向左移动,能移动返回,否则返回*/ for (i=0;i4;i+) /*函数名称:leftable;函数功能:判断当前方块能否向左移动,能移动返回,否则返回*/ x=shapex+current_coordinatei0; /*函数名称:leftable;函数功能:判断当前方块能否向左移动,能移动返回,否则返回*/ y=shapey+current_coordinatei1; /*函数名称:leftable;函数功能:判断当前方块能否向左移动,能移动返回,否则返回*/ if (x=0|tableyx-1=1) /*函数名称:leftable;函数功能:判断当前方块能否向左移动,能移动返回,否则返回*/ return 0; /*函数名称:leftable;函数功能:判断当前方块能否向左移动,能移动返回,否则返回*/ return 1; /*函数名称:leftable;函数功能:判断当前方块能否向左移动,能移动返回,否则返回*/*判断方块能否向右移动*/int rightable() /*函数名称:rightable;函数功能:判断当前方块能否向右移动,能移动返回,否则返回*/ int i=0; /*函数名称:rightable;函数功能:判断当前方块能否向右移动,能移动返回,否则返回*/ int x,y; /*函数名称:rightable;函数功能:判断当前方块能否向右移动,能移动返回,否则返回*/ for (i=0;i=(COLUMS-1)|tableyx+1=1) /*函数名称:rightable;函数功能:判断当前方块能否向右移动,能移动返回,否则返回*/ return 0; /*函数名称:rightable;函数功能:判断当前方块能否向右移动,能移动返回,否则返回*/ return 1; /*函数名称:rightable;函数功能:判断当前方块能否向右移动,能移动返回,否则返回*/*判断方块能否向下移动*/int downable() /*函数名称:downable;函数功能:判断当前方块能否向下移动,能移动返回,否则返回*/ int i=0; /*函数名称:downable;函数功能:判断当前方块能否向下移动,能移动返回,否则返回*/ int x,y; for (i=0;i=(ROWS-1)|tabley+1x=1) /*函数名称:downable;函数功能:判断当前方块能否向下移动,能移动返回,否则返回*/ return 0; /*函数名称:downable;函数功能:判断当前方块能否向下移动,能移动返回,否则返回*/ return 1; /*函数名称:downable;函数功能:判断当前方块能否向下移动,能移动返回,否则返回*/ /*向左移动当前方块*/void move_left() /*函数名称:move_left;函数功能:向左移动当前方块*/ if (leftable() /*函数名称:move_left;函数功能:向左移动当前方块*/ shapex-; /*函数名称:move_left;函数功能:向左移动当前方块*/*向右移动当前方块*/void move_right() /*函数名称:move_right;函数功能:向右移动方块*/ if (rightable() /*函数名称:move_right;函数功能:向右移动方块*/ shapex+; /*函数名称:move_right;函数功能:向右移动方块*/ /*向下移动当前方块*/void move_down() /*函数名称:move_down;函数功能:向下移动当前方块*/ if (downable() /*函数名称:move_down;函数功能:向下移动当前方块*/ shapey+; /*函数名称:move_down;函数功能:向下移动当前方块*/ else if (add_to_table() /*函数名称:move_down;函数功能:向下移动当前方块*/ remove_full(); /*函数名称:move_down;函数功能:向下移动当前方块*/next_shape(); /*函数名称:move_down;函数功能:向下移动当前方块*/ else state=game_over; /*函数名称:move_down;函数功能:向下移动当前方块*/ /*将当前方块固定到桌面上*/int add_to_table() /*函数名称:add_to_table;函数功能:将当前方块固定到桌面上,若返回,表示游戏结束*/ int i=0; /*函数名称:add_to_table;函数功能:将当前方块固定到桌面上,若返回,表示游戏结束*/ int x,y; /*函数名称:add_to_table;函数功能:将当前方块固定到桌面上,若返回,表示游戏结束*/ for (i=0;i4;i+) /*函数名称:add_to_table;函数功能:将当前方块固定到桌面上,若返回,表示游戏结束*/ x=shapex+current_coordinatei0; /*函数名称:add_to_table;函数功能:将当前方块固定到桌面上,若返回,表示游戏结束*/y=shapey+current_coordinatei1; /*函数名称:add_to_table;函数功能:将当前方块固定到桌面上,若返回,表示游戏结束*/if (y0;i-) /*函数名称:remove_full;函数功能:删除桌面上填满的行*/ c=0; /*函数名称:remove_full;函数功能:删除桌面上填满的行*/ for(j=0;j(MAX_SPEED-speed)*100) move_down();start=clock();InvalidateRect(gameWND,NULL,TRUE); /操作当前方块void next_shape() current=next; memcpy(current_coordinate, shape_coordinatenext, sizeof(int)*BLOCK_COUNT*2); shapex=(COLUMS-(maxX(current)-minX(current) /2; shapey=0; next = random(SHAPE_COUNT);/取随机数int random(int seed) if (seed=0) return 0; srand(unsigned)time(NULL); return (rand() % seed);/绘图void paint() PAINTSTRUCT ps; HDC hdc; draw_table(); hdc=BeginPaint(gameWND,&ps); BitBlt(hdc, clientRC.left, clientRC.top, clientRC.right, clientRC.bottom, memDC, 0, 0, SRCCOPY); EndPaint(gameWND, &ps);/绘制游戏桌面void draw_table() HBRUSH hBrushOld; HPEN hPenOld; HFONT hFontOld; RECT rc; int x0, y0, w; int x, y, i, j; char* str; w = clientRC.bottom / (ROWS+2);/一个方块的宽度 x0 = y0 =w; FillRect(memDC, &clientRC,blackBrush);/用黑色矩形填充桌面背景区 /如果游戏是开始或结束状态 if(state = game_start | state = game_over) memcpy(&rc, &clientRC, sizeof(RECT);rc.bottom =rc.bottom /2;hFontOld= SelectObject(memDC, bigFont);SetBkColor(memDC,BLACK);/如果游戏是开始状态,用黄色字显示游戏开始画面if(state=game_start) str = APP_TITLE; SetTextColor(memDC,YELLOW);else/如果游戏是结束状态,用红色字显示GAME OVER str = GAMEOVER; SetTextColor(memDC,RED); DrawText(memDC, str, strlen(str), &rc, DT_SINGLELINE | DT_CENTER | DT_BOTTOM);SelectObject(memDC, hFontOld); hFontOld=SelectObject(memDC, smallFont);rc.top= rc.bottom;rc.bottom =rc.bottom *2;if (state = game_over) SetTextColor(memDC, YELLOW); sprintf(score_char, SCORE, score); DrawText(memDC, score_char, strlen(score_char), &rc, DT_SINGLELINE | DT_CENTER | DT_TOP);SetTextColor(memDC, STONE);DrawText(memDC, press_enter, strlen(press_enter), &rc, DT_SINGLELINE | DT_CENTER | DT_VCENTER); SelectObject(memDC, hFontOld);return; /画桌面上残留的方块 hBrushOld =SelectObject(memDC, stoneBrush); for (i=0; i ROWS; i+) for (j=0;jCOLUMS;j+) if (tableij=1) x=x0+j*w; y=y0+i*w; Rectangle(memDC,x,y,x+w+1,y+w+1); SelectObject(memDC,hBrushOld); /画当前的方块 hBrushOld=SelectObject(memDC,shapeBrushcurrent); for(i=0;i4;i+) x=x0+(current_coordinatei0+shapex)*w;y=y0+(current_coordinatei1+shapey)*w;if(xx0 | yy0) continue;Rectangle(memDC,x,y,x+w+1,y+w+1); SelectObject(memDC,hBrushOld); /画桌上的表格线条 hPenOld=SelectObject(memDC,grayPen); for(i=0;i=ROWS;i+) MoveToEx(memDC,x0,y0+i*w,NULL);LineTo(memDC,x0+COLUMS*w,y0+i*w); for(i=0;i=COLUMS;i+) MoveToEx(memDC,x0+i*w,y0,NULL);LineTo(memDC,x0+i*w,y0+ROWS*w); SelectObject(memDC,hPenOld); /画玩家得分 x0=x0+COLUMS*w+3*w; y0=y0+w; hFontOld=SelectObject(memDC,smallFont);/选择字体 SetTextColor(memDC,YELLOW);/设置字体颜色 sprintf(score_char,SCORE,score); TextOut(memDC,x0,y0,score_char,strlen(score_char);/输出得分 /画下一个方块 y0 +=w; SetTextColor(memDC,STONE); TextOut(memDC,x0,y0,NEXT,4); x0=x0+w; y0+=2*w; hBrushOld=SelectObject(memDC,shapeBrushnext); for(i=0;i4;i+) x=x0+shape_coordinatenexti0*w;y=y0+shape_coordinatenexti1*w;Rectangle(memDC,x,y,x+w+1,y+w+1); SelectObject(memDC,hBrushOld); /打印帮助信息 x0=(COLUMS+2)*w; y0+=4*w; SetTextColor(memDC,GRAY); i=0; while(helpi) TextOut(memDC,x0,y0,helpi,strlen(helpi); y0+=w; i+; SelectObject(memDC,hFontOld);/xueshuang/处理按键void key_down(WPARAM wParam) /*如果游戏状态不是运行状态,按下回车键*/ if(state !=game_run) if(wParam=VK_RETURN) switch(state ) case game_start:/*游戏开始状态*/ next_shape(); state=game_run; break;case game_pause:/*游戏暂停状态*/ state=game_run; break;case game_over:/*游戏结束状态*/ new_game(); next_shape(); state=game_run; break; else/*如果游戏状态是运行状态*/ switch(wParam) case VK_SPACE: case VK_UP: transform();/*按空格键或向上键,旋转
展开阅读全文