需求分析
首先对做俄罗斯方块的几个模块做分析
- 界面搭建
游戏欢迎界面
游戏主窗口
游戏规则界面
键盘说明界面
游戏结束界面 - 方块设置
7种基本方块
随机产生下落方块
方块的形状变化
下落速度
方块颜色随方向改变而变化 - 积分规则
每消除一行,积分增加100
每积累1000分,提升一个等级 - 排行榜
查看排行榜
游戏结束后输入昵称,查看排名 - 更改主页面背景颜色
- 添加背景音乐
#include <stdio.h>
#include <time.h>
#include <windows.h>
#include <conio.h>
#include<mmsystem.h>
#pragma comment(lib,"Winmm.lib")
/*******宏定义*******/
//游戏窗口左上角的X轴坐标
#define FrameX 13
//游戏窗口左上角的Y轴坐标
#define FrameY 3
//游戏窗口的高度
#define Frame_height 20
//游戏窗口的宽度
#define Frame_width 18
//文件
#define N 100
/*******全局变量 *******/
//temp,temp1,temp2用于记住和转换方块变量的值
int i,j,Temp,Temp1,Temp2;
//标记游戏屏幕的图案:2,1,0分别表示该位置为游戏边框、方块、无图案;初始化为无图案
int a[80][80]={0};
//标记4个"口"方块:1表示有方块,0表示无方块
int b[4];
//文件位置
char * file_place="C:\\Users\\12399\\Desktop\\charts.txt";
//声明俄罗斯方块的结构体
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 *);
//判断是否能移动,返回值为1->能移动
int ifMove(struct Tetris *);
//判断是否满行,并删除满行的俄罗斯方块
void Del_FullLine(struct Tetris *);
//开始游戏
void Gameplay();
//游戏规则
void regulation();
//按键说明
void explain();
//欢迎界面
void welcome();
//重新开始游戏
void Replay(struct Tetris *);
//关闭游戏
void close();
//设置文字颜色
int color(int c);
//更改主界面背景颜色
void change();
//写入排名
void intoFile();
//显示排名
void outFile();
//背景音乐
void music();
//设置目标位置
void gotoXY(int x,int y){
COORD coord;
coord.X = x;
coord.Y = y;
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),coord);
}
//设置文字颜色
int color(int c){
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),c);
return 0;
}
//主界面
void welcome() {
int n;
//T
color(15);
gotoXY(20, 5);
printf("■■■■");
color(9);
gotoXY(20, 6);
printf("■■");
color(11);
gotoXY(24, 6);
printf("■■");
color(9);
gotoXY(22, 7);
printf("■");
color(11);
gotoXY(24, 7);
printf("■");
color(9);
gotoXY(22, 8);
printf("■");
color(11);
gotoXY(24, 8);
printf("■");
color(15);
gotoXY(22, 9);
printf("■■");
color(15);
gotoXY(22, 10);
printf("■■");
//E
color(14);
gotoXY(31, 5);
printf("■■■");
color(14);
gotoXY(31, 6);
printf("■");
color(15);
gotoXY(33, 6);
printf("■");
color(15);
gotoXY(31, 7);
printf("■■■");
color(15);
gotoXY(31, 8);
printf("■■");
color(15);
gotoXY(31, 9);
printf("■");
color(10);
gotoXY(33, 9);
printf("■");
color(15);
gotoXY(31, 10);
printf("■");
color(10);
gotoXY(33, 10);
printf("■■■");
//T
color(15);
gotoXY(40, 5);
printf("■■■■");
color(5);
gotoXY(40, 6);
printf("■■");
color(13);
gotoXY(44, 6);
printf("■■");
color(5);
gotoXY(42, 7);
printf("■");
color(13);
gotoXY(44, 7);
printf("■");
color(5);
gotoXY(42, 8);
printf("■");
color(13);
gotoXY(44, 8);
printf("■");
color(15);
gotoXY(42, 9);
printf("■■");
color(15);
gotoXY(42, 10);
printf("■■");
//R
color(2);
gotoXY(52, 5);
printf("■");
color(1);
gotoXY(54, 5);
printf("■■■");
color(2);
gotoXY(52, 6);
printf("■");
color(1);
gotoXY(58, 6);
printf("■");
color(1);
gotoXY(52, 7);
printf("■■");
color(2);
gotoXY(56, 7);
printf("■■");
color(1);
gotoXY(52, 8);
printf("■");
color(2);
gotoXY(54, 8);
printf("■");
color(1);
gotoXY(52, 9);
printf("■");
color(2);
gotoXY(56, 9);
printf("■");
color(1);
gotoXY(52, 10);
printf("■");
color(2);
gotoXY(58, 10);
printf("■");
//i
color(15);
gotoXY(64, 5);
printf("■■");
color(15);
gotoXY(64, 6);
printf("■■");
color(13);
gotoXY(64, 8);
printf("■");
color(11);
gotoXY(66, 8);
printf("■");
color(13);
gotoXY(64, 9);
printf("■");
color(11);
gotoXY(66, 9);
printf("■");
color(13);
gotoXY(64, 10);
printf("■");
color(11);
gotoXY(66, 10);
printf("■");
//S
color(5);
gotoXY(74, 5);
printf("■■■");
color(15);
gotoXY(72, 6);
printf("■");
color(5);
gotoXY(74, 6);
printf("■");
color(15);
gotoXY(72, 7);
printf("■■■");
color(15);
gotoXY(72, 8);
printf("■■■");
color(5);
gotoXY(74, 9);
printf("■");
color(15);
gotoXY(76, 9);
printf("■");
color(5);
gotoXY(70, 10);
printf("■■■");
color(12);
gotoXY(45, 12);
printf("WELCOME");
//花
gotoXY(84,21);
color(12);
printf("(_)"); //红花上边花瓣
gotoXY(82,22);
printf("(_)"); //红花左边花瓣
gotoXY(86,22);
printf("(_)"); //红花右边花瓣
gotoXY(84,23);
printf("(_)"); //红花下边花瓣
gotoXY(85,22); //红花花蕊
color(6);
printf("@");
gotoXY(90,20);
color(13);
printf("(_)"); //粉花左边花瓣
gotoXY(94,20);
printf("(_)"); //粉花右边花瓣
gotoXY(92,19);
printf("(_)"); //粉花上边花瓣
gotoXY(92,21);
printf("(_)"); //粉花下边花瓣
gotoXY(93,20);
color(6);
printf("@");
gotoXY(89,22);
printf("|");
gotoXY(90,21);
printf("/");
gotoXY(88,23);
printf("\\|");
gotoXY(88,24);
printf("`|/");
gotoXY(88,25);
printf("\\|");
gotoXY(89,26);
printf("| /");
gotoXY(89,27);
printf("|");
gotoXY(85,27);
color(10);
printf("\\\\\\\\"); //草地
gotoXY(91,27);
printf("//");
gotoXY(85,28);//18
color(2);
printf("^^^^^^^^");
gotoXY(84,14);
color(9);
printf("西南大学");
gotoXY(84,16);
color(11);
printf("陈铷、陈旺旺");
int i,j = 1;
color(14); //黄色边框
for (i = 13; i <=28 ; i++) //输出上下边框===
{
for (j = 21; j <= 79; j++) //输出左右边框||
{
gotoXY(j, i);
if (i == 13 || i == 28) printf("—");
else if (j == 21 || j == 79) printf("|");
}
}
color(11);
gotoXY(30, 16);
printf("1.开始游戏");
gotoXY(56, 16);
printf("2.键盘说明");
gotoXY(30, 20);
printf("3.规则说明");
gotoXY(56, 20);
printf("4.查看排名\n");
gotoXY(30, 24);
printf("5.更改主界面背景颜色\n");
gotoXY(56, 24);
printf("6.退出游戏\n");
color(236);
gotoXY(42,26);
printf("请选择 1 2 3 4 5 6:");
music();
color(15);
scanf("%d", &n);
switch (n) {
case 1:
system("cls");
DrawGameFrame();
Gameplay();
break;
case 2:
explain();
break;
case 3:
regulation();
break;
case 4:
outFile();
getch();
system("cls");
welcome();
break;
case 5:
change();
break;
case 6:
close();
break;
}
}
//方块
void MakeTetris(struct Tetris *tetris) {
a[tetris->x][tetris->y] = b[0];
switch (tetris->flag)
{
case 1: /*田字方块 ■ ■
■ ■ */
{
color(9);
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(10);
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(11);
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(12);
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(13);
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: /* 顺时针180°T字方块 ■
■ ■ ■*/
{
color(14);
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(1);
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(2);
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(3);
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(4);
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(5);
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(6);
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(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 15: /* 顺时针270°7字方块 ■ ■ ■
■ */
{
color(11);
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(10);
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(14);
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(5);
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 DrawGameFrame() {
gotoXY(FrameX + Frame_width - 7, FrameY - 2);
color(11);
printf("俄 罗 斯 方 块");
gotoXY(FrameX + 2 * Frame_width + 13, FrameY + 7);
color(3);
printf("下一个方块:");
gotoXY(FrameX + 2 * Frame_width + 3, FrameY + 7);
color(2);
printf("**********");
gotoXY(FrameX + 2 * Frame_width + 3, FrameY + 13);
color(2);
printf("**********");
gotoXY(FrameX + 2 * Frame_width + 3, FrameY + 14);
color(14);
printf("↑:旋转方块");
gotoXY(FrameX + 2 * Frame_width + 3, FrameY + 16);
printf("space:暂停/继续");
gotoXY(FrameX + 2 * Frame_width + 3, FrameY + 18);
printf("↓:加速下落");
gotoXY(FrameX + 2 * Frame_width + 3, FrameY + 20);
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; 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 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) //按 ←键则向左动,中心横坐标减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) {
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)); //初始化BOX数组
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(30, 16);
color(11);
printf("1.再玩一次");
gotoXY(30, 18);
printf("2.查看排名并退出游戏\n");
int n;
color(236);
gotoXY(32, 20);
printf("请选择1 2:");
color(11);
scanf("%d", &n);
switch (n) {
case 1:
system("cls");
Replay(tetris);
break;
case 2:
system("cls");
FILE *fp;
char name[20];
char soc[20];
if( (fp=fopen(file_place, "at+")) == NULL ){
puts("Fail to open file!");
exit(0);
} else{
printf("请输入昵称:");
scanf("%s",name);
fputs(name,fp);
fputs("\t",fp);
printf("请输入分数:");
scanf("%s",soc);
fputs(soc,fp);
fputs("\n",fp);
}
fclose(fp);
outFile();
getch();
close();
exit(0);
break;
}
}
}
tetris->flag = tetris->next; //清除下一个俄罗斯方块的图形(右边窗口)
tetris->x = FrameX + 2 * Frame_width + 6;
tetris->y = FrameY + 10;
CleanTetris(tetris);
}
}
//退出
void close() {
exit(0);
}
//键盘说明
void explain() {
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("← →:左右移动方块");
color(10);
gotoXY(18, 9);
printf("↑:旋转方块");
color(14);
gotoXY(18, 11);
printf("↓:加速方块下落");
color(11);
gotoXY(18, 13);
printf("space: 暂停游戏/继续游戏");
color(4);
gotoXY(18, 15);
printf("ESC:退出游戏");
getch();
system("cls");
welcome();
}
//规则说明
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 change(){
system("cls");
color(206);
gotoXY(34, 3);
printf("更改成功");
getch(); //按任意键返回主界面
system("cls");
welcome();
}
//再玩一次
void Replay(struct Tetris *) {
system("cls"); //清屏
memset(a, 0, 6400 * sizeof(int)); //初始化BOX数组,否则不会正常显示方块,导致游戏直接结束
DrawGameFrame(); //制作游戏窗口
Gameplay(); //开始游戏
}
//显示方块
void PrintTetris(struct Tetris *tetris) {
for (i = 0; i < 4; i++) {
b[i] = 1; //数组b[4]的每个元素的值都为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("等级: ");
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(" %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)) ||
//或为直线方块且除中心方块位置外,其他"■"字方块位置上无图案时,返回值为1,即可移动
(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 Flag(struct Tetris *tetris) {
tetris->number++; //记住产生方块的个数
srand(time(NULL)); //初始化随机数
if (tetris->number == 1) {
tetris->flag = rand() % 19 + 1; //记住第一个方块的序号
}
tetris->next = rand() % 19 + 1; //记住下一个方块的序号
}
//清除方块的轨迹
void CleanTetris(struct Tetris *tetris) {
for (i = 0; i < 4; i++) {
b[i] = 0; //数组b[4]的每个元素的值都为0
}
MakeTetris(tetris); //制作俄罗斯方块
for (i = tetris->x - 2; i <= tetris->x + 4; i += 2) //■ X ■ ■ X为中心方块
{
for (j = tetris->y - 2; j <= tetris->y + 1; j++) /* ■
■
X
■ */
{
if (a[i][j] == 0 && j > FrameY) {
gotoXY(i, j);
printf(" "); //清除方块
}
}
}
}
//满行消除并积分
void Del_FullLine(struct Tetris *tetris){
int sor;
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 += 100 * del_rows; //每删除一行,得100分
if (del_rows > 0 && (tetris->score % 1000 == 0 ||
tetris->score / 1000 > tetris->level - 1)) { //如果得1000分即累计删除10行,速度加快20ms并升一级
tetris->speed -= 20;
tetris->level++;
sor = tetris->level;
}
}
//输出
void outFile(){
system("cls");
gotoXY(0,5);
color(78);
printf("排 行 榜\n");
color(14);
FILE *fp;
char str[N+1];
if( (fp=fopen(file_place,"rt")) == NULL){
puts("Fail to open file!");
exit(0);
}
while(fgets(str, N, fp) != NULL){
printf("%s", str);
}
fclose(fp);
}
//背景音乐
void music(){
//这里的music.mp3需要放在文件debug中
mciSendString("open music.mp3 alias bkmusic", NULL, 0, NULL);
mciSendString("play bkmusic repeat", NULL, 0, NULL);
}
int main() {
welcome();
}