/****头文件****/ #include #include #include #include /****宏定义****/ #define FrameX 13 //游戏窗口左上角的X轴坐标为13 #define FrameY 3 //游戏窗口左上角的Y轴坐标为3 #define Frame_height 20 //游戏窗口的高度为20 #define Frame_width 18 //游戏窗口的宽度为18 /****全局变量****/ int i,j,Temp,Temp1,Temp2; //Temp,Temp1,Temp2用于记住和转换方块变量的值 int a[80][80]={0}; //标记游戏屏幕的图案:2,1,0 分别表示该位置为游戏边框、方块、无图案;初始化为无图案 int b[4]; //声明俄罗斯方块的结构体 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); //控制文字颜色函数 void gotoxy(int x,int y); //获取屏幕光标位置 void Game(); //游戏界面 void play(); //开始游戏 void explation(); //操作说明 void rule(); //游戏规则 void Make(struct Tetris *); //制作方块 void Print(struct Tetris *); //打印方块 void Clean(struct Tetris *); //清除痕迹 /** *控制文字颜色函数 */ int color(int c) { SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),c); return 0; } /** *获取屏幕光标位置 */ void gotoxy(int x,int y) { COORD pos; pos.X=x; //横坐标 pos.Y=y; //纵坐标 SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),pos); } /** *首页 */ void main() { /*图案*/ color(11); gotoxy(20,3); printf("俄 罗 斯 方 块"); gotoxy(15,6); printf(" ■"); gotoxy(15,7); printf("■■■"); color(14); gotoxy(26,6); printf("■■"); gotoxy(26,7); printf(" ■■"); color(13); gotoxy(40,5); printf("■"); gotoxy(40,6); printf("■"); gotoxy(40,7); printf("■"); gotoxy(40,8); printf("■"); color(10); gotoxy(50,6); printf("■■"); gotoxy(50,7); printf("■■"); color(12); gotoxy(60,6); printf(" ■"); gotoxy(60,7); printf("■■■"); color(9); gotoxy(75,5); printf("■ ■ ■ ■ ■■■■■") ; gotoxy(75,6); printf("■ ■ ■ ■ ■"); gotoxy(75,7); printf("■■■■■ ■ ■ ■"); gotoxy(75,8); printf("■ ■ ■ ■ ■"); gotoxy(75,9); printf("■ ■ ■■■ ■"); color(3); gotoxy(75,12); printf("湖 南 工 业 大 学"); gotoxy(75,14); printf(" 课 程 设 计 作 业"); color(6); gotoxy(75,16); printf(" 计算机类1806班"); gotoxy(75,17); printf(" 18408000638"); gotoxy(75,18); printf(" 张智宇 "); gotoxy(75,19); printf(" 2018年12月27日"); /*操作框*/ int n; int i,j=1; color(6); for(i=9;i<=20;i++) { for(j=15;j<=65;j++) { gotoxy(j,i); if(i==9||i==20) { printf("="); } else if(j==15||j==64) { printf("||"); } } } /*操作框文字 */ color(12); gotoxy(25,12); printf("1.开始游戏"); gotoxy(45,12); printf("2.按键说明"); gotoxy(25,17); printf("3.游戏规则"); gotoxy(45,17); printf("4.退出"); gotoxy(21,22); color(3); printf("请选择[1 2 3 4]:[ ]\b\b"); scanf("%d",&n); switch(n) { case 1: system("cls"); Game(); play(); break; case 2: explation(); break; case 3: rule(); break; case 4: break; } } /** *按键说明 */ void explation() { int i,j = 1; system("cls"); color(6); gotoxy(30,3); printf("按 键 说 明"); for (i = 6; i <= 18; i++) { for (j = 12; j <= 70; j++) { gotoxy(j, i); if (i == 6 || i == 18) printf("="); else if (j == 12 || j == 69) printf("||"); } } color(12); gotoxy(16,9); printf("1/通过 ← →方向键来移动方块"); gotoxy(16,11); printf("2/通过 ↑使方块旋转"); gotoxy(16,13); printf("3/通过 ↓加速方块下落"); gotoxy(16,15); printf("4/通过空格键暂停游戏"); getch(); //按任意键返回主界面 system("cls"); main(); } /** *游戏规则 */ void rule() { int i,j = 1; system("cls"); color(6); gotoxy(30,3); printf("游 戏 规 则"); for (i = 6; i <= 18; i++) { for (j = 12; j <= 70; j++) { gotoxy(j, i); if (i == 6 || i == 18) printf("="); else if (j == 12 || j == 69) printf("||"); } } color(12); gotoxy(16,7); printf("1/不同形状的小方块从屏幕上方落下,玩家通过调整"); gotoxy(16,9); printf(" 方块的位置和方向,使他们在屏幕底部拼出完整的"); gotoxy(16,11); printf(" 一行或几行"); color(14); gotoxy(16,13); printf("2/每消除一行,积分增加100"); color(11); gotoxy(16,15); printf("3/每累计1000分,会提升一个等级"); color(10); gotoxy(16,17); printf("4/提升等级会使方块下落速度加快,游戏难度加大"); getch(); //按任意键返回主界面 system("cls"); main(); } void Game() { 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+3,FrameY+6); 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(6); 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("■"); for(i=2;i<2*Frame_width-2;i+=2) { gotoxy(FrameX+i,FrameY); printf("■"); //打印上横框 } for(i=2;i<2*Frame_width-2;i+=2) { gotoxy(FrameX+i,FrameY+Frame_height); printf("■"); //打印下横框 a[FrameX+i][FrameY+Frame_height]=2; //标记下横框为游戏边框,防止方块出界 } for(i=1;ix][tetris->y]=b[0]; //中心方块位置的图形状态 switch(tetris->flag) //共7大类,19种类型 { 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(12); 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: //1 { color(13); a[tetris->x][tetris->y-1]=b[1]; a[tetris->x][tetris->y+1]=b[2]; a[tetris->x][tetris->y+2]=b[3]; break; } case 4: //T { color(9); 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(10); a[tetris->x-2][tetris->y]=b[1]; a[tetris->x][tetris->y-1]=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(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 8: // Z { color(10); a[tetris->x-2][tetris->y]=b[1]; a[tetris->x][tetris->y+1]=b[2]; a[tetris->x+2][tetris->y+1]=b[3]; break; } case 9: //顺90 Z { color(5); a[tetris->x+2][tetris->y]=b[1]; a[tetris->x+2][tetris->y-1]=b[2]; a[tetris->x][tetris->y+1]=b[3]; break; } case 10: // 反Z { color(9); a[tetris->x+2][tetris->y]=b[1]; a[tetris->x][tetris->y+1]=b[2]; a[tetris->x-2][tetris->y+1]=b[3]; break; } case 11: //顺90 反Z { color(13); a[tetris->x+2][tetris->y]=b[1]; a[tetris->x+2][tetris->y+1]=b[2]; a[tetris->x][tetris->y-1]=b[3]; break; } case 12: // 7 { color(1); a[tetris->x-2][tetris->y]=b[1]; a[tetris->x][tetris->y+1]=b[2]; a[tetris->x][tetris->y+2]=b[3]; break; } case 13: // 顺90 7 { color(2); a[tetris->x-2][tetris->y]=b[1]; a[tetris->x-4][tetris->y]=b[2]; a[tetris->x][tetris->y-1]=b[3]; break; } case 14: // 顺180 7 { color(3); a[tetris->x][tetris->y-2]=b[1]; a[tetris->x][tetris->y-1]=b[2]; a[tetris->x+2][tetris->y]=b[3]; break; } case 15: // 顺270 7 { color(4); a[tetris->x+2][tetris->y]=b[1]; a[tetris->x+4][tetris->y]=b[2]; a[tetris->x][tetris->y+1]=b[3]; break; } case 16: // 反 7 { color(9); a[tetris->x+2][tetris->y]=b[1]; a[tetris->x][tetris->y+1]=b[2]; a[tetris->x][tetris->y+2]=b[3]; break; } case 17: // 顺90 反7 { color(10); a[tetris->x-2][tetris->y]=b[1]; a[tetris->x-4][tetris->y]=b[2]; a[tetris->x][tetris->y+1]=b[3]; break; } case 18: // 顺180 反7 { color(11); a[tetris->x][tetris->y-2]=b[1]; a[tetris->x][tetris->y-1]=b[2]; a[tetris->x-2][tetris->y]=b[3]; break; } case 19: // 顺270 反7 { color(12); a[tetris->x+2][tetris->y]=b[1]; a[tetris->x+4][tetris->y]=b[2]; a[tetris->x][tetris->y-1]=b[3]; break; } } } /** *打印方块 */ void Print(struct Tetris *tetris) { for(i=0;i<4;i++) //让数组b[4]中的每个数都为1 { b[i]=1; } Make(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]==1&&j>FrameY) //如果这个位置上有方块 { gotoxy(i,j); printf("■"); //打印边框内的方块 } } } gotoxy(FrameX+2*Frame_width+3,FrameY+1); color(4); printf("等级: "); color(12); printf("%d",tetris->level); gotoxy(FrameX+2*Frame_width+3,FrameY+3); color(4); printf("得分:"); color(12); printf("%d",tetris->score); gotoxy(FrameX+2*Frame_width+3,FrameY+5); color(4); printf("速度:"); color(12); printf("%d ms",tetris->speed); } /** * 开始游戏 */ void play() { 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; Print(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↓接收 { ch=getch(); if(ch==75) //按 ←键则向左动,中心横坐标减2 { tetris->x-=2; } if(ch==77) //按 →键则向右动,中心横坐标加2 { tetris->x+=2; } if(ch==80) //按 ↓键则加速下落 { if(ifMove(tetris)!=0) { tetris->y+=2; } if(ifMove(tetris)==0) { tetris->y=FrameY+Frame_height-2; } } if(ch==72) //按 ↑键则变体,即当前方块顺时针转90度 { if( tetris->flag>=2 && tetris->flag<=3 ) //如果是直线方块 { tetris->flag++; tetris->flag%=2; tetris->flag+=2; } if( tetris->flag>=4 && tetris->flag<=7 ) //如果是T字方块 { tetris->flag++; tetris->flag%=4; tetris->flag+=4; } if( tetris->flag>=8 && tetris->flag<=11 ) //如果是Z字方块 { tetris->flag++; tetris->flag%=4; tetris->flag+=8; } if( tetris->flag>=12 && tetris->flag<=15 ) //如果是7字方块 { tetris->flag++; tetris->flag%=4; tetris->flag+=12; } if( tetris->flag>=16 && tetris->flag<=19 ) //如果是反7字方块 { tetris->flag++; tetris->flag%=4; tetris->flag+=16; } } if(ch == 32) //按空格键,暂停 { Print(tetris); while(1) { if(kbhit()) //再按空格键,继续游戏 { ch=getch(); if(ch == 32) { goto label; } } } } if(ch == 27) { system("cls"); memset(a,0,6400*sizeof(int)); //初始化a数组 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(6); printf(" @=================================|||||======================================@ \n"); printf("|| ■■ ■ ■ ■ ■■■■■ || \n"); printf("|| ■ ■ ■ ■ ■■ ■■ ■ || \n"); printf("|| ■ ■ ■ ■ ■ ■ ■ ■ || \n"); printf("|| ■ ■■■ ■ ■ ■ ■■ ■ ■■■■■ || \n"); printf("|| ■ ■ ■■■■■ ■ ■ ■ ■ || \n"); printf("|| ■ ■ ■ ■ ■ ■ ■ || \n"); printf("|| ■■ ■ ■ ■ ■ ■■■■■ || \n"); printf("|* *| \n"); color(4); printf("|* *| \n"); printf("|| ■■ ■ ■ ■■■■■ ■■■■ || \n"); printf("|| ■ ■ ■ ■ ■ ■ ■ || \n"); printf("|| ■ ■ ■ ■ ■ ■ ■ || \n"); printf("|| ■ ■ ■ ■ ■■■■■ ■■■■ || \n"); printf("|| ■ ■ ■ ■ ■ ■ ■ || \n"); printf("|| ■ ■ ■ ■ ■ ■ ■ || \n"); printf("|| ■■ ■ ■■■■■ ■ ■ || \n"); printf(" @============================================================================@ \n"); if(MessageBox(NULL,"游戏结束.\n要重新来一局么?","Game Over",MB_YESNO|MB_ICONQUESTION)==IDYES) { system("cls"); memset(a,0,6400*sizeof(int)); Game(); play(); } else exit(0); } } tetris->flag = tetris->next; tetris->x=FrameX+2*Frame_width+6; tetris->y=FrameY+10; Clean(tetris); } } /** * 清除痕迹 */ void Clean(struct Tetris *tetris) { for(i=0;i<4;i++) //数组b[4]中有4个元素,循环这4个元素,让每个元素的值都为0 { b[i]=0; //数组b[4]的每个元素的值都为0 } Make(tetris); for( i = tetris->x - 2;i <= tetris->x + 4; i+=2 ) // X为中心方块 { for(j = tetris->y-2;j <= tetris->y + 1;j++) { if( a[i][j] == 0 && j > FrameY ) //如果这个位置上没有图案,并且处于游戏界面当中 { gotoxy(i,j); printf(" "); //清除方块 } } } }