最近在看俄罗斯方块的游戏,看到一个大神写的俄罗斯方块代码,非常非常优秀,拿出来解析给大家看看,也希望大家自己尝试运行试试,从中能得到一些启发。
#先了解下俄罗斯方块的几个形状一共分成7形状,有的形状有4种状态,有的形状有1种状态。
不管是多少种状态,一个方块需要一个2个字节来存储,也就是16bit来保存一个方块的信息。
基于上面的理论,我们可以使用4x4的数组来保存方块的信息。
注意,下面代码中的"■"占用的是2个字节。
方块数据,这两个数组其实是两种游戏模式的方块信息,我们只需要分析一种就可以了。
int TGM[7][4]={{0x159D,0x89AB,0x159D,0x89AB},{0x126A,0x4856,0x159A,0x4526},{0x926A,0x456A,0x1592,0x0456},{0x4859,0x4859,0x4859,0x4859},{0x5926,0x0156,0x5926,0x0156},{0x4159,0x4596,0x1596,0x4156},{0x156A,0x4152,0x156A,0x4152}}; int SRS[7][4]={{0x159D,0x89AB,0x26AE,0x4567},{0x0159,0x4856,0x159A,0x4526},{0x8159,0x456A,0x1592,0x0456},{0x4859,0x4859,0x4859,0x4859},{0x4815,0x459A,0x5926,0x0156},{0x4159,0x4596,0x1596,0x4156},{0x0459,0x8596,0x156A,0x4152}};
我们分析这段代码
/***********擦除显示*************/ int Display(int x, int y, int CAC, int Mode) { for(j=0;j<=3;j++){ P[j]=CAC&0xF, CAC>>=4; if (Mode==1){Pos((P[j]>>2)+x,(P[j]&0x3)+y);printf("■");} else if(Mode==0){Pos((P[j]>>2)+x,(P[j]&0x3)+y);printf(" ");} } return 0; }
P[j]=CAC&0xF取到的是 4个bit,然后通过判断这 4个bit决定输出方块的位置。
我们拿0这个方块的数据0x4859对应的二进制0B0100100001011001来做个例子。
0100 ----> 对应坐标(1,0) 1000 ----> 对应坐标(2,0) 0101 ----> 对应坐标(1,1) 1001 ----> 对应坐标(2,1)
通过这个坐标,我们会输出这样一个方块
再举个例子
我们拿Z这个方块的数据0x0156对应的二进制0B0000000101010110来做个例子。
0000 ----> 对应坐标(0,0) 0001 ----> 对应坐标(0,1) 0101 ----> 对应坐标(1,1) 0110 ----> 对应坐标(1,2)
显示方块没有问题了
上面的代码中,如果mode等于0的话,也就是把某个方块从显示中擦除掉。
我们用devc++写的程序,需要知道几个细节。
#构建固定行列的窗口正常情况,我们显示cmd是一个默认值的黑框「如下图」。
实际上,我们可以用代码来固定cmd的框框大小。
默认代码输出
示例代码:
#include #include #include #include #include /**********Main主函数***********/ int main() { system("color F1&mode con cols=35 lines=25"); getchar(); return 0; }
程序输出:
跟其他不同的是,这个程序的延迟没有使用usleep,我觉得这也是非常值得称赞的地方,不过空跑cpu,哈哈,是有那么一点调皮。
把延迟放到键值获取的函数中。
/**********按键获取**************/ int Getkey(int N,int T) { int start=clock(); if(KEY_V==115){return 115;} do{ if(kbhit()){ KEY_V=(int)(getch()); if(KEY_V<97){KEY_V+=32;} return KEY_V; } for(i=0;i<=N;i++); }while((clock()-start){0x159D,0x89AB,0x159D,0x89AB},{0x126A,0x4856,0x159A,0x4526},{0x926A,0x456A,0x1592,0x0456},{0x4859,0x4859,0x4859,0x4859},{0x5926,0x0156,0x5926,0x0156},{0x4159,0x4596,0x1596,0x4156},{0x156A,0x4152,0x156A,0x4152}}; int SRS[7][4]={{0x159D,0x89AB,0x26AE,0x4567},{0x0159,0x4856,0x159A,0x4526},{0x8159,0x456A,0x1592,0x0456},{0x4859,0x4859,0x4859,0x4859},{0x4815,0x459A,0x5926,0x0156},{0x4159,0x4596,0x1596,0x4156},{0x0459,0x8596,0x156A,0x4152}}; /**********光标位置函数**********/ void Pos(int x,int y) { COORD pos; HANDLE hOutput; pos.X=2*x; pos.Y=y; hOutput=GetStdHandle(STD_OUTPUT_HANDLE); SetConsoleCursorPosition(hOutput,pos); } void HideCursor() { CONSOLE_CURSOR_INFO cursor_info={1,0}; SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE),&cursor_info); } /**********初始化界面************/ void CreatUI() { int i,j,BOUNDARY; printf("┏━━━━━━━━━━┓\n"); for(j=1;j<=20;j++) { if (j==3){printf("┃ ┃LEVEL:1\n");} else if(j==5){printf("┃ ┃SCORE:0\n");} else if(j==7){printf("┃ ┃NEXT \n");} else {printf("┃ ┃\n");} } printf("┗━━━━━━━━━━┛\n"); printf(" CopyRight@2016~2018 BY HAPPY\n"); for(j=1;j<=21;j++){ for(i=0;i<=11;i++){ BOUNDARY=i*(i-11)*(j-21); if(BOUNDARY==0){ POINT_V[i][j]=1; }else{ POINT_V[i][j]=0; } } } } /**********按键获取**************/ int Getkey(int N,int T) { int start=clock(); if(KEY_V==115){return 115;} do{ if(kbhit()){ KEY_V=(int)(getch()); if(KEY_V<97){KEY_V+=32;} return KEY_V; } for(i=0;i<=N;i++); printf("%d\n",clock()-start); }while((clock()-start)关注打赏


微信扫码登录