C语言版 彩色俄罗斯方块 控制台输出
2015-10-28 14:52
302 查看
本代码由vc++6.0编译通过,属于本人三个晚上的作品,没什么优化 仅供学习娱乐专用。不用添加任何库文件。直接下载编译即可运行。下载地址在本文末尾处!
效果图:
源码:
完整代码下载地址:点击下载。
效果图:
源码:
///////////////////////////////////////////////////////////////////////////////////////////////// // 名称: 俄罗斯方块 彩色版1.1.0// // 语言: C语言 // //上一版本: 俄罗斯方块 彩色版1.0.0// //增加功能: 增加关卡 和 最高分// // 环境: Microsoft Visual C++ 6.0 // // 作者: 鼠标猎人// // 日期: 2015年1月19号// ///////////////////////////////////////////////////////////////////////////////////////////////// #include<stdio.h> #include <windows.h> #include<conio.h> #include<time.h> #define _WIN32_WINNT 0x0500 void gotoxy(int x,int y);//控制光标。X表示横坐标,Y表示纵坐标 void console();//设置控制台窗口大小,为了让程序运行得更好看 void my_print();//设置界面 void my_randout();//随机出现方块,并打印在提示区 void my_printblock();//打印 4*4 的方格来显示方块 void my_up();//旋转 void my_down();//下移 void my_lift();//左移 void my_right();//右移 void my_exit();//退出前保存最高分 void clear();//消除整行 void gameover();//游戏结束 void my_stop();//游戏暂停 int tem[4][4];//用4*4的方格来控制方块的操作和显示 这个作为传值媒介 int block[4][4];//提示区的方块 int BLOCK[4][4];//正在下落的方块 int scope[25][34] = {0};//操作的范围 这里要注意,一个方格是占两个横坐标单位的 int point_x , point_y;//方格的左上角坐标 int fen = 0;//得分 int pass = 1;//关卡 新增 int hang = 0;//消除的总行数 int max_fen = 0;//最高分 新增 FILE *fp; bool check = true;//检查方块还能不能下落 int block0[4][4] = {{0,1,1,0},{0,0,1,0},{0,0,1,0},{0,0,0,0}};// 7 个方块 用数组表示 正“7” int block1[4][4] = {{0,1,1,0},{0,1,0,0},{0,1,0,0},{0,0,0,0}};// 反“7” int block2[4][4] = {{0,0,0,0},{0,0,1,1},{0,1,1,0},{0,0,0,0}};// 反“z” int block3[4][4] = {{0,0,0,0},{1,1,0,0},{0,1,1,0},{0,0,0,0}};// 正“z” int block4[4][4] = {{0,0,0,0},{0,1,0,0},{1,1,1,0},{0,0,0,0}};// 倒“T” int block5[4][4] = {{0,0,0,0},{0,1,1,0},{0,1,1,0},{0,0,0,0}};// 正方形 int block6[4][4] = {{0,0,0,0},{0,0,0,0},{1,1,1,1},{0,0,0,0}};// 直条 void main() { if ((fp = fopen("test.txt","r") )== NULL) { fp = fopen("test.txt","w+");//打开文件 如果没有就创建 } srand((unsigned)time(NULL));//设置随机数种子 char key; int i , j; fscanf(fp, "%d", &i); max_fen = max_fen>i?max_fen:i;//将最高分赋给max_fen fclose(fp);//关闭文件 int time;//控制下落时间 console(); my_print(); my_randout(); while( true )//死循环 { if( check )//如果没有正在下落的方块就执行if里面的 { check = false; point_x = 14;//方块最初出现的地方 point_y = 0; for( i=0 ; i < 4 ; i++) { for( j = 0 ; j < 4 ; j++) { BLOCK[i][j] = block[i][j];//将提示区的方块数组传到下落的方块数组 } } my_printblock();//在point_x,point_y显示方块。 my_randout();//提示区随机换一个方块 } if (kbhit()) //检测,如果有按键就执行if里面的 { key = getch();//捕获按键 switch( key ) { case 72:my_up();//上 break; case 75:my_lift();//左 break; case 77:my_right();//右 break; case 80:my_down();//下 break; case 32:my_stop();//空格 暂停或开始 break; case 27:my_exit();//Esc 退出 default: ; } } Sleep(30);//等待0.03秒 0.03秒才能执行一个按键 也降低CPU if( 0 == ++time % (32 - pass*3))//控制下落的时间=30*30毫秒 { my_down();//时间到自动下落一格 } if( true == check)//当不能下落时 { for( i=0 ; i < 4 ; i++) { for( j = 0 ; j < 4 ; j++) { if( 1 == BLOCK[i][j]) scope[point_x / 2 + j][point_y + i] = BLOCK[i][j];//把下落的方块赋值给操作区的数组 //这里的point_x除以2是因为一个小格子占两个横坐标 } } my_printblock(); clear();//如果有某一行满了就消除 } } } //设置窗口位置和大小,为了让程序运行得更好看 void console() { HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);// 获取标准输出设备句柄 CONSOLE_SCREEN_BUFFER_INFO bInfo; // 窗口缓冲区信息 GetConsoleScreenBufferInfo(hOut, &bInfo );// 获取窗口缓冲区信息 SetConsoleTitle("俄罗斯方块 C版"); // 设置窗口的标题 COORD size = {80, 32};//不能小于默认大小(80,25) SetConsoleScreenBufferSize(hOut,size); // 重新设置缓冲区大小*/ SMALL_RECT rc = {0,0, 63, 31}; //不能大于缓冲区大小 SetConsoleWindowInfo(hOut,true ,&rc);// 重置窗口大小 CONSOLE_CURSOR_INFO cursor_info = {1, 0}; //第一个参数光标百分比大小。第二个参数是否可见。 SetConsoleCursorInfo(hOut, &cursor_info);//设置控制台光标 } void my_print() { SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_BLUE|FOREGROUND_INTENSITY);//黑底亮蓝字。 for(int i = 1 ; i < 30 ; i++) printf("■\t\t\t\t■ | |\n"); printf("■■■■■■■■■■■■■■■■■ |---------------------------|\n");//框架 gotoxy(36,0); printf("---------------------------"); SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_GREEN | FOREGROUND_RED |FOREGROUND_INTENSITY);//黑底亮黄字。 gotoxy(40,2); printf("关 卡: %d",pass); gotoxy(40,3); printf("分 数: %d",fen); gotoxy(40,4); printf("最高分: %d",max_fen); gotoxy(36,6); printf("下一个方块:"); gotoxy(36,14); printf("操作方法:"); gotoxy(40,16); printf("↑:旋转 ↓:沉淀"); gotoxy(40,18); printf("→:右移 ←:左移"); gotoxy(39,20); printf("空格键:开始 / 暂停"); gotoxy(39,22); printf(" Esc:退出"); gotoxy(36,25); printf("关 于:"); gotoxy(40,26); printf("俄罗斯方块 1.2.0"); gotoxy(49,27); printf("作者:鼠标猎人"); gotoxy(50,28); printf("2015年1月19日"); } //设置光标输出的位置函数。坐标不能为负数 void gotoxy(int x,int y)//X表示横坐标,Y表示纵坐标。 { HANDLE app; COORD pos; pos.X=x; pos.Y=y; app=GetStdHandle(STD_OUTPUT_HANDLE); SetConsoleCursorPosition(app,pos); } //旋转 将4*4方格顺时针旋转 void my_up() { int i,j; for( i=0 ; i < 4 ; i++) { for( j = 0 ; j < 4 ; j++) { tem[i][j] = BLOCK[i][j]; if( 1 == BLOCK[i][j]) { gotoxy(point_x + j*2 , point_y + i); printf(" "); } } } for( i=0 ; i < 4 ; i++) { for( j = 0 ; j < 4 ; j++) { BLOCK[j][3-i] = tem[i][j]; } } //以上为旋转。 //下面为防止旋转后超出框架范围 for( j = 0 ; j < 2 ; j++) { for( i = 0 ; i < 4 ; i++) { if (1 == BLOCK[i][j] ) { if(point_x+2*j < 2) { point_x+=2; j--; break; } else if(1 == scope[point_x / 2 + j][point_y + i] || 1 == scope[point_x / 2 + 3 - j][point_y + i]) { for( i=0 ; i < 4 ; i++)//顺270度 { for( j = 0 ; j < 4 ; j++) { BLOCK[i][j] = tem[i][j]; } } break; } } if (1 == BLOCK[i][3-j]) { if(point_x + 2 * (3-j)> 30) { point_x-=2; j--; break; } } } } my_printblock();//旋转之后立即显示出来 } //左移 void my_lift() { int i , j ; for( i = 0 ; i < 3 ; i++ ) for( j = 0 ; j < 4 ; j++ ) { if(1 == BLOCK[j][i] && (point_x+2*i-1 4000 < 2 || 1 == scope[point_x / 2 + i - 1][point_y + j])) { return ;//如果到边缘 或者是左边已经有了方块 } } for( i = 0 ; i < 4 ; i++ ) for( j = 0 ; j < 4 ; j++ ) if( 1 == BLOCK[i][j]) { gotoxy(point_x + j*2 , point_y + i); printf(" ");//把之前的擦掉 } point_x -= 2; my_printblock(); } void my_right() { int i , j ; for( i = 3 ; i > 0 ; i-- ) for( j = 0 ; j < 4 ; j++ ) { if(1 == BLOCK[j][i] && ( point_x+2*i+2 > 30 || 1 == scope[point_x / 2 + i + 1][point_y + j])) { return ;//如果到边缘 或者是右边已经有了方块 } } for( i = 0 ; i < 4 ; i++ ) for( j = 0 ; j < 4 ; j++ ) if( 1 == BLOCK[i][j]) { gotoxy(point_x + j*2 , point_y + i); printf(" ");//把之前的擦掉 } point_x += 2; my_printblock(); } void my_down( ) { int i , j ; if( true == check) { return ;//不能下落直接不执行 } gotoxy(point_x,point_y); for( i = 3 ; i >= 0 ; i-- )//检测该方格还能不能下落 for( j = 0 ; j < 4 ; j++ ) if ( 1 == BLOCK[i][j] ) { if (1 == scope[point_x / 2 + j][point_y + i + 1] || point_y + i + 1 > 28 ) //到最下边或是下面已经有方格 { check = true; return ; } } for( i = 0 ; i < 4 ; i++ ) for( j = 0 ; j < 4 ; j++ ) if( 1 == BLOCK[i][j]) { gotoxy(point_x + j*2 , point_y + i); printf(" ");//能下落,擦除以前的方格 } point_y++; my_printblock();//在下一格显示 } //暂停 void my_stop() { SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_RED|FOREGROUND_INTENSITY); gotoxy(10,10);printf(" "); gotoxy(10,11);printf(" ■■■■■ "); gotoxy(10,12);printf(" ■ ■ "); gotoxy(10,13);printf(" ■ ■ "); gotoxy(10,14);printf(" ■■■■■ "); gotoxy(10,15);printf(" ■ "); gotoxy(10,16);printf(" ■ "); gotoxy(10,17);printf(" ■ "); gotoxy(10,18);printf(" "); while (true) { int n = getch(); if(32 == n) { gotoxy(10,10);printf(" "); gotoxy(10,11);printf(" ■■■■■ "); gotoxy(10,12);printf(" ■ "); gotoxy(10,13);printf(" ■ "); gotoxy(10,14);printf(" ■■■■■ "); gotoxy(10,15);printf(" ■ "); gotoxy(10,16);printf(" ■ "); gotoxy(10,17);printf(" ■■■■■ "); gotoxy(10,18);printf(" "); Sleep(1000); gotoxy(10,10);printf(" "); gotoxy(10,11);printf(" ■■■■■ "); gotoxy(10,12);printf(" ■ "); gotoxy(10,13);printf(" ■ "); gotoxy(10,14);printf(" ■■■■■ "); gotoxy(10,15);printf(" ■ "); gotoxy(10,16);printf(" ■ "); gotoxy(10,17);printf(" ■■■■■ "); gotoxy(10,18);printf(" "); Sleep(1000); gotoxy(10,10);printf(" "); gotoxy(10,11);printf(" ■■ "); gotoxy(10,12);printf(" ■■■ "); gotoxy(10,13);printf(" ■■ "); gotoxy(10,14);printf(" ■■ "); gotoxy(10,15);printf(" ■■ "); gotoxy(10,16);printf(" ■■ "); gotoxy(10,17);printf(" ■■■■ "); gotoxy(10,18);printf(" "); Sleep(1000); SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_GREEN|FOREGROUND_INTENSITY); for(int i = 0 ; i < 9 ; i++)//将暂停掩盖的方块再次显示出来 { gotoxy(10 , 10 + i ); for(int j = 0 ; j < 7 ; j++ ) { if (1 == scope[5 + j][10 + i]) { printf("■"); } else { printf(" "); } } } return ; } else if (27 == n) { my_exit(); } } } //消除 void clear() { int i , j , k , m = 0; for(i = point_y + 3 ; i >= point_y ; i-- ) { for( j = 1 ; j < 16 ; j++ ) { if( 0 == scope[j][i] ) { break ; } } if ( 16 == j ) { SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_GREEN|FOREGROUND_INTENSITY); m++; for(k=i;k>3;k--) { for( j = 1 ; j < 16 ; j++ ) { scope[j][k] = scope[j][k - 1]; gotoxy(j*2 , k ); if (1 == scope[j][k]) { printf("■"); } else { printf(" "); } } } for( j = 1 ; j < 16 ; j++ ) { scope[j][4] = 0; } i++; } } switch(m) {//判断一次消除了几行,来设置得分数 case 1: fen+=100; break; case 2: fen+=230; break; case 3: fen+=438; break; case 4: fen+=854; break; default: ; } hang += m ; if( hang > 10 )//每10行升一关 { hang = 0 ; pass++; } max_fen = max_fen>fen?max_fen:fen;//更新最高分 SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_GREEN | FOREGROUND_RED |FOREGROUND_INTENSITY);//黑底亮黄色字。 gotoxy(40,2); printf("关 卡: %d",pass); gotoxy(40,3); printf("分 数: %d",fen); gotoxy(40,4); printf("最高分: %d",max_fen); for( j = 7 ; j < 11 ; j++ ) { if(1 == scope[j][4]) gameover(); } } //随机出现方块 void my_randout() { int i,j; switch( rand()%7 ) { case 0:for(i=0 ; i < 4 ; i++) for(j = 0 ; j < 4 ; j++) block[i][j] = block0[i][j]; break; case 1: for(i=0 ; i < 4 ; i++) for(j = 0 ; j < 4 ; j++) block[i][j] = block1[i][j]; break; case 2: for(i=0 ; i < 4 ; i++) for(j = 0 ; j < 4 ; j++) block[i][j] = block2[i][j]; break; case 3: for(i=0 ; i < 4 ; i++) for(j = 0 ; j < 4 ; j++) block[i][j] = block3[i][j]; break; case 4: for(i=0 ; i < 4 ; i++) for( j = 0 ; j < 4 ; j++) block[i][j] = block4[i][j]; break; case 5: for( i=0 ; i < 4 ; i++) for( j = 0 ; j < 4 ; j++) block[i][j] = block5[i][j]; break; case 6: for( i=0 ; i < 4 ; i++) for( j = 0 ; j < 4 ; j++) block[i][j] = block6[i][j]; break; default: ; } for( i=0 ; i < 4 ; i++) { for( j = 0 ; j < 4 ; j++) { tem[i][j] = block[i][j]; } } switch( rand()%4 )//再设置随机旋转的方向 { case 0 : break; case 1 : for( i=0 ; i < 4 ; i++)//顺时针90度 { for( j = 0 ; j < 4 ; j++) { block[j][3-i] = tem[i][j]; } } break; case 2 : for( i=0 ; i < 4 ; i++)//顺180度 { for( j = 0 ; j < 4 ; j++) { block[3-i][3-j] = tem[i][j]; } } break; case 3 : for( i=0 ; i < 4 ; i++)//顺270度 { for( j = 0 ; j < 4 ; j++) { block[3-j][i] = tem[i][j]; } } break; default: ; } //打印提示区的方块 SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_RED|FOREGROUND_INTENSITY);//黑底亮红字。 for( i=0 ; i < 4 ; i++) { gotoxy(44 , 8 + i); for( j = 0 ; j < 4 ; j++) { if(1 == block[i][j]) { printf("■"); } else { printf(" "); } } } SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_RED|FOREGROUND_GREEN|FOREGROUND_BLUE);//黑底白字 } //显示方格 void my_printblock() { int i , j ; for( i=0 ; i < 4 ; i++) { for( j = 0 ; j < 4 ; j++) { if (point_x / 2 + j > 0 ) { if ( 1 == scope[point_x / 2 + j][point_y + i]) { SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_GREEN|FOREGROUND_INTENSITY); gotoxy(point_x + j*2 , point_y + i); printf("■"); } else if (1 == BLOCK[i][j]) { SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_RED|FOREGROUND_GREEN|FOREGROUND_BLUE); gotoxy(point_x + j*2 , point_y + i); printf("■"); } } } } } void gameover() { SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_RED); gotoxy(4,10);printf(" "); gotoxy(4,11);printf(" ■■■ ■ ■ ■■■■ ■■■■ "); gotoxy(4,12);printf(" ■ ■ ■ ■ ■ ■ ■ "); gotoxy(4,13);printf(" ■ ■ ■ ■ ■■■■ ■■■■ "); gotoxy(4,14);printf(" ■ ■ ■ ■ ■ ■■ "); gotoxy(4,15);printf(" ■■■ ■ ■■■■ ■ ■ "); gotoxy(4,16);printf(" "); gotoxy(32,17);printf("空格键:重来\tEsc:退出"); while(true) { int n = getch(); switch( n ) { case 32: system("cls");//清屏 console(); memset(scope, 0, sizeof(int) * 25 * 34);//数组清零 fen = 0; hang = 0; pass = 1; my_print();//输出界面 my_randout(); return; case 27: my_exit(); return; default:; } } } void my_exit()//退出前保存最高分 { fp = fopen("test.txt","w"); fprintf(fp, "%d\n", max_fen); fclose(fp); SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_RED|FOREGROUND_INTENSITY); gotoxy(12,12);printf("================================"); gotoxy(12,13);printf("|| 游戏已退出 按任意键关闭! ||"); gotoxy(12,14);printf("================================"); gotoxy(0,30); exit(0); }
完整代码下载地址:点击下载。
相关文章推荐
- C语言版 彩色俄罗斯方块 控制台输出
- C语言版 彩色俄罗斯方块 控制台输出
- C语言版 彩色俄罗斯方块 控制台输出
- C语言版 彩色俄罗斯方块 控制台输出
- C++学习笔记7 - 函数
- C++11:变长模板的迭代与递归扩展
- strcpy,strcat,strcmp的函数实现
- IOS学习之OC语言数组的排序方法
- typedef
- cppcheck下载及使用
- c语言学习之基础知识点介绍(十):数组
- C++Primer第五版 练习12.2
- C++Primer第五版 12.1.1节练习
- C++注释
- 日志库EasyLogging++学习系列(6)—— 日志记录器
- C++设计模式——工厂方法模式
- C++设计模式——简单工厂模式
- C++设计模式——抽象工厂模式
- C++访问栈和堆对象成员
- C++STL学习(12)STL深入(1) 设计简单的空间配置器