俄罗斯方块的实现—C语言
目录
█ 开发工具:Dev C++
简单解释几个函数:
1、制作俄罗斯方块:
/*
*制作俄罗斯方块
*/
void MakeTetris(struct Tetris *tetris)
{
a[tetris->x][tetris->y ]=b[0];
switch(tetris->flag)
{
case 1:
{
color(2);
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(3);
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(3);
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:
{
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(6);
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:
{
color(6);
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:
{
color(6);
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:
{
color(6);
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:
{
color(7);
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:
{
color(7);
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:
{
color(7);
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:
{
color(7);
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:
{
color(7);
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:
{
color(7);
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:
{
color(7);
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:
{
color(7);
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;
}
}
}
✔在本游戏中,使用“■”来填充各种方块,在横向上,它占两个字符;在纵向上,它占一个字符。俄罗斯方块的7种基本图形旋转后共有19种旋转图形。而此段代码就是制作出这19种俄罗斯形状。
2、 判断方块是否可以移动
/*
*判断是否可移动
*/
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;
}
✔要判断移动到的位置是不是空位置,首先判断此位置中心方块是否是方块或墙壁,如果是方块或者墙壁,则不可移动;如果不是,则继续判断,如果19种形状的俄罗斯方块的各自的“■” 位置上都是空,那么表示可以移动。
3、 判断是否满行
/*
*判断是否满行,并删除满行的俄罗斯方块
*/
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(" ");
// Sleep(1);
}
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 += 10* del_rows; //每删除一行,得10分
tetris->speed -= 20*del_rows; //速度加快20ms
if (del_rows>0 && (tetris->score % 20 == 0 || tetris->score / 20>tetris->rank - 1))
{ //如果得20分即累计删除2行.进一级
tetris->rank++;
}
}
完整代码如下:
/*******头 文 件*******/
#include <stdio.h> //标准输入输出函数库
#include <windows.h> //控制 DOS界面(获取控制台上坐标位置、设置字体颜色)
#include<conio.h> //接受键盘输入输出
#include<time.h> //用于获得随机数
/******* 宏 定 义 *******/
#define FrameX 4 //游戏窗口左上角的X轴坐标为13
#define FrameY 4 // 游戏窗口左上角的Y轴坐标为3
#define Frame_height 20 //游戏窗口的高度为20
#define Frame_width 18 // 游戏窗口的宽度为18
/******* 定 义 全 局 变 量********/
int i,j,Temp,Temp1,Temp2,speed;
int score=0;
int rank=0;
int a[80][80]={0};
int b[4];
int HighScore=0;
struct Tetris{
int x;
int y;
int flag;
int next;
int speed;
int number;
int score;
int rank;
};
HANDLE hOut;
/********函 数 声 明********/
int color(int c);
void gotoxy(int x,int y);
void gameTime(clock_t star_time);
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 updateGrade() ;
void Gameplay();
void regulation();
void explation();
void welcom();
void Replay(struct Tetris*tetris);
void title();
void rabbit();
void HideCursor();
void close();
void File_in();
void File_out();
int main()
{
HideCursor();
title();
rabbit();
welcom();
File_out();
return 0;
}
/**
*文字颜色函数
*/
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 HideCursor()
{
CONSOLE_CURSOR_INFO curInfo; //定义光标信息的结构体变量
curInfo.dwSize = 1; //如果没赋值的话,隐藏光标无效
curInfo.bVisible = FALSE; //将光标设置为不可见
HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE); //获取控制台句柄
SetConsoleCursorInfo(handle, &curInfo); //设置光标信息
}
/**
*欢迎界面上方的标题
*/
void title(){
color(9);//深蓝色
gotoxy(24,3);
printf("趣 味 俄 罗 斯 方 块n");
color(11);
gotoxy(18,5);
printf("■");
gotoxy(18,6);
printf("■■");
gotoxy(18,7);
printf("■");
color(6);
gotoxy(26,6);
printf("■■");
gotoxy(28,7);
printf("■■");
color(2);
gotoxy(36,6);
printf("■■");
gotoxy(36,7);
printf("■■");
color(3);
gotoxy(45,5);
printf("■");
gotoxy(45,6);
printf("■");
gotoxy(45,7);
printf("■");
gotoxy(45,8);
printf("■");
color(7);
gotoxy(56,6);
printf("■");
gotoxy(52,7);
printf("■■■");
}
/**
*绘制兔子
*/
void rabbit(){
gotoxy(64,7);
color(3);
printf(" │ ̄│ │ ̄│");
gotoxy(64,8);
printf(" │ │ │ │");
gotoxy(64,9);
printf(" │ │ │ │");
gotoxy(64,10);
printf("_│");
gotoxy(73,10);
printf("│_");
gotoxy(62,11);
printf("│");
gotoxy(76,11);
printf("│");
gotoxy(62,12);
printf("│ │");
gotoxy(62,13);
printf("│ │");
gotoxy(62,14);
printf("│ │");
gotoxy(62,15);
printf("┗━━┯━━━┛━━━┱━━┛");
gotoxy(64,16);
printf("┏┫ ┣┓");
gotoxy(62,17);
printf("━━┸━━━━┷━━━━┷━━");
gotoxy(67,11);
color(5);
printf("`~'~`'");
color(12);
gotoxy(67,12);
printf("○ ○");
gotoxy(65,13);
color(13);
printf("//");
gotoxy(74,13);
printf("//");
gotoxy(69,14);
color(2);
printf("┻");
gotoxy(65,19);
color(4) ;
printf(" 光宗耀组");
}
/*
*菜单选项边框
*/
void welcom()
{
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("||");
}
}
//---desige menu option text
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]:[ ]bb");
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-7,FrameY-2);
color(15);
printf("趣味俄罗斯方块");
gotoxy(FrameX+2*Frame_width+3,FrameY+7);
color(7);
printf("︻︻︻︻︻");
gotoxy(FrameX+2*Frame_width+13,FrameY+7);
color(15);
printf("下一个出现方块:");
gotoxy(FrameX+2*Frame_width+3,FrameY+13);
color(7);
printf("︼︼︼︼︼");
gotoxy(FrameX+2*Frame_width+3,FrameY+17);
color(8);
printf("↑键:旋转");
gotoxy(FrameX+2*Frame_width+3,FrameY+19);
printf("空格:暂停游戏");
gotoxy(FrameX+2*Frame_width+3,FrameY+15);
printf("Esc:退出游戏");
gotoxy(FrameX,FrameY);
color(15);
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[13][23]=2, 防止方块出边框
a[FrameX+2*Frame_width-2][FrameY+Frame_height]=2; //边框右下角的 a[47][23]=2, 防止方块出边框
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-1,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)
{
case 1:
{
color(2);
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(3);
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(3);
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:
{
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(6);
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:
{
color(6);
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:
{
color(6);
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:
{
color(6);
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:
{
color(7);
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:
{
color(7);
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:
{
color(7);
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:
{
color(7);
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:
{
color(7);
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:
{
color(7);
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:
{
color(7);
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:
{
color(7);
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-2;j<=tetris->y+1;j++)
{
if( a[i][j]==1 && j>FrameY)
{
gotoxy(i,j);
printf("■") ;
}
}
}
----print menu message
gotoxy(FrameX+2*Frame_width+3,FrameY-1);
File_out();
color(8);
printf("最高记录:%d",HighScore);
gotoxy(FrameX+2*Frame_width+3,FrameY+1);
color(8);
printf("rank: ");
color(8);
printf("%d",tetris->rank);
gotoxy(FrameX+2*Frame_width+3,FrameY+3);
color(8);
printf("score: ");
color(8);
printf("%d",tetris->score);
gotoxy(FrameX+2*Frame_width+3,FrameY+5);
color(8);
printf("speed: ");
color(8);
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 File_out()
{
FILE *fp;
fp =fopen("save.txt","r+");
fscanf(fp,"%d",&HighScore);
fclose(fp);
}
/*
*将最高分存储与文件中
*/
void File_in()
{
FILE *fp ;
fp =fopen("save.txt","w+");
fprintf(fp,"%d",HighScore);
fclose(fp);
}
/*
*清除俄罗斯方块的痕迹
*/
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(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(" ");
// Sleep(1);
}
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 += 10* del_rows; //每删除一行,得10分
tetris->speed -= 20*del_rows; //速度加快20ms
if (del_rows>0 && (tetris->score % 20 == 0 || tetris->score / 20>tetris->rank - 1))
{ //如果得20分即累计删除2行.进一级
tetris->rank++;
}
}
/*
*随机产生俄罗斯方块类型的序号
*/
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->rank=1;
while(1)
{
Flag(tetris); //随机产生方块当前序号 和下一个序号
Temp=tetris->flag; //当前方块序号暂时保存
tetris->x=FrameX+2*Frame_width+6; //右边预览界面方块坐标x=55
tetris->y=FrameY+10; //右边预览界面方块坐标y=13
tetris->flag = tetris->next; //下一个方块序号暂给flag ,准备在预览窗口打印
PrintTetris(tetris); //在预览窗口打印下一个方块
tetris->x=FrameX+Frame_width; //游戏窗口出现方块的中心方块坐标x=31
//tetris->x=FrameX+10; //改变游戏窗口出现方块的中心方块坐标x=13
tetris->y=FrameY-1; //游戏窗口出现方块的中心方块坐标y=2
tetris->flag=Temp; //找回当前方块序号
//--keys options按键操作
while(1)
{
label: PrintTetris(tetris);
Sleep(tetris->speed);
CleanTetris(tetris);
Temp1=tetris->x;
Temp2=tetris->flag;
if(kbhit()) // 有键盘输入?
{
ch=getch(); // 有,接受 输入
if(ch==75) // 75 对应方向键 ←
{
tetris->x-=2;
}
if(ch==77) // 77 对应方向键 →
{
tetris->x+=2;
}
if(ch==80) // 80 对应方向键 ↓----加速下落
{
if(ifMove(tetris)!=0) //判断可以移动吗?
{
tetris->y+=2; // 可以,一次下落两行
}
if(ifMove(tetris)==0) //如果不能移动
{
tetris->y=FrameY+Frame_height-2; //确定Y
}
}
if(ch==72)
{
if(tetris->flag>=2 && tetris->flag<=3)// 2/3 是直线方块 ,
{
tetris->flag++; //if 2,then get 3 if 3, then get 4
tetris->flag%=2; //3%2=1 4%2=0
tetris->flag+=2; //1+2=3 0+2=2
}
if(tetris->flag>=4 && tetris->flag<=7) // 4/5/6/7 是T字方块
{
tetris->flag++; //if4 ,then get 5 if7, then get 8
tetris->flag%=4; //5%4=1 8%4=0
tetris->flag+=4; //1+4=5 0+4=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) // ESC键 ----返回 欢迎界面
{
system("cls");
memset(a,0,6400*sizeof(int));
welcom();
}
if(ifMove(tetris)==0) //如果不可以动 ----上面的操作无效
{
tetris->x=Temp1;
tetris->flag=Temp2;
}
else //如果可移动,返回label
{
goto label;
}
}
tetris->y++; //没有操作,方块向下移动,每次一行
if(ifMove(tetris)==0) //向下移动,又判断不能移动,方块放在此处
{
tetris->y--;
PrintTetris(tetris);
Del_Fullline(tetris);
break;
}
}
//--game over: blocks get the top of frame
for (i=tetris->y-2;i<tetris->y+2;i++) //方块接触到框顶位置
{
if(i==FrameY)
{
system("cls");
gotoxy(29,7);
printf(" n");
color(15);
printf("ttt■■■■ ■ ■ ■■ n");
printf("ttt■ ■■ ■ ■ ■ n");
printf("ttt■■■ ■ ■ ■ ■ ■ n");
printf("ttt■■■ ■ ■ ■ ■ ■ n");
printf("ttt■ ■ ■■ ■ ■ n");
printf("ttt■■■■ ■ ■ ■■ n");
gotoxy(29,18);
color(6);
printf("再玩一局--------1");
gotoxy(29,19);
printf("不玩了--------2");
gotoxy(29,20);
printf("choose[1/2]");
color(15);
scanf("%d",&n);
switch(n)
{
case 1:
system("cls");
Replay(tetris);
break;
case 2:
system("cls");
gotoxy(29,7);
printf("您的得分是: %d",tetris->score);
if(tetris->score >= HighScore)
{
color(6);
gotoxy(29,8);
printf("创记录啦!最高记录被你刷新啦~");
HighScore=tetris->score;
File_in();
}else{
color(6);
gotoxy(29,8);
printf("继续努力吧~ 你离最高分还差:%d",HighScore-tetris->score);
}
exit(0);
break;
}
}
}
tetris->flag = tetris->next; //清除右边窗口方块的图形
tetris->x=FrameX+2*Frame_width+6;
tetris->y=FrameY+10;
CleanTetris(tetris);
}
}
/*
*重新开始游戏
*/
void Replay(struct Tetris *tetris)
{
system("cls");
memset(a,0,6400*sizeof(int));
DrawGameframe();
Gameplay();
}
/*
*按键说明
*/
void explation(){
int i,j=1;
system("cls");
color(15);
gotoxy(32,3);
printf("按键说明");
color(8);
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(6);
gotoxy(18,7);
printf("tip1:玩家可以通过←→方向键来移动方块");
color(2);
gotoxy(18,9);
printf("tip2:通过↑使方块旋转");
color(3);
gotoxy(18,11);
printf("tip3:通过↓加速方块下落");
color(7);
gotoxy(18,13);
printf("tip4:按空格键暂停游戏,再按空格键继续游戏");
color(11);
gotoxy(18,15);
printf("tip5:按 Esc退出游戏");
getch();
system("cls");
main();
}
/*
*游戏规则
*/
void regulation()
{
int i,j=1;
system("cls");
color(15);
gotoxy(56,3);
printf("游戏规则");
color(8);
for(i=6;i<=18;i++)
{
for(j=30;j <=88;j++ )
{
gotoxy(j,i);
if(i==6||i==18) printf("=");
else if(j==30||j==87) printf("||");
}
}
color(7);
gotoxy(34,7);
printf("tip1:不同形状的小方块从屏幕上方落下,玩家通过调整");
gotoxy(42,9);
printf("方块的位置和方向,使它们在屏幕底部拼出完整的");
gotoxy(42,11);
printf("一行或几行");
color(6);
gotoxy(34,13);
printf("tip2:每消除一行,积分增加100");
color(2);
gotoxy(34,15);
printf("tip3:每累计1000分,会提升一个等级");
color(3);
gotoxy(34,17);
printf("tip4:提升等级会使方块下落速度加快,游戏难度加大");
getch();
system("cls");
welcom();
}
/*
*退出游戏
*/
void close()
{
exit (0);
}
运行界面展示: