first commit

master
Your Name 7 years ago
commit f64fe9f560

@ -0,0 +1,798 @@
#include<stdio.h> //标准输入输出
#include<windows.h> //控制控制台
#include<conio.h> //接收键盘信号
#include<time.h> //调用随机数函数
#define FrameX 13 // 游戏窗口左上角X坐标
#define FrameY 3 //游戏窗口左上角Y坐标
#define Frame_gao 20 //游戏窗口高度
#define Frame_kuan 18 //游戏窗口宽度
int i, j, temp, temp1, temp2; //定义全局变量, temp表示存储方块变量的值
int a[80][80] = {0}; //0表示无方块1表示有方块 2为边界
int b[4]; //四个方块值为01
struct fangkuai
{
int x, y; //横纵坐标值
int flag; //方块类型序号
int next; //下一个方块序号
int speed; // 方块速度
int number; //方块个数
int score; //分数
int level; //游戏等级
};
HANDLE hOut; //控制台控制
/********函数声明**********/
void gotoxy(int x, int y); //光标移动到指定位置
int color(int c); //控制台文字颜色
void DrawGameframe(); //绘制游戏边界
void Flag(struct fangkuai *); //产生随机数
void Makefangkuai(struct fangkuai *); //制作方块
void printfangkuai(struct fangkuai *); //打印~
void cleanfangkuai(struct fangkuai *); //清除~
int ifMove(struct fangkuai *); //判断是否可移动
void Del_fullline(struct fangkuai *); //判断是否满行,并删除满行方块
void Gamebegin(); //游戏开始
void welcome(); //欢迎菜单
void explation(); //规则说明
void Replay(struct fangkuai *); //重新游戏
void title(); //界面上方标题
void close(); //关闭游戏
/*****控制文字颜色*******/
int color(int c){
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),c); //只在windows上改变文字颜色
return 0;
} //0~15共16种颜色
/*用法:
coler
printf
*/
/*******文字显示位置********/
void gotoxy(int x, int y)
{
COORD pos;
pos.X = x;
pos.Y = y;
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),pos);
}
/*
gotoxy3010 3010
printf
*/
/*****设置开始界面标题*****/
void title()
{
color(15);
gotoxy(30,3);
printf(" 俄 罗 斯 方 块");
color(11);
gotoxy(17,5);
printf("");
gotoxy(17,6);
printf("■■");
gotoxy(17,7);
printf("");
color(10);
gotoxy(25,5);
printf("■■");
gotoxy(25,6);
printf("■■");
color(13);
gotoxy(33,6);
printf("■■■■");
color(4);
gotoxy(45,5);
printf("■■");
gotoxy(45,6);
printf("");
gotoxy(45,7);
printf("");
color(12);
gotoxy(53,5);
printf("■■");
gotoxy(53,6);
printf(" ■■");
}
/*****设置菜单选项*****/
void welcome(){
int i = 1, j = 1;
int n;
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("||");
}
}
}
color(12);
gotoxy(25,12);
printf("1.开始游戏");
gotoxy(40,12);
printf("2.说明和规则");
gotoxy(33,17);
printf("3.退出游戏\n");
gotoxy(31,19);
printf("本游戏纯属内测");
gotoxy(28,22);
color(3);
printf("请选择[1 2 3]:{ }\b\b");
color(14);
scanf("%d", &n);
switch(n)
{
case 1:
{
system("cls"); //清屏
DrawGameframe();
Gamebegin();
break;
}
case 2:
explation();
break;
case 3:
close();
break;
}
}
/*****游戏窗口界面*****/
void DrawGameframe()
{
gotoxy((FrameX+Frame_kuan-7), FrameY-2);
color(11);
printf("俄罗斯方块");
color(12);
gotoxy(FrameX,FrameY);
printf("");
gotoxy(FrameX + 2*Frame_kuan-2,FrameY);
printf("");
gotoxy(FrameX,FrameY + Frame_gao);
printf("");
gotoxy(FrameX+ 2*Frame_kuan-2,FrameY + Frame_gao);
printf("");
a[FrameX+ 2*Frame_kuan-2][FrameY + Frame_gao] = 2;
/****上横框*****/
for(i = 2; i < 2 * Frame_kuan-2; i += 2){
gotoxy(FrameX + i, FrameY);
printf("");
}
/*****下横框*****/
for(i = 2; i < 2 * Frame_kuan-2; i += 2){
gotoxy(FrameX + i, FrameY + Frame_gao);
printf("");
a[FrameX + i][FrameY + Frame_gao] = 2;
}
/****竖框****/
for(i = 1; i < Frame_gao; i++){ //左
gotoxy(FrameX, FrameY+i);
printf("");
a[FrameX][FrameY + i] = 2;
}
for(i = 1; i < Frame_gao; i++){
gotoxy(FrameX + 2 * Frame_kuan-2, FrameY+i);
printf("");
a[FrameX + 2 * Frame_kuan-2][FrameY+i] = 2;
}
/****提示****/
color(2);
gotoxy(FrameX + 2* Frame_kuan + 3,FrameY + 7);
printf("**********");
gotoxy(FrameX + 2* Frame_kuan + 3,FrameY + 13);
printf("**********");
color(3);
gotoxy(FrameX + 2* Frame_kuan + 3,FrameY + 6);
printf("下一个方块:");
color(14);
gotoxy(FrameX + 2* Frame_kuan + 3,FrameY + 17);
printf("空格:暂停游戏");
gotoxy(FrameX + 2* Frame_kuan + 3,FrameY + 19);
printf("ESC退出游戏");
}
/****制作方块*****/
void Makefangkuai(struct fangkuai *tetris)
{
a[tetris->x][tetris->y] = b[0];
switch(tetris->flag)
{
case 1: //田字方块
{
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: //直线方块:----
{
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: //直线方块: |
{
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字方块
{
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: //T字顺时针转90度方块
{
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: //T字顺时针转180度方块
{
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: //T字顺时针转270度方块
{
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字方块
{
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字顺时针转90度方块
{
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字顺时针转180度方块
{
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字顺时针转270度方块
{
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字方块
{
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字顺时针转90度方块
{
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字顺时针转180度方块
{
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字顺时针转270度方块
{
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字方块
{
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字顺指针转90度方块
{
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字顺时针转180度方块
{
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字顺时针转270度方块
{
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 Printfangkuai(struct fangkuai *tetris)
{
for(i = 0; i < 4; i++)
{
b[i] = 1;
}
Makefangkuai(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_kuan+3,FrameY + 1);
color(4);
printf("等级: ");
color(12);
printf("%d", tetris->level);
gotoxy(FrameX + 2 * Frame_kuan+3,FrameY + 3);
color(4);
printf("分数: ");
color(12);
printf("%d", tetris->score);
gotoxy(FrameX + 2 * Frame_kuan+3,FrameY + 5);
color(4);
printf("速度: ");
color(12);
printf("%dms", tetris->speed);
}
/*****判断是否可移动*****/
int ifMove(struct fangkuai *tetris)
{
if(a[tetris->x][tetris->y] != 0){ //中心方块处不为空
return 0;
}
else
{
if(//当为田字方块且除中心方块位置外,其他"口"字方块位置上无图案时返回值为1即可移动
( 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==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==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==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==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==17 && ( 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==19 && ( 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 Cleanfangkuai(struct fangkuai *tetris)
{
for(i = 0; i < 4; i++){
b[i] = 0;
}
Makefangkuai(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 fangkuai *tetris)
{
int k, del_rows = 0;
for(j = FrameY+Frame_gao-1; j >= FrameY+1; j--){
k=0;
for(i = FrameX+2; i < FrameX + 2* Frame_kuan - 2; i += 2){ //从左下角开始向右上方遍历
if(a[i][j] == 1){
k++;
if(k == Frame_kuan - 2) //k代表i——横坐标
{
for(k = FrameX + 2; k < FrameX + 2 * Frame_kuan - 2; k += 2)
{
a[k][j] = 0;
gotoxy(k, j);
printf(" "); //删除整行
}
for(k = j-1; k > FrameY; k--) //k代表j——纵坐标
{
for(i = FrameX + 2; i < FrameX + 2 * Frame_kuan-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; //得分
if(del_rows > 0 && (tetris->score % 1000 == 0 || (tetris->score / 1000) > (tetris->level-1)))
{
tetris->speed -= 20;
tetris->level++;
}
}
/*****随机产生方块*****/
void Flag(struct fangkuai *tetris)
{
tetris->number++;
srand(time(NULL)); //初始化随机数
if(tetris->number == 1)
{
tetris->flag == rand()%19+1; //rand产生随机数除取余结果为0~18
}
tetris->next = rand()%19+1;
}
/*******开始游戏********/
void Gamebegin()
{
int n;
struct fangkuai t, *tetris = &t; //定义变量
char ch;
tetris->number = 0; //初始方块数为0
tetris->speed = 300; //初始化速度
tetris->score = 0; //初始得分
tetris->level = 1; //初始等级
while(1)
{
Flag(tetris);
temp = tetris->flag; //temp将下一个方块输入到游戏中
tetris->x = FrameX + 2 * Frame_kuan + 6;
tetris->y = FrameY +10;
tetris->flag = tetris->next;
Printfangkuai(tetris);
tetris->x = FrameX + Frame_kuan;
tetris->y = FrameY -1;
tetris->flag = temp;
//按键操作
while(1) //控制方块变化,直至不再下落
{
label:Printfangkuai(tetris); //打印方块
Sleep(tetris->speed); //延缓时间
Cleanfangkuai(tetris); //清除痕迹
temp1 = tetris->x; //标定中心方块横坐标的值
temp2 = tetris->flag; //记住当前俄罗斯方块的序号
if(kbhit()) //判断是否有键盘输入kbhit
{
ch = getch(); //用ch接收
if((ch == 75) || (ch == 'a' || ch == 'A'))
{
tetris->x-=2; //方向键左或A则向左移动中心横坐标减2
}
if((ch == 77) || (ch == 'd' || ch == 'D'))
{
tetris->x+=2; //方向键右或D则向右移动中心横坐标加2
}
if((ch == 0x28) || (ch == 's' || ch == 'S')) //下键或S则向下加速
{
if(ifMove(tetris) != 0)
{
tetris->y+=2;
}
if(ifMove(tetris) == 0)
{
tetris->y = FrameY + Frame_gao - 2;
}
}
if((ch == 72) || (ch == 'w' || ch == 'W')) //按上键和W改变方块形状
{
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){ //空格,暂停
Printfangkuai(tetris);
while(1)
{
if(kbhit())
{
ch == getch(); //再按,继续游戏
if(ch == 32)
{
goto label;
}
}
}
}
if(ch == 27) //按ESC退出至菜单界面
{
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--;
Printfangkuai(tetris);
Del_fullline(tetris);
break;
}
}
for(i = tetris->y; i < tetris->y+1; 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\n");
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_kuan +6;
tetris->y = FrameY + 10;
Cleanfangkuai(tetris);
}
}
/******重新开始******/
void Replay(struct fangkuai *tetris)
{
system("cls");
memset(a,0,6400*sizeof(int)); //memset——初始化数组数组名数据数组个数*长度)
DrawGameframe();
Gamebegin();
}
/*******规则说明*******/
void explation()
{
int i, j = 1;
system("cls");
color(13);
gotoxy(32,3);
printf("按键说明");
color(2);
for(i == 6; i <= 16; i++) //y轴坐标值
{
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玩家可以通过A、D或左右方向键控制方向");
color(10);
gotoxy(18,9);
printf("tip2通过W或上方向键使方块逆时针旋转");
color(14);
gotoxy(18,11);
printf("tip3通过S或下方向键加速方块下落");
color(11);
gotoxy(18,13);
printf("tip4按空格暂停游戏再按空格继续");
color(4);
gotoxy(18,15);
printf("tip5按ESC退出游戏");
getch(); //按任意键返回主菜单
system("cls");
main();
}
/****退出游戏****/
void close()
{
exit(0);
}
int main(){
title();
welcome();
}
Loading…
Cancel
Save