西工大C大作业第题.pdf
作业名称:作业名称:俄罗斯方块小游戏学学院:院:自动化学院班班级:级:学学号:号:姓姓名:名:团队组成:团队组成:西北工业大学西北工业大学20202020 年年 5 5 月月 3 3 日日请填写以下十项内容,将表格按页对齐(插入空行)请填写以下十项内容,将表格按页对齐(插入空行),勿删除任何部分。,勿删除任何部分。1 1、问题与背景(描述程序所要解决的问题或应用背景)、问题与背景(描述程序所要解决的问题或应用背景)1.1 游戏需求随机给出不同形状(长条形、Z 字形、反Z 字形、田字形、7 字形、反7 字形、T 字形)下落填充给定的区域,若填满一条便消掉,若在游戏中个形状填满了给定区域就判定输,弹出相应的提示。1.2 游戏界面需求良好的用户界面,有相关的操作方法(如速度、分数以及下一步要落下的形状等)。让方块在一定的区域内运动和变形,该区域用一种颜色表明,即用一种颜色作为背景,本游戏的背景为黑色。还需用另外一种颜色把黑色围起来,宽度适中,要实现美感。而不同的方块在本游戏中一律用灰色填充后,从而使界面更加清晰有条理。1.3 游戏方块需求良好的方块设计,绘制七种常见的基本图形(长条形、Z 字形、反 Z形、田字形、L 字形、反 L 形、T 字形)以及另外本程序加入的点形方块,哥哥方块要能实现它的变形,本游戏设置为逆时针变形。1.4 游戏控制的需求游戏控制分为多个方面,包括画面绘制,控制命令的分配、控制命令的处理,方块的绘制,方块的移动,方块的旋转,方块的下落和消层以及计分等。对各个命令的合理处理和综合控制十分重要,一旦出错可能导致整个程序的崩溃,因此设计要十分小心。2 2、开发工具(列出所使用的开发工具和第、开发工具(列出所使用的开发工具和第 3 3 方开发库)方开发库)Code:blockDEV-C+3 3、主要功能(详细说明程序的功能)、主要功能(详细说明程序的功能)这个游戏实现了 1 中的四个游戏需求,完成了如下功能:(1)随机给出不同形状(长条形、Z 字形、反 Z 字形、田字形、7 字形、反 7 字形、T 字形)下落填充给定的区域,并能完成消除以及结束的判断。(2)用户界面,有相关的提示(如速度、分数以及下一步要落下的形状等)。(3)绘制七种常见的基本图形(长条形、Z 字形、反 Z 形、田字形、L 字形、反 L 形、T 字形)以及点图形。(4)操作上用上下左右按键控制4 4、设计内容(详细描述解决问题的原理和方法、算法、数据结构等)、设计内容(详细描述解决问题的原理和方法、算法、数据结构等)1、程序流程图2、定义方块的数据结构方块是本游戏的基本要素,对于方块的设计,本游戏采用矩阵画出来在相应的位置用1和0表示,以实现各种方块形状。3、方块的变形方块要实现变形,其实就是通过 Exchange 俩画出不谈的图形来实现,当然乱画是不行的,而要控制其变化的情况,必须设定相应的图形描述,本程序是使用不同图形的不同 ID 码表示的方法来实现方块的描述的。能通过接收键盘指令(即向上键),将所得信号传递给接收函数,再通过信号处理函数改变当前方块的 ID 值,最后根据新的 ID 值打印出新的图形,从而实现了方块的变形。4、定时处理机制为了提高游戏的易控性和制动性,定时机制是很有必要的。经过定时器设置后,这里通过利用控制程序跳到定时器的时间的处理函数去实现,当固定时间片间隔到达后,先检测当前下坠物是否已经到达了底部,不是则进行下坠物向下移动一个单位的操作,是则到底后产生一个新的“下坠物”并代替旧的,将原先旧的“下坠物”用作当前激活状态下正在使用的下坠物,并对使用后的一些状态进行分析检测:是否马上下沉到底部,是则进行销毁操作:是否在到达底部的同时到达游戏区的顶部,从而判定游戏是否因违规而结束,弹出相应对话框供用户选择是否继续重新开始。5 5、程序文件与工程名称(标出程序中所有文件名、工程名称及其说明)、程序文件与工程名称(标出程序中所有文件名、工程名称及其说明)(1)俄罗斯.cpp(2)俄罗斯.exe6 6、函数模块(程序中各个函数的原型声明及其说明)、函数模块(程序中各个函数的原型声明及其说明)(1)/*设置光标位置*/void SetCursor(int x,int y)(2)/*初始化图*/void INITMAP()(3)/*右上方提前显示方块*/node bl5;void Former_Print_block(int n)(4)/*获取不同的方块,出现在中间*/node block5;/全局使用的核心!void print_block(int n)(5)/*按 上 键 旋转*/void Exchange(int m)(6)/*清除当前方块*/void clear_cube(node*block)(7)/*打印当前方块*/void printt_cube(node*block)(8)/*按键*/void Move(int m,int n)(9)/*判断是否可以向左移动*/int If_Can_Left(node*block)(10)/*判断是否可以向右移动*/int If_Can_Right(node*block)(11)/*打印图*/void print_map()(12)/*下降一格*/void cube_drop(node*block)(13)/*到达底部返回 1*/int is_at_botton(node*block)(14)/*到达底部 map 赋值为 1*/void print_map(node*block)(15)/*是否可以消去并消去*/int Can_It_Cut()(16)/*是否 GameOver*/int is_gameover(int num)(17)/*游戏结束,再来一局,清理屏幕*/void Clear_map()(18)/*main 函数程序入口*/int main()7 7、使用说明(运行程序的小型说明书)、使用说明(运行程序的小型说明书)游戏操作说明:控制方块在规定区域内逆时针改变形状控制方块在规定区域内下沉到底部控制方块在规定区域内向左移动控制方块在规定区域内向又移动Esc退出游戏Enter继续游戏8 8、程序开发总结(简要叙述编写本作业的收获与思考)、程序开发总结(简要叙述编写本作业的收获与思考)本次 C+课程设计前期准备阶段,设想一些构想和主要任务;后期这是具体功能的私实现。这次设计中我遇到了不少困难,本来想设计实现双人版对战,美化界面等但由于时间仓促最终没有完成,心里不免有些遗憾,但在实现类的封装和类的继承和多态性时,也遇到了不少问题,通过和同学们的一起讨论和分析,问题最终都得到了解决。通过这次课程设计,是我懂得了不少东西。我们在日常的学习中应该注意对所学的知识进行实践运用,在学习时应该进行深入的了解,体会知识,这对我们今后的学习和工作都会有很大的帮助。通过此次的时间,我体会到学以致用的乐趣,收获了很多。9 9、运行截图(附上程序运行的截图画面,至少有、运行截图(附上程序运行的截图画面,至少有 1 1 幅,截图越翔实得分幅,截图越翔实得分越高)越高)Windows 中抓取当前活动窗口:Alt+Print Screen,抓取全屏:PrintScreen。或者使用 HyperSnap 等软件(百度搜索)。游戏运行中截图:游戏结束截图:1010、源程序(附上程序源代码,若是多个文件,标出文件名)、源程序(附上程序源代码,若是多个文件,标出文件名)#include#include#include#include#include#include using namespace std;#define me(a)memset(a,0,sizeof(a)#define judge(bl,ok)for(i=0;i5;i+)if(bli.x&mapbli.xbli.y)ok=0#define is_pure(node,ok)if(mapnode.xnode.y)ok=0 const int HEIGHT=24,LENGTH=40,SIDE=22;char INIT_MAPHEIGHT+1LENGTH+1;int mapHEIGHTSIDE;struct nodeint x,y;int color;const int TIME_DWELL=1000;int state=0;/*获取句柄*/HANDLE Output=GetStdHandle(STD_OUTPUT_HANDLE);HANDLE Input=GetStdHandle(STD_INPUT_HANDLE);/*设置光标位置*/void SetCursor(int x,int y)COORD cd=x,y;SetConsoleCursorPosition(Output,cd);/*初始化图*/void INITMAP()for(int i=0;iHEIGHT;i+)for(int j=0;jSIDE;j+)if(i=0|i=HEIGHT-1|j=0|j=SIDE-1)mapij=1;else mapij=0;/*右上方提前显示方块*/node bl5;void Former_Print_block(int n)int i;for(i=0;i5;i+)bli.x=bli.y=0;if(n=0)bl0.x=3,bl0.y=28;bl1.x=3,bl1.y=30;bl2.x=4,bl2.y=30;bl3.x=4,bl3.y=32;if(n=1)bl0.x=3,bl0.y=32;bl1.x=3,bl1.y=30;bl2.x=4,bl2.y=30;bl3.x=4,bl3.y=28;if(n=2)bl0.x=3,bl0.y=30;bl1.x=4,bl1.y=28;bl2.x=4,bl2.y=30;bl3.x=4,bl3.y=32;if(n=3)bl0.x=3,bl0.y=27;bl1.x=3,bl1.y=29;bl2.x=3,bl2.y=31;bl3.x=3,bl3.y=33;if(n=4)bl0.x=3,bl0.y=29;bl1.x=3,bl1.y=31;bl2.x=4,bl2.y=29;bl3.x=4,bl3.y=31;if(n=5)bl0.x=3,bl0.y=28;bl1.x=4,bl1.y=28;bl2.x=4,bl2.y=30;bl3.x=4,bl3.y=32;if(n=6)bl0.x=3,bl0.y=32;bl1.x=4,bl1.y=28;bl2.x=4,bl2.y=30;bl3.x=4,bl3.y=32;for(i=0;i5;i+)SetCursor(bli.y,bli.x);printf();/*获取不同的方块,出现在中间*/node block5;/全局使用的核心!void print_block(int n)int i;for(i=0;i5;i+)blocki.x=blocki.y=0;if(n=0)block0.x=1,block0.y=7;block1.x=1,block1.y=9;block2.x=2,block2.y=9;block3.x=2,block3.y=11;if(n=1)block0.x=1,block0.y=11;block1.x=1,block1.y=9;block2.x=2,block2.y=9;block3.x=2,block3.y=7;if(n=2)block0.x=1,block0.y=9;block1.x=2,block1.y=7;block2.x=2,block2.y=9;block3.x=2,block3.y=11;if(n=3)block0.x=1,block0.y=7;block1.x=1,block1.y=9;block2.x=1,block2.y=11;block3.x=1,block3.y=13;if(n=4)block0.x=1,block0.y=9;block1.x=1,block1.y=11;block2.x=2,block2.y=9;block3.x=2,block3.y=11;if(n=5)block0.x=1,block0.y=7;block1.x=2,block1.y=7;block2.x=2,block2.y=9;block3.x=2,block3.y=11;if(n=6)block0.x=1,block0.y=11;block1.x=2,block1.y=7;block2.x=2,block2.y=9;block3.x=2,block3.y=11;for(i=0;i5;i+)SetCursor(blocki.y,blocki.x);printf();/*按 上 键 旋转*/void Exchange(int m)int i,ok=1;node blo5;for(i=0;i5;i+)bloi=blocki;if(m=0)if(state=0)blo0.x+=1;blo0.y+=2;blo2.x-=1;blo2.y+=2;blo3.x-=2;judge(blo,ok);if(mapblo0.xblo0.y-2)ok=0;if(ok)for(i=0;i5;i+)blocki=bloi;state=1;else blo0.x-=1;blo0.y-=2;blo2.x+=1;blo2.y-=2;blo3.x+=2;judge(blo,ok);if(mapblo1.x-1blo1.y)ok=0;if(ok)for(i=0;i5;i+)blocki=bloi;state=0;else if(m=1)if(state=0)blo0.x-=1;blo0.y-=2;blo2.x-=1;blo2.y+=2;blo3.y+=4;judge(blo,ok);if(mapblo1.xblo1.y-2)ok=0;if(ok)for(i=0;i5;i+)blocki=bloi;state=1;else blo0.x+=1;blo0.y+=2;blo2.x+=1;blo2.y-=2;blo3.y-=4;judge(blo,ok);if(mapblo0.x-1blo0.y)ok=0;if(ok)for(i=0;i5;i+)blocki=bloi;state=0;else if(m=2)if(state=0)blo0.x+=1;blo0.y-=2;blo1.x+=1;blo1.y+=2;blo3.x-=1;blo3.y-=2;judge(blo,ok);if(mapblo0.x+1blo0.y|mapblo0.x-1block0.y|mapblo3.xblo3.y+2)ok=0;if(ok)for(i=0;i5;i+)blocki=bloi;state=1;else if(state=1)blo0.x+=1;blo0.y+=2;blo1.x-=1;blo1.y+=2;blo3.x+=1;blo3.y-=2;judge(blo,ok);if(mapblo0.xblo0.y+2|mapblo0.xblo0.y-2|mapblo3.x-1blo3.y)ok=0;if(ok)for(i=0;i5;i+)blocki=bloi;state=2;else if(state=2)blo0.x-=1;blo0.y+=2;blo1.x-=1;blo1.y-=2;blo3.x+=1;blo3.y+=2;judge(blo,ok);if(mapblo0.x+1blo0.y|mapblo0.x-1blo0.y|mapblo3.xblo3.y-2)ok=0;if(ok)for(i=0;i5;i+)blocki=bloi;state=3;else blo0.x-=1;blo0.y-=2;blo1.x+=1;blo1.y-=2;blo3.x-=1;blo3.y+=2;judge(blo,ok);if(mapblo0.xblo0.y+2|mapblo0.xblo0.y-2|mapblo3.x+1blo1.y)ok=0;if(ok)for(i=0;i5;i+)blocki=bloi;state=0;else if(m=3)if(state=0)blo0.x+=1;blo0.y+=2;blo2.x-=1;blo2.y-=2;blo3.x-=2;blo3.y-=4;judge(blo,ok);if(mapblo0.xblo0.y-2|mapblo2.xblo2.y+2)ok=0;if(ok)for(i=0;i5;i+)blocki=bloi;state=1;else blo0.x-=1;blo0.y-=2;blo2.x+=1;blo2.y+=2;blo3.x+=2;blo3.y+=4;judge(blo,ok);if(mapblo0.x+1blo0.y|mapblo2.x-1blo2.y)ok=0;if(ok)for(i=0;i5;i+)blocki=bloi;state=0;else if(m=5)if(state=0)blo0.x+=2;blo1.x+=1;blo1.y+=2;blo3.x-=1;blo3.y-=2;judge(blo,ok);if(mapblo3.xblo3.y+2)ok=0;if(ok)for(i=0;i5;i+)blocki=bloi;state=1;else if(state=1)blo0.y+=4;blo1.x-=1;blo1.y+=2;blo3.x+=1;blo3.y-=2;judge(blo,ok);if(mapblo3.x-1blo3.y)ok=0;if(ok)for(i=0;i5;i+)blocki=bloi;state=2;else if(state=2)blo0.x-=2;blo1.x-=1;blo1.y-=2;blo3.x+=1;blo3.y+=2;judge(blo,ok);if(mapblo3.xblo3.y-2)ok=0;if(ok)for(i=0;i5;i+)blocki=bloi;state=3;else blo0.y-=4;blo1.x+=1;blo1.y-=2;blo3.x-=1;blo3.y+=2;judge(blo,ok);if(mapblo3.x+1blo3.y)ok=0;if(ok)for(i=0;i5;i+)blocki=bloi;state=0;else if(m=6)if(state=0)blo0.y-=4;blo1.x+=1;blo1.y+=2;blo3.x-=1;blo3.y-=2;judge(blo,ok);if(mapblo1.xblo1.y-2)ok=0;if(ok)for(i=0;i5;i+)blocki=bloi;state=1;else if(state=1)blo0.x+=2;blo1.x-=1;blo1.y+=2;blo3.x+=1;blo3.y-=2;judge(blo,ok);if(mapblo1.x+1blo1.y)ok=0;if(ok)for(i=0;i5;i+)blocki=bloi;state=2;else if(state=2)blo0.y+=4;blo1.x-=1;blo1.y-=2;blo3.x+=1;blo3.y+=2;judge(blo,ok);if(mapblo1.xblo1.y+2)ok=0;if(ok)for(i=0;i5;i+)blocki=bloi;state=3;else blo0.x-=2;blo1.x+=1;blo1.y-=2;blo3.x-=1;blo3.y+=2;judge(blo,ok);if(mapblo1.x-1blo1.y)ok=0;if(ok)for(i=0;i5;i+)blocki=bloi;state=0;/*清除当前方块*/void clear_cube(node*block)for(int i=0;i5;i+)if(blocki.x)SetCursor(blocki.y,blocki.x);printf();/*打印当前方块*/void printt_cube(node*block)for(int i=0;i5;i+)if(blocki.x)SetCursor(blocki.y,blocki.x);printf();/*按键*/void Move(int m,int n)int i;if(n=0)/左 for(i=0;i5&blocki.x;i+)if(blocki.y)blocki.y-=2;if(n=1)/右 for(i=0;i5&blocki.x;i+)if(blocki.y)blocki.y+=2;if(n=2)/上 Exchange(m);if(n=3)/下 int ok=1;while(ok)for(i=0;i5;i+)if(blocki.x)if(mapblocki.x+1blocki.y)ok=0;if(ok)for(i=0;i5;i+)if(blocki.x)blocki.x+=1;/*判断是否可以向左移动*/int If_Can_Left(node*block)int ok=1,i;int min=22;for(i=0;i5&blocki.x;i+)if(blocki.ymin)min=blocki.y;if(min-21)ok=0;for(i=0;i5&blocki.x;i+)if(blocki.x)if(mapblocki.xblocki.y-2)ok=0;return ok;/*判断是否可以向右移动*/int If_Can_Right(node*block)int ok=1,i;int max=0;for(i=0;imax)max=blocki.y;if(max+219)ok=0;for(i=0;i5&blocki.x;i+)if(blocki.x)if(mapblocki.xblocki.y+2)ok=0;return ok;/*打印图*/void print_map()int i,j;me(INIT_MAP);for(i=0;iHEIGHT;i+)if(i=0|i=23)for(j=0;jLENGTH;j+)printf(%c,INIT_MAPij=-);else printf(%c,INIT_MAPi0=|);for(j=1;jSIDE-1;j+)printf(%c,INIT_MAPij=);printf(%c%c,INIT_MAPij+=|,INIT_MAPij+=|);for(;jLENGTH-1;j+)printf(%c,INIT_MAPij=);printf(%c,INIT_MAPij=|);coutendl;SetCursor(SIDE+1,10);printf(=);SetCursor(SIDE+1,11);printf(Speed);SetCursor(SIDE+1,13);printf(=);SetCursor(SIDE+1,14);printf(Score);SetCursor(SIDE+1,16);printf(=);SetCursor(SIDE+1,19);printf(Created By );SetCursor(SIDE+1,20);/*下降一格*/void cube_drop(node*block)int i;for(i=0;i5;i+)if(blocki.x)blocki.x+=1;/*到达底部返回 1*/int is_at_botton(node*block)for(int i=0;i5;i+)if(blocki.x&mapblocki.x+1blocki.y)return 1;return 0;/*到达底部 map 赋值为 1*/void print_map(node*block)int i;for(i=0;i1;i-)int ok=1;for(j=1;j1;j-)for(int k=1;k1;i-)for(int j=1;jSIDE-1;j+=2)SetCursor(j,i);if(mapij)printf();else printf();return cut;/*是否 GameOver*/int is_gameover(int num)int i,j,ok=1;print_block(num);for(i=0;i5;i+)if(blocki.x&mapblocki.xblocki.y)ok=0;if(!ok)char aa20=Game Over!;for(i=9;i12;i+)if(i=10)int t=0;for(int j=4;j=5&j17)printf(%c,aat+);else printf();else for(j=4;j0;i-)for(int j=1;jSIDE-1;j+=2)mapij=0;SetCursor(j,i);printf();int main()srand(time(NULL);print_map();INITMAP();int gameover=1;int ok=1;/用于判断游戏是否结束 while(gameover)int Score=0;int Speed=0;int numm=(rand()%7)*(rand()%7)%7;Sleep(TIME_DWELL);while(ok)SetCursor(SIDE+4+Speed,12);printf();SetCursor(SIDE+4,15);printf();SetCursor(SIDE+4+Speed,12);printf(*);SetCursor(SIDE+4,15);printf(%d,Score);Sleep(200);int num=numm;/第 num 个方块,初始时为 0 这个状态 numm=(rand()%7)*(rand()%7)%7;/提前显示的方块 clear_cube(bl);Former_Print_block(numm);/打印提前显示的方块 print_block(num);/打印要落下的方块初始位置 state=0;int botton=1;/用于判断是否已经落到底部 while(botton)clear_cube(block);/*键位响应*/if(GetAsyncKeyState(VK_LEFT)&If_Can_Left(block)Move(num,0);else if(GetAsyncKeyState(VK_RIGHT)&If_Can_Right(block)Move(num,1);else if(GetAsyncKeyState(VK_UP)Move(num,2);else if(GetAsyncKeyState(VK_DOWN)Move(num,3);botton=0;if(!is_at_botton(block)cube_drop(block);else botton=0;printt_cube(block);/打印当前方块 if(!botton)print_map(block);Sleep(100*(4-Score/80);int cut=Can_It_Cut();if(cut)Score+=cut*10;Speed=Score/80;ok=is_gameover(numm);if(GetAsyncKeyState(VK_ESCAPE)gameover=0;else if(GetAsyncKeyState(VK_RETURN)Clear_map();ok=1;return 0;