Dec C++中常用的快捷键:

给代码行加注释:<Ctrl+/ >

删除代码行:<Ctrl+D > 只能删除光标所在的代码行

1.俄罗斯方块游戏开发设计细节:

随机产生下滑方块,自动提速,积分,满行消除,方块形状变化,下一方块提示

2、系统功能设计

2.1系统功能结构

2.2业务流程图

3.使用Dev C++创建项目

文件->新建->项目->选择"Basic"选项卡中的第二项-Console Application(控制台应用程序)->C语言

4.预处理模块

预处理指定:#if  #ifdef  #ifndef  #else  #endif(条件编译)  #define(宏定义)  #include(文件引用)  #line(行控制)  #error(错误指定)  #pragma(和实现相关的杂注)

5.游戏欢迎界面

按键盘数字‘1’开始游戏,按”2“查看游戏功能键,按"3"查看本游戏规则,按"4"退出游戏

5.1设计字体颜色

/*** 设计字体颜色 ***/
int color(int c)
{SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),c);//更改字体颜色return 0;
} 

在c语言中,SetConsoleTextAttribute()是设置控制台窗口字体颜色和背景色的函数

函数原型是:

BOOL SetConsoleTextAttribute(HANDLE consolehwnd,WORD wAttributes);
consolehwnd = GetStdHandles(STD_OUTPUT_HANDLE);

GetStdHandle是获得输入,输出或错误的屏幕缓冲区的句柄

参数列表

参数值 含 义
STD_INPUT_HANDLE 标准输入的句柄
STD_OUTPUT_HANDLE 标准输出的句柄
STD_ERROR_HANDLE 标准错误的句柄

wAttributes是设置颜色的参数

5.2设置文字显示位置

/*** 获取屏幕光标位置 ***/
void gotoxy(int x,int y)
{COORD pos;pos.X =x; //横坐标pos.Y =y; //纵坐标SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),pos);
}

SetConsoleCursorPosition()函数用来获取控制台的光标位置

COORD pos是一个结构体变量

5.3标题部分设计


/*** 主界面上方的位置 ***/
void title()
{color(15);//亮白色gotoxy(28,3);printf("俄 罗 斯 方 块\n"); //输出标题color(11); //亮蓝色gotoxy(18,5);      // ■printf("■");      // ■■gotoxy(18,6);      // ■printf("■■");gotoxy(18,7);printf("■");color(14); //黄色gotoxy(26,6);      //■■printf("■■");    //  ■■gotoxy(28,7);printf("■■");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("■■■");
}

5.4 设计菜单选项的边框


/*** 菜单边框 ***/
void welcome()
{int n;int i,j=1;color(14);for(i=9;i<=20;i++) //循环y纵坐标,打印输出上,下边框 {for(j=15;j<=60;j++) //循环x横坐标,打印输出左,右边框 {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);color(3);printf("请选择[1,2,3,4]: \b\b");color(14);scanf("%d",&n); //输入选项switch(n){case 1:system("cls");break;case 2:break;case 3:break;case 4:break; }
}

6.游戏主窗体设计

在界面绘制部分,一部分是左边的方块下落界面,另一部分是右边的得分记录,出现块展示和主要按键说明界面


