基于VC++6.0开发俄罗斯方块(三)

游戏主窗体的设计

在欢迎界面选择1之后就会进入游戏主窗体的界面,此界面大致可分为两部分,第一部分是左侧的方块下落界面,另一部分是右侧的得分统计,下次出现的方块和主要的案件说明。
设计思路:
1)首先把游戏主窗体画出来;
2)绘制相应的俄罗斯方块;
3)其他部分;

1.打印输出游戏界面

在这里插入图片描述
为了实现这一个整体框架,如下代码:

/**
 * 制作游戏窗口
 */
void DrwaGameframe()
{
 	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("╚");
 	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;   //标记右竖框为游戏边框,防止方块出界	
    }
}

在这里插入图片描述
形成代码如下:

#include <stdio.h>
#include <time.h>
#include <windows.h>
#include <conio.h>

#define FrameX 13   		//游戏窗口左上角的X轴坐标为13
#define FrameY 3   		//游戏窗口左上角的Y轴坐标为13
#define Frame_height  20 	//游戏窗口的高度为20
#define Frame_width  18 	//游戏窗口的宽度为18


/*******定  义  全  局  变  量 *******/
int i,j,Temp,Temp1,Temp2; 	//temp,temp1,temp2用于记住和转换方块变量的值
//标记游戏屏幕的图案:2,1,0分别表示该位置为游戏边框、方块、无图案;初始化为无图案
int a[80][80]={0};   			
int b[4];     					//标记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;					//控制台句柄


/*******函  数  声  明 *******/
int color(int c);					//设置文字颜色
void gotoxy(int x, int y);				//光标移到指定位置
void title();                       		//欢迎界面上方的标题
void close();                      		//关闭游戏

										
										/**
 * 文字颜色函数      此函数的局限性:1、只能Windows系统下使用   2、不能改变背景颜色
 */
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 DrwaGameframe()
{
 	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("╚");
 	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;   //标记右竖框为游戏边框,防止方块出界	
    }
}

    int main()
    {
        DrwaGameframe();
    	return 0;
    }

2.绘制俄罗斯方块:

首先有下列这五种基本类型:
在这里插入图片描述
另外还有两种镜像图形(原图形变换是得不到的):

在这里插入图片描述
加上这两种镜像图形,俄罗斯方块一共有7种基本类型,然而这7种基本类型旋转之后又会得到不同的旋转图形:
1)田字没有变换;
2)“T”字方块算上本体一共四种变换;
3)"Z"和反“Z”各有两种变换;
4)“7”和反“7”各有四种变换;
5)直线方块有横竖两种变换;

一共有19种类型,这19种类型我们都要考虑!!!
/**
 * 制作俄罗斯方块
 */
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:         /* 顺时针90°T字方块   ■
		  			                         ■■
									           ■*/
   		{
		   	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:         /* 顺时针180°T字方块   ■
		  			                          ■■■*/
   		{
		   	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:         /* 顺时针270°T字方块 ■
		  			                          ■■
									          ■  */
   		{
		   	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:         /* 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 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:        /* 顺时针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(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:        /* 顺时针270°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(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 17:        /* 顺时针转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 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(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;
  	 	}
 	}
}
此段代码还有部分解释:
1.方块是如何画出来的:

在这里插入图片描述
1)我们使用的这个小方块,横向占据两个字符,纵向占据一个字符;
2)我们可以看到这些俄罗斯方块的共同点,都是有四个小方块组成;
3)基于2)我们在全局变量之中定义了数组b[4],用于保存四个小方块的位置;
4)具体如何保存:首先我们保存的是中心小方块的位置,之后基于它来定位;

2.关于我们此处使用到的坐标轴:

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3.设置不同类型方块的颜色

1)因为共有7各大类,我们就可以设置7种颜色,
2)用事先定义好的color函数来设置颜色,将这个函数放在打印方块的前面,那么打印出来的就是已经设置好颜色的方块

4.使用switch分支语句做主体

在这里插入图片描述
注意:
1)switch后面的括号之中的表达式就是要进行判断的条件;
2)当表达式的值与某一个case后面括号里的值相等时,就执行case后面的语句;
3)若没有匹配的就执行default语句

4.打印俄罗斯方块

在上一部分我们知识定义好了俄罗斯方块的大致形状,还并没有选择用什么符号去打印,接下来要做的就是用符号“小方块”组成俄罗斯方块:

/**
 * 打印俄罗斯方块
 */
void PrintTetris(struct Tetris *tetris)
{
 	for(i=0;i<4;i++)					//数组b[4]中有4个元素,循环这4个元素,让每个元素的值都为1
 	{
  		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("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); 			//输出速度
}

实际上在上述代码中不仅打印了方块,还打印了得分信息,速度,等级信息

  • 2
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值