/********头文件*********/ #include #include #include #include /********宏定义********/ #define FrameX 13 #define FrameY 3 #define Frame_height 20 //定义游戏窗口高度 #define Frame_width 18//定义游戏窗口宽度 /********全局变量*********/ int i,j,Temp,Temp1,Temp2; int a[80][80]={0};//a数组中2,1,0分别代表边框,方块和无图案 int b[4];//每种方块都由四个█组成,b数组用来标记四个█的位置以构造图形 struct Tetris { int x; //中心方块的x轴坐标 int y; //中心方块的y轴坐标 int flag;//标记方块类型的序号 int next;//下一个方块类型的序号 int speed;//俄罗斯方块产生的速度 int number;//产生俄罗斯方块的个数 int score;//游戏分数 int level;//游戏等级 }; HANDLE hOut;//控制台句柄 /******函数声明*******/ int color(int c); static void gotoxy(int x, int y);//移动光标位置 void DrawGameframe(); //绘制游戏边框 void Flag(struct Tetris * );//随机产生俄罗斯方块序号 void MakeTetris(struct Tetris *);//制作俄罗斯方块 void PrintTetris(struct Tetris *);//打印俄罗斯方块 void CleanTetris(struct Tetris *);//清除俄罗斯方块的痕迹 int ifMove(struct Tetris *);//判断能否移动 void Del_Fullline(struct Tetris *);//判断是否满行 void GamePlay();//开始游戏 void regulation();//游戏规则 void explation();//按键说明 void welcome();//欢迎界面 void Replay(struct Tetris *);//重新开始游戏 void title();//欢迎界面上方标题 void close();//关闭游戏 /*****文字颜色函数******/ int color(int c){ SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),c);//更改文字颜色 return 0; } /*****获取屏幕光标位置*******/ static void gotoxy(int x, int y){ COORD point = { x, y };//光标要设置的位置x,y HANDLE HOutput = GetStdHandle(STD_OUTPUT_HANDLE);//使用GetStdHandle(STD_OUTPUT_HANDLE)来获取标准输出的句柄 SetConsoleCursorPosition(HOutput, point);//设置光标位置 } /*****欢迎界面标题********/ void title(){ color(15); gotoxy(30,3); printf("趣味俄罗斯方块\n"); //标题 color(11); gotoxy(18,5); printf("█"); gotoxy(18,6); printf("██"); gotoxy(18,7); printf("█"); //T字方块 color(14); gotoxy(26,6); printf("██"); gotoxy(28,7); printf("██"); //Z字方块 color(10); gotoxy(36,6); printf("██"); gotoxy(36,7); printf("██"); //田字方块 color(13); gotoxy(45,5); printf("█"); gotoxy(45,6); printf("█"); gotoxy(45,7); printf("█"); gotoxy(45,8); printf("█"); //直线方块 color(12); gotoxy(56,6); printf("█"); gotoxy(52,7); printf("███\n"); //7字方块 } /*******菜单选项边框*******/ void welcome() { int n; int i,j=1; color(14); for(i=9;i<=20;i++){ for(j=15;j<=60;j++){ gotoxy(j,i); if(i==9||i==20) printf("="); else if(j==15||j==59) printf("::"); } } /*******菜单选项的文字********/ color(12); gotoxy(25,12); printf("1.开始游戏"); gotoxy(40,12); printf("2.按键说明"); gotoxy(25,17); printf("3.游戏规则"); gotoxy(40,17); printf("4.退出"); gotoxy(21,22); printf("请选择[1,2,3,4]:[ ]\b\b"); scanf("%d",&n); switch(n){ case 1: system("cls"); DrawGameframe(); break; case 2: break; case 3: break; case 4: break; } } /*******游戏窗口*******/ void DrawGameframe() { /***********游戏名称***********/ gotoxy(FrameX+Frame_width-7,FrameY-2); color(11); printf("趣味俄罗斯方块"); /**********下一个出现方块********/ gotoxy(FrameX+2*Frame_width+3,FrameY+7); color(2); printf("**********"); gotoxy(FrameX+2*Frame_width+13,FrameY+7); color(3); printf("下一个出现方块"); gotoxy(FrameX+2*Frame_width+3,FrameY+13); color(2); printf("**********"); /**********按键说明***********/ gotoxy(FrameX+2*Frame_width+3,FrameY+17); color(14); printf("↑键:旋转"); gotoxy(FrameX+2*Frame_width+3,FrameY+19); printf("空格:暂停游戏"); gotoxy(FrameX+2*Frame_width+3,FrameY+15); printf("Esc:退出游戏"); /*********游戏边框***********/ gotoxy(FrameX,FrameY); color(12); printf("╔"); gotoxy(FrameX+2*Frame_width-2,FrameY); printf("╗"); gotoxy(FrameX,FrameY+Frame_height); printf("╚"); gotoxy(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(FrameX+i,FrameY); printf("═"); } for(i=2;ix][tetris->y]=b[0];//中心方块的图形状态 switch(tetris->flag){ case 1: //田字方块 color(10); 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: //横直线方块 color(13); 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: //竖直线方块 color(13); 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字方块 color(11); 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: //顺时针90°T字方块 color(11); a[tetris->x][tetris->y-1]=b[1]; a[tetris->x-2][tetris->y]=b[2]; a[tetris->x][tetris->y+1]=b[3]; break; case 6: //顺时针180°T字方块 color(11); a[tetris->x][tetris->y-1]=b[1]; a[tetris->x-2][tetris->y]=b[2]; a[tetris->x+2][tetris->y]=b[3]; break; case 7: //顺时针270°T字方块 color(11); 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字方块 color(14); a[tetris->x+2][tetris->y+1]=b[1]; a[tetris->x][tetris->y+1]=b[2]; a[tetris->x-2][tetris->y]=b[3]; break; case 9: //顺时针Z字方块 color(14); 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字方块 color(14); 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字方块 color(14); 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字方块 color(12); 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 13: //顺时针90°7字方块 color(12); 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: //顺时针180°7字方块 color(12); 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: //顺时针270°7字方块 color(12); 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 16: //反7字方块 color(12); 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: //顺时针90°反7字方块 color(12); 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: //顺时针180°反7字方块 color(12); 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 19: //顺时针270°反7字方块 color(12); 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; } } /******打印俄罗斯方块*******/ void PrintTetris(struct Tetris *tetris){ for(i=0;i<4;i++) b[i]=1; MakeTetris(tetris); for(i=tetris->x-2;i<=tetris->x+4;i+=2){ for(j=tetris->y-1;j<=tetris->y+1;j++){ if(a[i][j]==1&&j>FrameY){ gotoxy(i,j); printf("█"); } } } //打印菜单信息 gotoxy(FrameX+2*Frame_width+3,FrameY+1); color(4); printf("level:"); color(12); printf("%d",tetris->level); gotoxy(FrameX+2*Frame_width+3,FrameY+3); color(4); printf("score:"); color(12); printf("%d",tetris->score); gotoxy(FrameX+2*Frame_width+3,FrameY+3); color(4); printf("speed"); color(12); printf("%dms",tetris->speed); } /******判断方块能否移动******/ int ifMove(struct Tetris *tetris) { if(a[tetris->x][tetris->y]!=0){ return 0; } else{ if( (tetris->flag==1&&(a[tetris->x][tetris->y-1]==0&& a[tetris->x][tetris->y-1]==0&&a[tetris->x+2][tetris->y]==0))|| (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&& 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 CleanTetris(struct Tetris *tetris){ for(i=0;i<4;i++){ b[i]=0; } MakeTetris(tetris); for(i=tetris->x-2;i<=tetris->x+4;i+=2){ for(tetris->y-2;i<=tetris->y+1;j++){ if(a[i][j]==0&&j>FrameY){ gotoxy(i,j); printf(" "); } } } } /*******判断是否满行********/ void Del_Fullline(struct Tetris *tetris){ int k,del_rows=0; for(j=FrameY+Frame_height-1;j>=FrameY+1;j--){ k=0; for(i=FrameX+2;iFrameY;k--){ for(i=FrameX+2;iscore+=100*del_rows; if(del_rows>0&&(tetris->score%1000==0||tetris->score/1000>tetris->level-1)){ tetris->speed-+20; tetris->level++; } } /******随机产生俄罗斯方块类型的序号*******/ void Flag(struct Tetris *tetris){ tetris->number++; srand(time(NULL)); if(tetris->number==1){ tetris->flag=rand()%19+1; } tetris->next=rand()%19+1; } /*******开始游戏*******/ void Gameplay(){ int n; struct Tetris t,*tetris=&t; char ch; tetris->number=0; tetris->speed=300; tetris->score=0; tetris->level=1; while(1){ Flag(tetris); Temp=tetris->flag; tetris->x=FrameX+2*Frame_width+6; tetris->y=FrameY+10; tetris->flag=tetris->next; PrintTetris(tetris); tetris->x=FrameX+Frame_width; tetris->y=FrameY-1; tetris->flag=Temp; /******获取键盘按键*******/ while(1){ label:PrintTetris(tetris); Sleep(tetris->speed);//控制时间 CleanTetris(tetris); Temp1=tetris->x; Temp2+tetris->flag; if(kbhit()){ ch=getch(); if(ch==75){ tetris->x-=2; //←键左移 } if(ch==77) tetris->x+=2;//→键右移 if(ch==80){ //↓键加速下落 if(ifMove(tetris)!=0) tetris->y+=2; else tetris->y=FrameY+Frame_height-2; } if(ch==72){ 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; }//T字方块 if(tetris->flag>=8&&tetris->flag<=11){ tetris->flag++; tetris->flag%=4; tetris->flag+=8; }//Z字方块 if(tetris->flag>=12&&tetris->flag<=15){ tetris->flag++; tetris->flag%=4; tetris->flag+=12; }// 7字方块 if(tetris->flag>=16&&tetris->flag<=19){ tetris->flag++; tetris->flag%=4; tetris->flag+=16; }//反7字方块 } if(ch==32) //空格暂停 { PrintTetris(tetris); while(1){ if(kbhit()){ ch=getch(); if(ch==32) goto label; } } } if(ch==27){ //ESC退出游戏 system("cls"); memset(a,0,6400*sizeof(int));//初始化数组 welcome(); } if(ifMove(tetris)==0){ tetris->x=Temp1; tetris->flag=Temp2; } else{ goto label; } } tetris->y++; if(ifMove(tetris)==0){ tetris->y--; PrintTetris(tetris); Del_Fullline(tetris); break; } } //游戏结束 for(i=tetris->y-2;iy+2;i++){ if(i==FrameY){ system("cls"); gotoxy(29,7); printf(" \n"); color(12); printf("\t\t\t████ █ █ ██ \n"); printf("\t\t\t█ ██ █ █ █ \n"); printf("\t\t\t███ █ █ █ █ █ \n"); printf("\t\t\t█ █ ██ █ █ \n"); printf("\t\t\t████ █ █ ██ \n"); gotoxy(17,18); color(14); printf("我要重新玩一局---------1"); gotoxy(44,18); printf("不玩了,退出-----------2\n"); int n; gotoxy(32,20); printf("选择【1/2】"); color(11); scanf("%d",&n); switch(n){ case 1: system("cls"); Replay(tetris); break; case 2: exit(0); break; } } } tetris->flag=tetris->next; tetris->x=FrameX+2*Frame_width+6; tetris->y=FrameY+10; CleanTetris(tetris); } } /*******主函数*******/ int main(){ title(); welcome(); return 0; }