/*** 制作游戏窗口 ***/
void DrawGameframe()
{gotoxy(FrameX+Frame_width-5,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("╚");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;i<Frame_height;i++){gotoxy(FrameX,FrameY+i);printf("║"); //打印左竖框 a[FrameX][FrameY+i]=2;//标记左竖框为游戏边框,防止边框出界 }for(i=1;i<Frame_height;i++){gotoxy(FrameX+2*Frame_width-2,FrameY+i);printf("║"); //打印右竖框 a[FrameX+2*Frame_width-2][FrameY+i]=2;//标记右竖框为游戏边框,防止方块出界 }
} 

按1 进入游戏界面

俄罗斯方块是要下落到下方边框才可,此时要做一个判断

定义一个数组a[80][80]用来标记游戏屏幕的图案,只有3个值 分别为2,1,0.

2表示数组a所示的位置为游戏边框

1表示数组a所示位置有方块

0表示无图案

只要分别找到游戏的左,右,下边框的数组表示,让其数组值为2,就可以成功设置边界

边界代码:

a[FrameX+i][FrameY+Frame_height]=2; //标记下横框为游戏边框,防止方块出界
a[FrameX][FrameY+i]=2;//标记左竖框为游戏边框,防止边框出界
a[FrameX+2*Frame_width-2][FrameY+i]=2;//标记右竖框为游戏边框,防止方块出界 

7.游戏逻辑设计

1.制造方块不断下落的现象

2.在方块下落的时候,判断方块能不能放置在下方位置;或者能否继续左右移动

3.判断是否满行,满行即删除满行的方块

4.随机产生俄罗斯方块

7.1 判断俄罗斯方块是否可以移动

首先要判断中心方块移动的位置是否为空位置,即a[tetris->x][tetris->y]是否为方块或者墙壁


/**** 判断是否可移动 ****/
int ifMove(struct Tetris *tetris)
{if(a[tetris->x][tetris->y]!=0)//当中心块位置上有图案时,返回值为0,即不可移动 {return 0;}else{if((tetris->flag==1&&(a[tetris->x][tetris->y-1]==0 && a[tetris->x+2][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==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==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==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==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==19 && (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==17 && (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;
}

7.2清除俄罗斯方块下落的痕迹

只要在输出位置之前加上“  ”即可


/*** 清除俄罗斯方块的痕迹 ***/
void CleanTetris(struct Tetris *tetris)
{for(i=0;i<4;i++) //数组b[4]中有4个元素,循环这4个元素,让每个元素的值都为0{b[i]=0;    } MakeTetris(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(" "); //清除方块 }} }
}

7.3判断方块是否满行

因为游戏界面的宽度是Frame_width,所以除去两个竖边框,那么在满行时,方块所占的宽度就是Frame_width-2

7.4随机产生俄罗斯方块类型的序号

需要使用随机函数rand()来获得随机的方块类型序号

已经定义好每种类型的方块都有各自的flag,也就是序号,从1到19

rand()是一个随机数函数,每次执行同一个程序时,调用rand()函数所得的随机数序列是固定的

令rand()函数的返回值更具有随机性,通常需要为随机数生成器提供一粒新的随机种子、C语言提供了srand()函数,可以为随机数生成器播散种子,只要种子不同,rand()函数就会产生不同的随机序列。srand()函数被称为随机数生成器的初始化器。

srand()函数位于time.h头文件中。需引用time.h头文件

使用rand()函数获得随机数的步骤可以总结为:

(1)调用srand(time(NULL))设置随机数种子,初始化随机数。

(2)调用rand()函数获得一个或一系列随机数。


用于获取1~19之间的随机数:

srand(time(NULL));  //设置随机数种子,初始化随机数
tetris->flag=rand()%19+1; //记住第一个方块的序号

8.各种按键的操作

使用kbhit()和getch()函数来接收键盘按键

所在头文件conio.h

在c语言中可以通过kbhit()函数来检测当前是否有键盘输入

getch()函数用来从控制台读取一个字符

if(kbhit()) //判断是否有键盘输入
{ch=getch(); //ch接收键盘的按键
}

ch=getch()是指在按下键盘后,会把该键字符所对应的ASCII码赋值给ch,然后将ch的值分别和我们用到的键盘字符的ASCII码值进行对比。

完整程序:

#include<stdio.h>
#include<windows.h> //控制DOS界面
#include<conio.h> //接收键盘输入、输出(kbhit(),getch())
#include<time.h> //获取随机数
/****  宏定义****/
#define FrameX 13   //游戏窗口左上角的x轴坐标
#define FrameY 3    //游戏窗口左上角的y轴坐标
#define Frame_height 20  //游戏窗口的高度
#define Frame_width 18  //游戏窗口的宽度/**** 定义全局变量 ****/
int i,j,Temp,Temp1,Temp2; //temp,temp1,temp2用于记住和转换方块变量的值
//标记游戏屏幕的图案:2,1,0分别表示该位置为游戏边框,方块,无图案;初始化为无图案
int a[80][80]={0};
int b[4]; //1表示由方块,0表示无方块
struct Tetris //声明俄罗斯方块的结构体
{int x; //中心方块的x轴坐标 int y; //中心方块的y轴坐标 int flag; //标记方块类型的序号 int next; //下一个俄罗斯方块类型的序号int speed; //俄罗斯方块移动的速度int number;//产生俄罗斯方块的个数int score; //游戏的分数int level; //游戏的等级
};
HANDLE hOut; //控制台句柄/**** 函数声明 ****/
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 *); //判断是否能移动,返回值为1,能移动;
void Del_Fullline(struct Tetris *); //判断是否满行,并删除满行的俄罗斯方块
void Gameplay(); //开始游戏
void regulation(); //游戏规则
void explation(); //按键说明
void welcome(); //欢迎界面
void Replay(struct Tetris * tetris); //重新开始游戏
void title(); //欢迎界面上方的标题
void flower(); //字符花装饰
void close(); //关闭游戏/*** 设计字体颜色 ***/
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 title()
{color(15);//亮白色gotoxy(28,3);printf("俄 罗 斯 方 块\n"); //输出标题color(11); //亮蓝色gotoxy(18,5);      // ■printf("■");      // ■■gotoxy(18,6);      // ■printf("■■");gotoxy(18,7);printf("■");color(14); //黄色gotoxy(26,6);      //■■printf("■■");    //  ■■gotoxy(28,7);printf("■■");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("■■■");
}/*** 菜单边框 ***/
void welcome()
{int n;int i,j=1;color(14);for(i=9;i<=20;i++) //循环y纵坐标,打印输出上,下边框 {for(j=15;j<=60;j++) //循环x横坐标,打印输出左,右边框 {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);color(3);printf("请选择[1,2,3,4]: \b\b");color(14);scanf("%d",&n); //输入选项switch(n){case 1:system("cls");DrawGameframe(); //绘制游戏边界 Gameplay();  break;case 2:explation(); break;case 3:regulation();break;case 4:close();break;  }
}/*** 制作游戏窗口 ***/
void DrawGameframe()
{gotoxy(FrameX+Frame_width-5,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("╚");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;i<Frame_height;i++){gotoxy(FrameX,FrameY+i);printf("║"); //打印左竖框 a[FrameX][FrameY+i]=2;//标记左竖框为游戏边框,防止边框出界 }for(i=1;i<Frame_height;i++){gotoxy(FrameX+2*Frame_width-2,FrameY+i);printf("║"); //打印右竖框 a[FrameX+2*Frame_width-2][FrameY+i]=2;//标记右竖框为游戏边框,防止方块出界 }
} /*** 制作俄罗斯方块 ***/
void MakeTetris(struct Tetris *tetris)
{a[tetris->x][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(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:   // ■{//        ■■//           ■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 6:  //   ■{  //       ■■■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:  //■{   //     ■■//         ■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:// ■■{   //      ■■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 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: //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: //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: //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 16: //7字方块     ■■{        //            ■//            ■ color(9);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: //7字方块  ■■■{        //             ■     color(9);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: //7字方块     ■{        //            ■//          ■■ color(9);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: //7字方块   ■{        //          ■■■          color(9);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;}}
} //■横向占2个字符,纵向占1个字符/** 打印俄罗斯方块 **/
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-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("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+5);
color(4);
printf("speed:");
color(12);
printf(" %dms",tetris->speed); //输出速度
}/**** 判断是否可移动 ****/
int ifMove(struct Tetris *tetris)
{if(a[tetris->x][tetris->y]!=0)//当中心块位置上有图案时,返回值为0,即不可移动 {return 0;}else{if((tetris->flag==1&&(a[tetris->x][tetris->y-1]==0 && a[tetris->x+2][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==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==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==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==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==19 && (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==17 && (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[4]中有4个元素,循环这4个元素,让每个元素的值都为0{b[i]=0;    } MakeTetris(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("  "); //清除方块 }} }
}/*** 判断是否满行 ***/
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;i<FrameX+2*Frame_width-2;i+=2){if(a[i][j]==1) //竖坐标依次从下往上,横坐标依次由左向右判断是否满行 {k++; //记录此行方块的个数 if(k==Frame_width-2) //如果满行 {for(k=FrameX+2;k<FrameX+2*Frame_width-2;k+=2) //删除满行的方块 {a[k][j]=0;gotoxy(k,j);printf("  ");} //如果删除行以上的位置有方块,则先删除,再将方块下移到一个位置for(k=j-1;k>FrameY;k--){for(i=FrameX+2;i<FrameX+2*Frame_width-2;i+=2){if(a[i][k]==1){a[i][k]=0;gotoxy(i,k);printf("  ");a[i][k+1]=1;gotoxy(i,k+1);printf("■"); }   }   }j++; //方块下移后,重新判断删除行是否满行del_rows++; //记录删除方块的行数 } }}}tetris->score+=100*del_rows; //每删除一行,得100分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; //初始化俄罗斯方块数为0个tetris->speed=300; // 初始移动速度为300tetris->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接收{ch=getch();if(ch==75 ) //按 ←键则向左移动,中心横坐标减2 {tetris->x-=2;}if(ch==77) //按 →键则1向右移动,中心横坐标加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) //按 ↑键则1向右移动,中心横坐标加2 {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; }if(tetris->flag>=8 && tetris->flag <=11){tetris->flag++;tetris->flag%=4;tetris->flag+=8; }if(tetris->flag>=12 && tetris->flag <=15){tetris->flag++;tetris->flag%=4;tetris->flag+=12; }if(tetris->flag>=16 && tetris->flag <=19){tetris->flag++;tetris->flag%=4;tetris->flag+=16; }}if(ch==32) //按空格键暂停 {PrintTetris(tetris);while(1){if(kbhit()) //再次按空格键,继续游戏 {ch=getch();if(ch==32){goto label;}}}}if(ch==27){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;i<tetris->y+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");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); }//while(1) 循环产生方块,直至游戏结束
} /*** 重新开始游戏 ***/
void Replay(struct Tetris *tetris)
{system("cls"); //清屏memset(a,0,6400*sizeof(int)); DrawGameframe(); //制作游戏窗口Gameplay();//开始游戏 }/*** 按键说明 ***/
void explation()
{int i,j=1;system("cls");color(13);gotoxy(32,3);printf("按键说明");color(2);for(i=6;i<=16;i++) //输出上下边框 {for(j=15;j<=60;j++){gotoxy(j,i);if(i==6||i==16) printf("=");else if(j==15||j==59) printf("||");    }       }color(3);gotoxy(18,7); printf("tip1:玩家可以通过←→方向键来移动方块");color(10);gotoxy(18,9);printf("tip2:玩家可以通过 ↑使方块旋转");color(14);gotoxy(18,11);printf("tip3:玩家可以通过 ↓加速方块下落");color(11);gotoxy(18,13);printf("tip4:按空格键暂停游戏,再按空格键继续");color(4);gotoxy(18,15);printf("tip5:按ESC键退出游戏");getch(); //按任意键返回主界面 system("cls");main();
}/*** 游戏规则 ***/
void regulation()
{int i,j=1;system("cls");color(13);gotoxy(34,3);printf("游戏规则");color(2);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("tip1:不同形状的小方块从屏幕上方落下,玩家通过调整");gotoxy(22,9);printf("方块的位置和方向,使他们在屏幕底部拼出完整的");gotoxy(22,11);printf("一条或几条");color(14);gotoxy(16,13);printf("tip2:每消除一行,积分涨100");color(11);gotoxy(16,15);printf("tip3:每积累1000分,会提升一个等级");color(10);gotoxy(16,17);printf("tip4:提升等级会使方块下落速度加快,游戏难度加大");getch();system("cls");welcome();}/*** 退出 ***/
void close()
{exit(0);
}/*** 主函数 ***/
int main()
{title(); //欢迎界面上的标题 welcome(); //新添加的语句 return 0;} 

俄罗斯方块游戏系统-c语言版相关推荐

  1. 模拟投票系统--c语言版

    模拟投票系统–c语言版 题目及要求 请设计完成一个投票系统,实现三个角色: 选民.备选对象.管理员: 实现参加票选.管理投票过程.结果查询与公布.加入投票等.代码要能提供以下几个基本功能. (1)注册 ...

  2. c语言程序设计俄罗斯方块PPT,俄罗斯方块游戏:C语言程序设计初步感受

    C语言课程设以一节课,老师提供了一个C语言的俄罗斯方块游戏让我们感受,本学期C语言课程,主要是各种语句的练习,这次是用以前的知识来感受一个实际的系统. 首先安装c-free,然后打开老师所发给我们的小 ...

  3. 俄罗斯方块游戏(C语言)

    简介:俄罗斯方块(Tetris)是一款经典的游戏,下面是用C语言实现俄罗斯方块的示例代码: code #include <stdio.h> #include <stdlib.h> ...

  4. 推箱子游戏(C语言版)

    [C语言经典算法100道实战题]点击链接即可在线学习: https://edu.csdn.net/course/detail/37564 一.推箱子游戏C语言版[运行效果如下]** 二.安装图形库 我 ...

  5. 使用百度云智能SDK和树莓派搭建简易的人脸识别系统 Python语言版

    硬件 树莓派4B一个 CSI摄像头一个 笔者使用的是树莓派4B和CSI摄像头,但是树莓派3和USB摄像头等相似设备均可. 百度云智能设置 Step 1 登录 百度云智能 网址https://cloud ...

  6. 关于俄罗斯方块游戏软件C语言初步感受

    C语言课程设,老师先给我们发了一个使用C语言做的飞机游戏,第一次看到用C语言做的游戏,虽然画面简陋,但却是真正的游戏.后老师又给我们发了用C语言做的俄罗斯方块的游戏 int x;     //中心方块 ...

  7. c语言 队列 游戏,循环队列实现约瑟夫游戏(C语言版)

    #include #include typedef struct node { int *base; int front; int rear; }Node; /* 思路: *使用一个顺序循环队列来存放 ...

  8. 三子棋小游戏(C语言版)

    目录 一.游戏菜单 二.打印棋盘 三.下棋 四.判断输赢 五.游戏结果 六.代码整合 自己上手写一个小游戏首先需要知道游戏的框架.步骤以及相关的逻辑 主要从以下三个文件着手: test.c  游戏的测 ...

  9. 消除类游戏201512(C语言版)

    问题描述 消除类游戏是深受大众欢迎的一种游戏,游戏在一个包含有n行m列的游戏棋盘上进行,棋盘的每一行每一列的方格上放着一个有颜色的棋子,当一行或一列上有连续三个或更多的相同颜色的棋子时,这些棋子都被消 ...

最新文章

  1. php设置低于设定值不能用,php memory limit怎么设置不限制
  2. 感动哭!Starbreeze发布《收获日2》VR版
  3. (2) 假设字符串类似这样的aba和aab就相等,现在随便给你二组字符串,请编程比较他们看是否相等...
  4. Linux 上的高可用中间件
  5. android volatile的使用
  6. 【Python】GUI编程(Tkinter)教程
  7. 从四大造字法看文字所承载的文化_对央视“汉字的魅力”讲授之管见(《天津教育报》2012年6月15日)...
  8. 043、JVM实战总结:动手实验,自己动手模拟出频繁Young GC的场景
  9. 网络编程之 信号捕捉器(函数指针与回调函数)
  10. pr自学教程,为丢失的镜头注入新的活力
  11. 技巧:在Silverlight应用程序中操作Cookie
  12. ASP.NET Core中返回 json 数据首字母大小写问题
  13. java------io基础(一)
  14. 局域网邮件服务器搭建地址薄更新,搭建局域网邮件服务器
  15. 【OSS】使用Element实现图片上传到OSS
  16. mac下Charles https抓包乱码,手机不能上网解决
  17. ES6中的箭头函数详细梳理
  18. OSPF你懂多少之经典问题50个
  19. uniapp开发app中配置高德地图定位流程
  20. 前沿重器[13] | 知乎query改写思路启示

热门文章

  1. Nginx优化之虚拟主机
  2. uniapp 下载文件却变成了跳转
  3. 软件测试自动化分类,自动化测试的主要分类
  4. request.js?b775:43 Uncaught (in promise) Error: 抱歉,系统繁忙,请稍后重试! at __webpack_exports__.default (r
  5. perl 产生随机数
  6. HDU 6411 带劲的and和
  7. 某市体育彩票采用整数1,2,3,…,36表示36种体育运动,一张彩票可选择7种运动。编写程序,选择一张彩票的号码,使这张彩票的7个号码之和是105且相邻两个号码之差按顺序依次是1,2,3,4,5,6。
  8. Grad-CAM可视化
  9. 动物识别系统代码python_动物识别系统 代码
  10. 构建和管理有效API市场的关键步骤