俄罗斯方块(Tetris)

《俄罗斯方块》(Tetris, 俄文:Тетрис)是一款由俄罗斯人阿列克谢·帕基特诺夫于1984年6月发明的休闲游戏。

  我将其作为我课程设计的题目,重温程序设计的基础。由于课设时间有限,本想用OpenGL弄个3D效果的俄罗斯方块,最终借鉴网上已有程序,进行修改编写。借助Easy_X库完成我的课程设计。这也是本人花时间调整的,特在此记录,作为一次经历。并在此提供相关工程,供有需要的朋友借鉴。本人在此声明,该程序有一定借鉴,如有侵权,请联系本人进行删除。

使用前需要安装easy_x的库

  1. 总体设计方案(程序总体框图或流程图)

2.游戏工程目录

3.项目运行结果

由于代码比较长,我将工程上传,有需要者可以前往下载

Tetris.cc
//----------------------------------------------------------------------------
//   Tetris                                                v1.0
//   作者 : yk
//----------------------------------------------------------------------------
//   email:  [email protected]
//----------------------------------------------------------------------------
//   说明:
//     该程序为2019年东北林业大学课程设计。
//   本人仅完成了俄罗斯方块的基本实现。就
//   目前来看,它已经能让我在闲暇之余体味
//   小游戏的妙处,并且该小游戏借助Easy X
//   大大节约了在编写中的繁杂过程。
//   如发现问题请联系我,互相学习交流。
//
//   v1.0 June 2019
//  
//----------------------------------------------------------------------------
#include <iostream>
#include"Game.h"

Game Teris("Tetris ---- yk",832,768);		 //初始化游戏窗口数据
int main()
{
	Teris.Init();							  //初始化游戏参数
	Teris.Primary_Menu_();					  //进入主菜单
	Teris.Game_interface_init_();			  //初始化游戏界面
	Teris.Game_control_init_();               //初始化游戏参数
	while (true)
	{
		Teris.Update_show();                  //刷新屏显
		if (!Teris.Game_active)               //判断游戏状态
		{
			Teris.Primary_Menu_();             //进入主菜单
			Teris.Game_interface_init_();      //初始化游戏界面
			Teris.Game_control_init_();        //初始化游戏参数
		}
	}
	return 0;
}

Game.h
//----------------------------------------------------------------------------
//   Tetris                                                v1.0
//   作者 : yk
//----------------------------------------------------------------------------
//
//   email:  [email protected]
//
//
//----------------------------------------------------------------------------
//   说明:
//     该程序为2019年东北林业大学课程设计。
//   本人仅完成了俄罗斯方块的基本实现。就
//   目前来看,它已经能让我在闲暇之余体味
//   小游戏的妙处,并且该小游戏借助Easy X
//   大大节约了在编写中的繁杂过程。
//   如发现问题请联系我,互相学习交流。
//   
//
//
//   v1.0 June 2019
//  
//----------------------------------------------------------------------------
#ifndef GAME_H
#define GAME_H
#include<graphics.h>
#include<iostream>
#include<time.h>
#include"Tool.h"

class Game
{
public:
	bool Game_active;
	Game(const std::string Title,const int game_width, const int game_height);  
									     //构造游戏类并传入窗口参数
	void Init();					     //初始化游戏的相关参数,及绘图面板
	void Primary_Menu_();			     //实现主菜单的UI和控制
	void Game_interface_init_();	     //初始化游戏界面
	void Game_control_init_();	         //初始化游戏参数
	void Show_Menu_();                  //绘制主菜单
	void Rand_newblock_();              //生成一个随机的方块形状
	void Review_box_show();             //绘制预览面板
	void Active_box_show();			 //绘制游戏主界面
	void Aleady_box_show();             //绘制已存在方块
	void Eliminate_block_full_();       //消除满行方块
	void Update_Block_site();		     //更新方块位置状态
	void Updatewithinput();		     //处理用户输入
	void Update_show();				 //更新绘图
	void Load_resources();              //加载资源数据
	bool Game_over_();                  //绘制结束游戏信息
	bool Block_Down();                  //控制方块下落
	bool Block_Up();                    //控制方块旋转
	bool Block_Left();                  //控制方块左移
	bool Block_Right();				 //控制方块右移
	~Game();

private:
	 int grade = 0;
	 int rank = 30;
	 std::string Rank = "A";

	 DWORD m_oldtime;
	 DWORD newtime = GetTickCount();
	 int width;
	 int height;
	 std::string Title;
	 IMAGE texture[20];
	 Tool tool;
	 int Max_box=19;
	 int wall_WS;
	 int wall_HS;
	 int Block_type_now=14;
	 int Block_type_next=1;
	 int Block_WS=7*2;
	 int Block_HS=11*2;
	 int Block_size = 64;
	 int Active_x = 64;
	 int Active_y = 64;
	 int Choose_x;
	 int Choose_X;
	 int Choose_Y;
	 void Delete_fullblock(int n);
	 void Show_grade();
	 void Show_Aboutgame_();
	 void Show_systime();
};

#endif // !GAME_H
Game.cc
//----------------------------------------------------------------------------
//   Tetris                                                v1.0
//   作者 : yk
//----------------------------------------------------------------------------
//
//   email:  [email protected]
//
//
//----------------------------------------------------------------------------
//   说明:
//     该程序为2019年东北林业大学课程设计。
//   本人仅完成了俄罗斯方块的基本实现。就
//   目前来看,它已经能让我在闲暇之余体味
//   小游戏的妙处,并且该小游戏借助Easy X
//   大大节约了在编写中的繁杂过程。
//   如发现问题请联系我,互相学习交流。
//   
//
//
//   v1.0 June 2019
//  
//----------------------------------------------------------------------------

//-----------------------------------------------------------------------------
//        【游戏中核心算法】
//  使用二进制数对方块形状进行储存
//  1100     即1100 0100 0100 0000
//  0100	 储存为L,在进行移动旋转以及
//  0100     碰撞检测时,用最高位为1的数
//  0000     与其 & 从而得到其形状。
//
//---------------------------------------------------------------------------

#include"Game.h"
#include"Game_properties.h"
#pragma comment(lib,"Winmm.lib")
#define _CRT_SECURE_NO_WARNINGS
#define PI 3.1415926535
#define W_UP		72 		// 方块旋转
#define W_LEFT	    75 		// 方块向左移动
#define W_RIGHT	    77		// 方块向右移动
#define W_DOWN	    80		// 方块向下移动
#define W_ESC		27		// 退出游戏
#define W_ENTER     13
#define W_SPACE     32



//----------------------------------------------------------------------------------------------
//函数声明:Game(const std::string Title,const int game_width, const int game_height)
//函数参数:1.Title --[窗口名字(仅英文)] 2.game_width--[窗口宽度], game_height--[窗口高度]
//函数功能:
//		构造类并获取窗口的属性数据,以便于后续创建一个绘图窗口。
//----------------------------------------------------------------------------------------------
Game::Game(const std::string Title,const int game_width, const int game_height)
{
	this->width = game_width;
	this->height = game_height;
	this->Title = Title;
}


//----------------------------------------------------------------------------------------------
//函数声明:void Init();	
//函数参数:   无
//函数功能:
//		初始化游戏的基本数据。包括加载资源数据,创建绘图窗口,设置游戏参数
//和进入主菜单,准备开始游戏
//----------------------------------------------------------------------------------------------
void Game::Init()
{
	this->Load_resources();	                                        //加载数据
	initgraph(this->width, this->height);					     	//创建绘图窗口
	BeginBatchDraw();												//开始批量绘图,解决绘图中闪烁的问题,但是会增加游戏对CPU的占用
	HWND hwnd = GetHWnd();											//获取窗口句柄,对窗口进行设置
	SetWindowText(hwnd,this->tool.stringToLPCWSTR(this->Title));	//设置窗口标题
	Resize(&this->texture[12], this->width, this->height);			//调整主菜单背景图片与窗口适应
	putimage(0, 0, &this->texture[12]);								//在(0,0)位置进行贴图
	setbkmode(TRANSPARENT);											//设置窗口的属性
	this->Primary_Menu_();										    //进入主菜单
	FlushBatchDraw();												//执行批量绘图操作
	this->wall_WS = ((this->width / 4) * 3) / this->Block_size-1;   //获取绘图窗口的相对位置属性
	this->wall_HS = this->height  / this->Block_size-1;
	this->m_oldtime = this->newtime;                                //设置游戏参数
}

//----------------------------------------------------------------------------------------------
//函数声明:void Primary_Menu_()	
//函数参数:   无
//函数功能:
//		绘制主菜单的界面,并实现对鼠标与键盘操作的监听,
//并且根据鼠标键盘的相关操作,执行相关功能
//----------------------------------------------------------------------------------------------
void Game::Primary_Menu_()
{
	this->Choose_x = 120;
	this->Choose_X = this->Choose_x + 630;											//获取主菜单相对位置属性以便于鼠标,键盘的功能判断
	this->Choose_Y = this->height / 4+100;
	this->Show_Menu_();														//绘制主菜单
	MOUSEMSG m;																		//创建鼠标对象
	while (true)															//循环绘制
	{
		if (_kbhit())														//等待键盘操作
		{
			
			switch (_getch())											      //获取键盘操作内容
			{
			case 'w':
			case 'W':																
			case W_UP:													//上,对主菜单下划线位置进行控制
				{

 				if (this->Choose_Y ==292)											
				{
					this->Choose_Y += 360;
				}
				else if (this->Choose_Y == 412)
				{
					this->Choose_Y -= 120;
				}
				else if (this->Choose_Y == 532)
				{
					this->Choose_Y -= 120;
				}
				else if (this->Choose_Y == 652)
				{
					this->Choose_Y -= 120;
				}
				}
				break;
			case's':
			case'S':
			case W_DOWN:															 //下
				{
				if (this->Choose_Y == 292)
				{
					this->Choose_Y += 120;
				}
				else if (this->Choose_Y == 412)
				{
					this->Choose_Y += 120;
				}
				else if (this->Choose_Y == 532)
				{
					this->Choose_Y += 120;
				}
				else if (this->Choose_Y == 652)
				{
					this->Choose_Y -= 360;
				}
				}
				break;
			case W_ENTER:
			case W_SPACE:												//空格,对功能进行选择执行
			{
				if (this->Choose_Y == 292)
				{
					this->Game_active = true;								      //设置游戏状态
					return;
				}
				else if (this->Choose_Y == 412)
				{
					this->Show_Aboutgame_();									//输出游戏
					this->Show_Menu_();													//绘制主菜单
				}
				else if (this->Choose_Y == 532)
				{
					this->Show_systime();										//绘制时钟
				}
				else if (this->Choose_Y == 652)
				{

					EndBatchDraw();										//结束绘制
					closegraph();											//关闭绘图窗口
					this->~Game();     
					Sleep(100);
					exit(0);												//退出程序
				}
			}break;
			
			case W_ESC:
			{
				EndBatchDraw();											//结束绘制
				closegraph();												//关闭绘图窗口
				this->~Game();
				Sleep(100);
				exit(0);												     //退出程序
			}
			default:
				break;
			}
			this->Show_Menu_();
		}
		if (MouseHit())													       //等待鼠标操作
		{
			m = GetMouseMsg();												 //获取鼠标数据
			switch (m.uMsg)
			{
			case WM_MOUSEMOVE:											//鼠标移动,从而控制下划线移动
			{
				if ((m.y >= 172 && m.y < 292) && (m.x >= 120 && m.x <= 750))
				{
					this->Choose_Y = 292;
				}
				if ((m.y >= 300 && m.y < 412) && (m.x >= 120 && m.x <= 750))
				{
					this->Choose_Y = 412;
				}
				if ((m.y >= 422 && m.y < 532) && (m.x >= 120 && m.x <= 750))
				{
					this->Choose_Y = 532;
				}
				if ((m.y >= 542 && m.y < 652) && (m.x >= 120 && m.x <= 750))
				{
					this->Choose_Y = 652;
				} 
				this->Show_Menu_();										    //绘制主菜单
			}
			break;

			case WM_LBUTTONDOWN:										    //按下左键
			{
				if ((m.y >= 172 && m.y < 292) && (m.x >= 120 && m.x <= 750))
				{
					this->Game_active = true;								   //设置游戏状态
					return;
				}
				if ((m.y >= 300 && m.y < 412) && (m.x >= 120 && m.x <= 750))
				{
					this->Show_Aboutgame_();								    //输出游戏介绍
					this->Show_Menu_();									   //绘制主菜单
				}
				if ((m.y >= 422 && m.y) < 532 && (m.x >= 120 && m.x <= 750))
				{
					this->Show_systime();									  //显示时钟界面
				}
				if ((m.y >= 542 && m.y < 652) && (m.x >= 120 && m.x <= 750))
				{
					EndBatchDraw();								         //终止批量绘图
					closegraph();										  //关闭绘图窗口
					this->~Game();
					Sleep(100);
					exit(0);											  //退出游戏
				}
			}
			break;
			}
			this->Show_Menu_();											 //显示主菜单
		}
		FlushBatchDraw();												 //执行批量绘图
	}
}
//----------------------------------------------------------------------------------------------
//函数声明:void Game_interface_init_();	
//函数参数:   无
//函数功能:
//		初始化游戏界面,并准备开始游戏
//----------------------------------------------------------------------------------------------
void Game::Game_interface_init_()
{
	Resize(&this->texture[8], this->Block_size * (this->wall_WS-1), this->Block_size * this->wall_HS);    //调整贴图尺寸
	Resize(&this->texture[9], this->Block_size * 2, this->Block_size *2);
	for (int i = 0; i <= this->wall_WS; i++)
	{
		putimage(i * this->Block_size, 0, &this->texture[0]);					        //绘制游戏活动区边缘部分
		putimage(i * this->Block_size, this->wall_HS * this->Block_size, &this->texture[0]);
	}
	for (int j = 0; j < this->wall_HS; j++)
	{
		putimage(0, (j + 1) * this->Block_size, &this->texture[0]);
		putimage(this->wall_WS *this->Block_size, (j + 1) * this->Block_size, &this->texture[0]);
	}
	putimage(this->Active_x, this->Active_y, &this->texture[8]);
	this->Show_grade();																				  //显示得分情况
}

//----------------------------------------------------------------------------------------------
//函数声明:void Game_control_init_();	
//函数参数:   无
//函数功能:
//		初始化游戏参数,包括游戏过程中方块的随机产生
//----------------------------------------------------------------------------------------------
void Game::Game_control_init_()
{
	for (int i = 0; i < 22; i++)						//游戏活动区面板范围
	{
		for (int j = 0; j < 14; j++)
		{
			block_site[i][j].state = false;				//初始化相关位置数据
			block_site[i][j].Block_type = 0;
		}
	}
	this->Rand_newblock_();						   //随机产生一个方块
	this->Active_box_show();						   //绘制方块移动面板
	this->Rand_newblock_();    
	this->Review_box_show();						   //预览面板方块位置
	FlushBatchDraw();							    //执行批量绘图
}

//----------------------------------------------------------------------------------------------
//函数声明:void Show_Menu_();	
//函数参数:   无
//函数功能:
//		绘制主菜单UI进行显示
//---------------------------------------------------------------------------------------------- 
void Game::Show_Menu_()
{
	setlinestyle(PS_SOLID, 5);									//设置线宽
	putimage(0, 0, &this->texture[12]);								//绘图
	setcolor(RGB(184, 61, 186));
	tool.Show_text_(100, this->height / 4, "[A] New  Game", 100);				//输出文本
	setcolor(RGB(0, 168, 243));
	tool.Show_text_(100, this->height / 4 + 120, "[B] About Game", 100);
	setcolor(RGB(70, 178, 36));
	tool.Show_text_(100, this->height / 4 + 240, "[C] Time ", 100);
	setcolor(RGB(236, 28, 36));
	tool.Show_text_(100, this->height / 4 + 360, "[D] Exit Game", 100);
	setcolor(RGB(0, 0, 0));
	tool.Show_text_(this->width - 200, this->height - 70, "Author:Yk", 30);
	tool.Show_text_(this->width - 200, this->height - 35, "ID:2017211146", 30);
	line(this->Choose_x, this->Choose_Y, this->Choose_X, this->Choose_Y);       		//绘制直线
}

//----------------------------------------------------------------------------------------------
//函数声明:void Game_over_();	
//函数参数:   无
//函数功能:
//		判断游戏是否结束
//---------------------------------------------------------------------------------------------- 
bool Game::Game_over_()
{
	int i, j, mask, a = 0;
	place_active_next.X = 6;								  //找到要移动到的位置
	place_active_next.Y = 0;															//*------------------------
	for (i = 0; i < 2; i++)									 //  用128 64 32  ....
	{																				    										// 与存储方块数据相与从而判断
		mask = 128;																												//相应位置上的方块存在状态
		for (j = 0; j < 8; j++)								//最后与已存在方块进行比较
		{																													//得出游戏是否结束状态
			if (j % 4 == 0 && j != 0) {													//*-------------------------
				place_active_next.Y++; 
				place_active_next.X = 0;
			}
			if (form[this->Block_type_now].box[i] & mask)			//判断相应位置上方块存在状态
			{
				if (block_site[place_active_next.Y][place_active_next.X].state == 1)	//判断已存在方块的状态确定是否占用
				{
					putimage(0, 0, &this->texture[10]);
					FlushBatchDraw();
					return true;
				}																												//底板有位置已占用游戏结束	  
			}
			mask = mask / 2;
		}
		place_active_next.Y++;
	}
	return false;
}

//----------------------------------------------------------------------------------------------
//函数声明:void Rand_newblock_();	
//函数参数:   无
//函数功能:
//		随机生成一个随机形状的方块
//---------------------------------------------------------------------------------------------- 
void Game::Rand_newblock_()
{
	this->Block_type_now = this->Block_type_next;
	srand((unsigned)time(NULL));												//产生随机时间种子
	this->Block_type_next = rand() % this->Max_box;									//产生随机形状的方块
	place_active_now.X = 6;																//设置生成方块的出现位置
	place_active_now.Y =0;
}

//----------------------------------------------------------------------------------------------
//函数声明:void Review_box_show();	
//函数参数:   无
//函数功能:
//		绘制预览面板,显示之后的方块
//---------------------------------------------------------------------------------------------- 
void Game::Review_box_show()
{
	putimage(this->Block_size * (this->wall_WS + 1), 0, &this->texture[9]);				//显示基础背景图
	putimage(this->Block_size * (this->wall_WS + 3), 0, &this->texture[9]);
	putimage(this->Block_size * (this->wall_WS + 1), this->Block_size*2, &this->texture[9]);
	putimage(this->Block_size * (this->wall_WS + 3), this->Block_size * 2, &this->texture[9]);
	place.X = this->Block_size * (this->wall_WS+2)+32;
	place.Y = 64;
	int mask=0,x= place.X,y= place.Y;
	for (int i = 0; i < 2; i++)
	{
		mask = 128;
		for (int j = 0; j < 8; j++)
		{
			if (j % 4 == 0 && j != 0)
			{
				y += 32;
				x = place.X;
			}
			if (form[this->Block_type_next].box[i] & mask)					//依据相应位置的方块存在类型与状态,绘制相应图案
			{
				putimage(x, y, &this->texture[form[this->Block_type_next].type]);		//绘制图案
			}
			x += 32;
			mask /= 2;
		}
		x = place.X;
		y += 32;
	}
}

//----------------------------------------------------------------------------------------------
//函数声明:void Active_box_show();	
//函数参数:   无
//函数功能:
//		绘制游戏活动区,在相关位置绘制游戏活动界面
//---------------------------------------------------------------------------------------------- 
void Game::Active_box_show()
{
	
	int mask = 0, x = 0, y = 0;
	x = place_active_now.X;
	y = place_active_now.Y;
	
	if (this->Block_type_now >= 0 && this->Block_type_now < this->Max_box)						//判断方块是否在指定位置
	{
		for (int i = 0; i < 2; i++)
		{
			mask = 128;
			for (int j = 0; j < 8; j++)
			{
				if (j % 4 == 0 && j != 0)
				{
					y++;
					x = place_active_now.X;
				}
				if (form[this->Block_type_now].box[i] & mask)										//确定方块形状
				{
					putimage(this->Active_x+x*32,this->Active_y+y*32, &this->texture[form[this->Block_type_now].type]);
				}
				x++;
				mask /= 2;
			}
			x = place_active_now.X;
			y++;
		}
	}
}

//----------------------------------------------------------------------------------------------
//函数声明:void Aleady_box_show();	
//函数参数:   无
//函数功能:
//		 绘制已经存在的方块
//---------------------------------------------------------------------------------------------- 
void Game::Aleady_box_show()
{
	for (int i = 0; i < 22; i++)
		for (int j = 0; j < 14; j++)                                   //游戏活动区范围
			if (block_site[i][j].state == 1)
				putimage((2 + j) *(this->Block_size / 2), (2 + i) * (this->Block_size / 2), &this->texture[block_site[i][j].Block_type]);
										  //在指定区域绘制方块
}


//----------------------------------------------------------------------------------------------
//函数声明:void Eliminate_block_full_();	
//函数参数:   无
//函数功能:
//		判断是否满行,从而对满行进行消除
//---------------------------------------------------------------------------------------------- 
void Game::Eliminate_block_full_()
{
	int m, n, top;
	n = place_active_now.Y + 3;						//判断是否超过活动区范围
	top = place_active_now.Y;
	for (; n >= top;)
	{
		if (n < 0 || n >= 22) 
		{
			n--; 
			continue;
		}
		for (m = 0; m < 14; m++)
		{
			if (block_site[n][m].state == 0)
			{
				n--;

				break;
			}
			if (m == 13) 
			{	
				this->Delete_fullblock(n);		//消除满行
				this->grade++;
				if (this->grade >= 10)			//大于10分则提升等级
					this->Rank = "B";
				if (this->grade >= 20)
					this->Rank = "C";
				this->Show_grade();				//显示得分等级情况
			}
		}
	}
}

//----------------------------------------------------------------------------------------------
//函数声明:void Update_Block_site();	
//函数参数:   无
//函数功能:
//		更新相关位置上方块状态情况
//---------------------------------------------------------------------------------------------- 
void Game::Update_Block_site()
{
	int mask, x = place_active_now.X, y = place_active_now.Y;
	for (int i = 0; i < 2; i++)
	{
		mask = 128;
		for (int j = 0; j < 8; j++)
		{
			if (j % 4 == 0 && j != 0) 
			{
				y++;
				x = place_active_now.X;
			}
			if (form[Block_type_now].box[i] & mask)							//判断方块形状,并更新位置状态
			{
				block_site[y][x].Block_type = form[Block_type_now].type;
				block_site[y][x].state = 1;
			}
			x++;
			mask /= 2;
		}
		x = place_active_now.X;
		y++;
	}
}

//----------------------------------------------------------------------------------------------
//函数声明:void Updatewithinput();	
//函数参数:   无
//函数功能:
//		处理用户键入,此处未加入鼠标功能,但可以加入并进行抽象
//---------------------------------------------------------------------------------------------- 
void Game::Updatewithinput()
{
	char c;
	c = _getch();
	switch (c)
	{
	case 'w':
	case 'W':
	case W_UP:
		if (this->Block_Up())												//上,旋转
		{
			this->Block_type_now = form[this->Block_type_now].next;						//改变方块形状
		}
		break;
	case 's':
	case 'S':
	case W_DOWN:
		if (this->Block_Down())											//下,向下移动
		{
			place_active_now.Y++;

		}
		break;
	case 'a':
	case 'A':
	case W_LEFT:
		if (this->Block_Left())												//左移动
		{
			place_active_now.X--;
		}
		break;
	case 'd':
	case 'D':
	case W_RIGHT:
		if (this->Block_Right())												//右移动
		{
			place_active_now.X++;
		}
		break;
	case W_ESC:
		this->Game_active = false;											//改变游戏状态
	default:
		break;
	}
}

//----------------------------------------------------------------------------------------------
//函数声明:void Update_show();	
//函数参数:   无
//函数功能:
//		更新游戏活动区绘图
//---------------------------------------------------------------------------------------------- 
void Game::Update_show()
{
	

	
		if(_kbhit())this->Updatewithinput();					//处理用户输入
		newtime = GetTickCount();						//获取系统时间
		DWORD t = (600 - this->rank* (this->grade));			       //干预方块下落的速度
		if (newtime - m_oldtime >= t)
		{
			m_oldtime = newtime;
			if (this->Block_Down())					//方块下落
				place_active_now.Y++;
			else
			{

				this->Update_Block_site();					//更新方块状态信息
				this->Eliminate_block_full_();					//消除满行
				this->Rand_newblock_();					//产生新的方块形状
				this->Review_box_show();					//预览面板方块绘制
			}
		}
		putimage(this->Active_x, this->Active_y, &this->texture[8]);
		this->Aleady_box_show();							//绘制已有的方块
		this->Active_box_show();							//运动中的方块绘制
		FlushBatchDraw();								//批量绘图
		if (this->Game_over_())							//判断游戏是否结束
		{
			Sleep(150);
			system("pause");
			this->Game_active = false;

		}
		


}

//----------------------------------------------------------------------------------------------
//函数声明:void Load_resources();	
//函数参数:   无
//函数功能:
//		加载资源数据
//---------------------------------------------------------------------------------------------- 
void Game::Load_resources()
{
	loadimage(&this->texture[0], _T("resources\\T_bo.jpg"));	//加载图片
	loadimage(&this->texture[1], _T("resources\\Type_A.jpg"));
	loadimage(&this->texture[2], _T("resources\\Type_B.jpg"));
	loadimage(&this->texture[3], _T("resources\\Type_C.jpg"));
	loadimage(&this->texture[4], _T("resources\\Type_D.jpg"));
	loadimage(&this->texture[5], _T("resources\\Type_E.jpg"));
	loadimage(&this->texture[6], _T("resources\\Type_F.jpg"));
	loadimage(&this->texture[7], _T("resources\\Type_G.jpg"));
	loadimage(&this->texture[8], _T("resources\\background.jpg"));
	loadimage(&this->texture[9], _T("resources\\preview.jpg"));
	loadimage(&this->texture[10], _T("resources\\Game.jpg"));
	loadimage(&this->texture[11], _T("resources\\next.jpg"));
	loadimage(&this->texture[12], _T("resources\\start.jpg"));
	loadimage(&this->texture[13], _T("resources\\grade_A.jpg"));
	loadimage(&this->texture[14], _T("resources\\grade_B.jpg"));
	loadimage(&this->texture[15], _T("resources\\grade_C.jpg"));
	loadimage(&this->texture[16], _T("resources\\time.jpg"));
}

//----------------------------------------------------------------------------------------------
//函数声明:void Block_Down();	
//函数参数:   无
//函数功能:
//		控制方块向下移动
//---------------------------------------------------------------------------------------------- 
bool Game::Block_Down()
{

		int i, io, save_x, mask;
		place_active_next.X = place_active_now.X;		//找到要移动到的位置
		place_active_next.Y = place_active_now.Y;
		if (place_active_next.Y == 21)				//判断是否到底部
		{
			return FALSE;

		}
		else if (place_active_next.Y == 20)			//判断特定形状是否会超出游戏边界
		{
			if (this->Block_type_now == 17)
			
				if (block_site[place_active_next.Y+1][place_active_next.X].state == 0 && block_site[place_active_next.Y+1][place_active_next.X + 1].state== 0 &&
					block_site[place_active_next.Y + 1][place_active_next.X + 2].state == 0 && block_site[place_active_next.Y +1][place_active_next.X + 3].state == 0)
					return TRUE;
				else return FALSE;
			}
			return FALSE;

		}
		else if (place_active_next.Y == 19)
		{
			mask = 128;
			for (int k = 0; k < 4; k++) {
				if (form[this->Block_type_now].box[1] & mask) {
					return FALSE;
				}
				else mask = mask / (2);
			}
		}
		else if (place_active_next.Y == 18)
		{
			mask = 8;
			for (int k = 0; k < 4; k++) {
				if (form[this->Block_type_now].box[1] & mask) {
					return FALSE;
				}
				else mask = mask / (2);
			}
		}
		place_active_next.Y++;
		save_x = place_active_next.X;						//向下移动合理的方块
		if (this->Block_type_now >= 0 && this->Block_type_now < this->Max_box)
		{
			for (io = 0; io < 2; io++)
			{
				mask = 128;
				for (i = 0; i < 8; i++)
				{
					if (i % 4 == 0 && i != 0) {
						place_active_next.Y++;

						place_active_next.X = save_x;
					}
					if (form[this->Block_type_now].box[io] & mask)
					{
						if (block_site[place_active_next.Y][place_active_next.X].state == 1) 
{
							return FALSE;
						}						//底板有位置已占用,不能移动
					}
					place_active_next.X++;		
					mask = mask / (2);
				}
				place_active_next.X = save_x;	
				place_active_next.Y++;
			}
			return TRUE;
		}
		return FALSE;

	
}

//----------------------------------------------------------------------------------------------
//函数声明:void Block_Up();	
//函数参数:   无
//函数功能:
//		控制方块旋转
//---------------------------------------------------------------------------------------------- 
bool Game::Block_Up()
{
	int i, io, save_x, mask;
	place_active_next.X = place_active_now.X;							//找到要移动到的位置
	place_active_next.Y = place_active_now.Y;
	save_x = place_active_next.X;

	if (place_active_next.X < 11)									//当方块在底板内部时
	{
		if (place_active_next.Y < 19)
		{
			if (this->Block_type_now >= 0 && this->Block_type_now < this->Max_box)
			{
				for (io = 0; io < 2; io++)
				{
					mask = 128;
					for (i = 0; i < 8; i++)
					{
						if (i % 4 == 0 && i != 0) {

							place_active_next.Y++;
							place_active_next.X = save_x;
						}							 //获取相关形状的位置状态
						if (form[form[this->Block_type_now].next].box[io] & mask)
						{
							if (block_site[place_active_next.Y][place_active_next.X + i % 4].state == 1) {
								return FALSE;	
							}					//底板有位置已占用,不能移动
						}
						mask = mask / (2);
					}
					place_active_next.Y++;
				}
			}
			return TRUE;	
		}
		else if (place_active_next.Y == 19)
		{
			mask = 8;
			for (int k = 0; k < 4; k++)
			{
				if (form[form[this->Block_type_now].next].box[1] & mask)

				{
					return FALSE;	
				}
				else mask = mask / (2);
			}
			if (this->Block_type_now >= 0 && this->Block_type_now < this->Max_box)
			{
				for (io = 0; io < 2; io++)
				{
					mask = 128;
					for (i = 0; i < 8; i++)
					{
						if (i % 4 == 0 && i != 0) {

							place_active_next.Y++; 
							place_active_next.X = save_x;
						}
						if (form[form[this->Block_type_now].next].box[io] & mask)
						{
							if (block_site[place_active_next.Y][place_active_next.X + i % 4].state == 1) {
								return FALSE;	
							}					//底板有位置已占用,不能移动
						}
						mask = mask / (2);
					}
					place_active_next.Y++;
				}
			}
			return TRUE;	
		}
		else if (place_active_next.Y > 19)
		{ 
			return FALSE;	
		}
	}
	else if (place_active_next.X == 11)						     //当方块在底板右边界时
	{
		if (place_active_next.Y < 19)
		{
			if ((form[form[this->Block_type_now].next].box[0] & 16) || 
				(form[form[this->Block_type_now].next].box[0] & 1) ||
				(form[form[this->Block_type_now].next].box[1] & 16) ||
				(form[form[this->Block_type_now].next].box[1] & 1))
			{
				return FALSE;			
			}
			else
				if (this->Block_type_now >= 0 && this->Block_type_now < this->Max_box)
				{
					for (io = 0; io < 2; io++)
					{
						mask = 128;
						for (i = 0; i < 8; i++)
						{
							if (i % 4 == 0 && i != 0) {

								place_active_next.Y++;
								place_active_next.X = save_x;
							}
							if (form[form[this->Block_type_now].next].box[io] & mask)
							{
								if (block_site[place_active_next.Y][place_active_next.X + i % 4].state == 1)
								{
									return FALSE;	
								}			//底板有位置已占用,不能移动
							}
							mask = mask / (2);
						}
						place_active_next.Y++;
					}
				}
			return TRUE;	
		}
		else if (place_active_next.Y == 19)
		{
			if ((form[form[this->Block_type_now].next].box[0] & 16) || 
				(form[form[this->Block_type_now].next].box[0] & 1) ||
				(form[form[this->Block_type_now].next].box[1] & 16) ||
			    (form[form[this->Block_type_now].next].box[1] & 1) ||
				(form[form[this->Block_type_now].next].box[1] & 8) ||
				(form[form[this->Block_type_now].next].box[1] & 4) ||
				(form[form[this->Block_type_now].next].box[1] & 2))
			{
				return FALSE;			
			}
			else
				if (this->Block_type_now >= 0 && this->Block_type_now < this->Max_box)
				{
					for (io = 0; io < 2; io++)
					{
						mask = 128;
						for (i = 0; i < 8; i++)
						{
							if (i % 4 == 0 && i != 0) {

								place_active_next.Y++;
								place_active_next.X = save_x;
							}
							if (form[form[this->Block_type_now].next].box[io] & mask)
							{
								if (block_site[place_active_next.Y][place_active_next.X + i % 4].state == 1) {
									return FALSE;	
								}				//底板有位置已占用,不能移动
							}
							mask = mask / (2);
						}
						place_active_next.Y++;
					}
				}
			return TRUE;	
		}
		else
		{ 
			return FALSE;			
		}
	}
	return FALSE;
}

//----------------------------------------------------------------------------------------------
//函数声明:void Block_Up();	
//函数参数:   无
//函数功能:
//		控制方块左移
//---------------------------------------------------------------------------------------------- 
bool Game::Block_Left()
{
	int i, io, save_x, mask;
	place_active_next.X = place_active_now.X;						//找到要移动到的位置
	place_active_next.Y = place_active_now.Y;
	if (place_active_next.X == 0) 
	{ 
		return FALSE;	
	}
	place_active_next.X = place_active_now.X - 1;
	place_active_next.Y = place_active_now.Y;
	save_x = place_active_next.X;
	if (this->Block_type_now >= 0 && this->Block_type_now < this->Max_box)		//判断形状的正确性
	{
		for (io = 0; io < 2; io++)
		{
			mask = 128;
			for (i = 0; i < 8; i++)
			{
				if (i % 4 == 0 && i != 0) {
					place_active_next.Y++;

					place_active_next.X = save_x;
				}
				if (form[this->Block_type_now].box[io] & mask)
				{
					if (block_site[place_active_next.Y][place_active_next.X + i % 4].state== 1)
					{
						return FALSE;	
					}						  //底板有位置已占用,不能移动
				}
				mask = mask / (2);
			}
			place_active_next.Y++;
		}
		return TRUE; 
	}
	return FALSE;
}

//----------------------------------------------------------------------------------------------
//函数声明:void Block_Up();	
//函数参数:   无
//函数功能:
//		控制方块右移
//---------------------------------------------------------------------------------------------- 
bool Game::Block_Right()
{
	int i, io, save_x, mask;
	place_active_next.X = place_active_now.X;				//找到要移动到的位置
	place_active_next.Y = place_active_now.Y;
	if (place_active_next.X == 13) 
	{ 
		return FALSE;	
	}
	else if (place_active_next.X == 12)
	{
		if (this->Block_type_now == 16) 
		{
			return TRUE;	
		}
		else 
		{ 
			return FALSE;	
		}
	}
	else if (place_active_next.X == 11)						//找到右边界避免相关形状越界
	{
		if ((form[this->Block_type_now].box[0] & 32) || (form[this->Block_type_now].box[0] & 2)||
			(form[this->Block_type_now].box[1] & 32) || (form[this->Block_type_now].box[1] & 2)) 
		{
			return FALSE;
		}
		else 
		{ 
			return TRUE; 
		}
	}
	else if (place_active_next.X == 10)
	{
		if ((form[this->Block_type_now].box[0] & 16) || (form[this->Block_type_now].box[0] & 1)|| 
			(form[this->Block_type_now].box[1] & 16) || (form[this->Block_type_now].box[1] & 1)) 
		{
			return FALSE;
		}
		else
		{
			place_active_next.X++;
			save_x = place_active_next.X;

			if (this->Block_type_now >= 0 && this->Block_type_now < this->Max_box)
			{
				for (io = 0; io < 2; io++)
				{
					mask = 128;
					for (i = 0; i < 8; i++)
					{
						if (i % 4 == 0 && i != 0) {

							place_active_next.Y++;
							place_active_next.X = save_x;
						}
						if (form[this->Block_type_now].box[io] &mask)
						{
							if (block_site[place_active_next.Y][place_active_next.X + i % 4].state == 1)
							{
								return FALSE;	
							}				//底板有位置已占用,不能移动
						}
						mask = mask / (2);
					}
					place_active_next.Y++;
				}
				return TRUE; 
			}
		}
	}
	place_active_next.X = place_active_now.X + 1;
	place_active_next.Y = place_active_now.Y;
	save_x = place_active_next.X;
	if (this->Block_type_now >= 0 && this->Block_type_now < this->Max_box)
	{
		for (io = 0; io < 2; io++)
		{
			mask = 128;
			for (i = 0; i < 8; i++)
			{
				if (i % 4 == 0 && i != 0) {
					place_active_next.Y++;

					place_active_next.X = save_x;
				}
				if (form[this->Block_type_now].box[io] & mask)
				{
					if (block_site[place_active_next.Y][place_active_next.X + i % 4].state == 1) {
						return FALSE;	
					}			//底板有位置已占用,不能移动
				}
				mask = mask / (2);
			}
			place_active_next.Y++;
		}
		return TRUE; 
	}
	return FALSE;
}

//----------------------------------------------------------------------------------------------
//函数声明:~Game();	
//函数参数:   无
//函数功能:
//		析构函数
//---------------------------------------------------------------------------------------------- 
Game::~Game()
{
}

//----------------------------------------------------------------------------------------------
//函数声明:void Delete_fullblock(int n);	
//函数参数:   n- 行宽
//函数功能:
//		判断是否满行,满行则消除
//---------------------------------------------------------------------------------------------- 
void Game::Delete_fullblock(int n)
{
	for (int e = 0; e < 14; e++) 
	{
		block_site[n][e].state = 0;
	}
	for (; n >= 0; n--)
		for (int m = 0; m < 14; m++)		
			if (n > 0)
			{
				block_site[n][m].state = block_site[n-1][m].state;
				block_site[n][m].Block_type = block_site[n - 1][m].Block_type;
			}
}

//----------------------------------------------------------------------------------------------
//函数声明:void Show_grade( );	
//函数参数:  无
//函数功能:
//		显示得分情况及游戏等级
//---------------------------------------------------------------------------------------------- 
void Game::Show_grade()        
{
	if (this->Rank[0] == 'A')			//依据等级设置等级参数
	{
		putimage(this->Block_size * (this->wall_WS + 1), this->Block_size * 4, &this->texture[13]);
		this->rank = 30;
	}
	else if (this->Rank[0] == 'B')
	{
		putimage(this->Block_size * (this->wall_WS + 1), this->Block_size * 4, &this->texture[14]);
		this->rank = 40;
	}
	else if (this->Rank[0] == 'C')
	{
		putimage(this->Block_size * (this->wall_WS + 1), this->Block_size * 4, &this->texture[15]);
		this->rank = 50;
	}
	std::string str;
	char s[20];
	sprintf_s(s, "%d", this->grade);	//在指定位置绘制分数情况
	str = s;
	tool.Show_text_(this->Block_size * (this->wall_WS + 1) + 100, this->Block_size * 4 + 10, str, 40);
	tool.Show_text_(this->Block_size * (this->wall_WS + 1) + 100, this->Block_size * 4 + 60, this->Rank, 40);
}

//----------------------------------------------------------------------------------------------
//函数声明:void Show_Aboutgame_( );	
//函数参数:  无
//函数功能:
//		显示游戏介绍情况
//---------------------------------------------------------------------------------------------- 
void Game::Show_Aboutgame_()			
{
	putimage(0, 0, &this->texture[11]);
	FlushBatchDraw();
	system("pause");
}

//----------------------------------------------------------------------------------------------
//函数声明:void Show_systime( );	
//函数参数:  无
//函数功能:
//		绘制系统时钟,显示系统时间,此处借鉴他人代码
//---------------------------------------------------------------------------------------------- 
void Game::Show_systime()        
{
	int center_x, center_y;						  // 中心点的坐标,也是表的中心
	center_x = this->width / 2;
	center_y = this->height / 2;
	int secondLength = this->width / 5;           // 秒针的长度
	int minuteLength = this->width / 6;           // 分针的长度
	int hourLength = this->width / 7;             // 时针的长度
	int secondEnd_x, secondEnd_y;			// 秒针的终点
	int minuteEnd_x, minuteEnd_y;		      // 分针的终点
	int hourEnd_x, hourEnd_y;			// 时针的终点
	float secondAngle;				// 秒钟对应的角度
	float minuteAngle;				// 分钟对应的角度
	float hourAngle;				 // 时钟对应的角度

	SYSTEMTIME ti;				 // 定义变量保存当前时间
	while (true)
	{
		if (_kbhit())
		{
			_getch();
			return;
		}
		putimage(0, 0, &this->texture[16]);
							// 绘制一个简单的表盘
		setlinestyle(PS_SOLID, 1);
		setcolor(WHITE);
		circle(center_x, center_y, this->width / 4);
							 // 画刻度
		int x, y, i;
		for (i = 0; i < 60; i++)
		{
			x = center_x + int(this->width / 4.3 * sin(PI * 2 * i / 60));
			y = center_y + int(this->width / 4.3 * cos(PI * 2 * i / 60));

			if (i % 15 == 0)
				bar(x - 5, y - 5, x + 5, y + 5);
			else if (i % 5 == 0)
				circle(x, y, 3);
			else
				putpixel(x, y, WHITE);
		}
		GetLocalTime(&ti);				// 获取当前时间
								// 秒钟角度变化
		secondAngle = ti.wSecond * 2 * PI / 60;      // 一圈一共2*PI,一圈60秒,一秒钟秒钟走过的角度为2*PI/60
							      // 分钟角度变化
		minuteAngle = ti.wMinute * 2 * PI / 60 + secondAngle / 60;  
							     // 一圈一共2*PI,一圈60分,一分钟分钟走过的角度为2*PI/60
							     // 时钟角度变化
		hourAngle = ti.wHour * 2 * PI / 12 + minuteAngle / 12;  
							     // 一圈一共2*PI,一圈12小时,一小时时钟走过的角度为2*PI/12		
							     // 由角度决定的秒针端点坐标
		secondEnd_x = center_x + secondLength * sin(secondAngle);
		secondEnd_y = center_y - secondLength * cos(secondAngle);
							    // 由角度决定的分针端点坐标
		minuteEnd_x = center_x + minuteLength * sin(minuteAngle);
		minuteEnd_y = center_y - minuteLength * cos(minuteAngle);
							   // 由角度决定的时针端点坐标
		hourEnd_x = center_x + hourLength * sin(hourAngle);
		hourEnd_y = center_y - hourLength * cos(hourAngle);
		setlinestyle(PS_SOLID, 2);
		setcolor(YELLOW);
		line(center_x, center_y, secondEnd_x, secondEnd_y); 
							  // 画秒针
		setlinestyle(PS_SOLID, 5);
		setcolor(BLUE);
		line(center_x, center_y, minuteEnd_x, minuteEnd_y);
							 // 画分针
		setlinestyle(PS_SOLID, 10);
		setcolor(RED);
		line(center_x, center_y, hourEnd_x, hourEnd_y);
							// 画时针
		FlushBatchDraw();
		Sleep(10);
	}
} 
Tool.h
//----------------------------------------------------------------------------
//   Tetris                                                v1.0
//   作者 : yk
//----------------------------------------------------------------------------
//
//   email:  [email protected]
//
//
//----------------------------------------------------------------------------
//   说明:
//     该程序为2019年东北林业大学课程设计。
//   本人仅完成了俄罗斯方块的基本实现。就
//   目前来看,它已经能让我在闲暇之余体味
//   小游戏的妙处,并且该小游戏借助Easy X
//   大大节约了在编写中的繁杂过程。
//   如发现问题请联系我,互相学习交流。
//   
//
//
//   v1.0 June 2019
//  
//----------------------------------------------------------------------------
#ifndef TOOL_H
#define TOOL_H
#include<windows.h>
#include<iostream>
#include <conio.h>
class Tool
{
public:
	LPCWSTR stringToLPCWSTR(std::string orig);       //格式转换
	void Show_text_(const int x, const int y, const std::string text, const int LfHeight, const int Lfwidth=0, const std::string mode="黑体");
	char ProcessInput();
private:	
};
#endif // TOOL_H



Tool.cc
//----------------------------------------------------------------------------
//   Tetris                                                v1.0
//   作者 : yk
//----------------------------------------------------------------------------
//
//   email:  [email protected]
//
//
//----------------------------------------------------------------------------
//   说明:
//     该程序为2019年东北林业大学课程设计。
//   本人仅完成了俄罗斯方块的基本实现。就
//   目前来看,它已经能让我在闲暇之余体味
//   小游戏的妙处,并且该小游戏借助Easy X
//   大大节约了在编写中的繁杂过程。
//   如发现问题请联系我,互相学习交流。
//   
//
//
//   v1.0 June 2019
//  
//----------------------------------------------------------------------------
#include "Tool.h"
#include<graphics.h>
#include<Windows.h>

//----------------------------------------------------------------------------------------------
//函数声明:LPCWSTR stringToLPCWSTR(std::string orig);	
//函数参数:   orig-需要转换的字符串
//函数功能:
//		格式转换
//---------------------------------------------------------------------------------------------- 
LPCWSTR Tool::stringToLPCWSTR(std::string orig)
{
	
		wchar_t* wcstring = 0;
		try
		{
			size_t origsize = orig.length() + 1;
			const size_t newsize = 100;
			size_t convertedChars = 0;
			if (orig == "")
			{
				wcstring = (wchar_t*)malloc(0);
				mbstowcs_s(&convertedChars, wcstring, origsize, orig.c_str(), _TRUNCATE);
			}
			else
			{
				wcstring = (wchar_t*)malloc(sizeof(wchar_t) * (orig.length() - 1));
				mbstowcs_s(&convertedChars, wcstring, origsize, orig.c_str(), _TRUNCATE);
			}
		}
		catch (std::exception e)
		{
		}
		return wcstring;
	
}

//----------------------------------------------------------------------------------------------
//函数声明:void Show_text_(const int x, const int y, const std::string text,const int LfHeight,const int Lfwidth, const std::string mode);	
//函数参数:   位置及内容还有格式
//函数功能:
//		在指定位置以特定形式显示字符串
//---------------------------------------------------------------------------------------------- 
void Tool::Show_text_(const int x, const int y, const std::string text,const int LfHeight,const int Lfwidth, const std::string mode)
{
	LOGFONT f;
	gettextstyle(&f);                                        // 获取当前字体设置
	f.lfHeight = LfHeight;                                   // 设置字体高度为 48
	_tcscpy_s(f.lfFaceName, this->stringToLPCWSTR(mode));    // 设置字体为“黑体”(高版本 VC 推荐使用 _tcscpy_s 函数)
	f.lfQuality = ANTIALIASED_QUALITY;                       // 设置输出效果为抗锯齿  
	settextstyle(&f);                                        // 设置字体样式
	outtextxy(x, y,this->stringToLPCWSTR(text));
}

//----------------------------------------------------------------------------------------------
//函数声明:char ProcessInput();	
//函数参数:   无
//函数功能:
//		获取用户输入情况
//---------------------------------------------------------------------------------------------- 
char Tool::ProcessInput()
{

	if (_kbhit())			//监听键盘输入
	{
		return _getch();
	}
	return NULL;
}
Game_properties.h

//----------------------------------------------------------------------------
//   Tetris                                                v1.0
//   作者 : yk
//----------------------------------------------------------------------------
//
//   email:  [email protected]
//
//
//----------------------------------------------------------------------------
//   说明:
//     该程序为2019年东北林业大学课程设计。
//   本人仅完成了俄罗斯方块的基本实现。就
//   目前来看,它已经能让我在闲暇之余体味
//   小游戏的妙处,并且该小游戏借助Easy X
//   大大节约了在编写中的繁杂过程。
//   如发现问题请联系我,互相学习交流。
//   
//
//
//   v1.0 June 2019
//  
//----------------------------------------------------------------------------
#ifndef GAME_PROPERTIES_H
#define GAME_PROPERTIES_H

//判断游戏坐标下方块存在的状态
struct Block_site
{
	bool state;         //状态,有方块为true 无则false
	short Block_type;   //方块类型
}block_site[22][14];;


enum Square_Type                  		// 定义七种方块色型
{
	Type_A = 1, Type_B, Type_C, Type_D, Type_E, Type_F, Type_G
};

struct Place_active					// 方块在底板中的位置。
{
	short X;						// 保存x坐标。
	short Y;						// 保存y坐标。
}place_active_now = { 3, 0 }, place_active_next;

struct Place_review                 //预览方块的位置
{
	short X;
	short Y;

}place;

struct Form					//方块的形状
{
	int  box[2];				// 每一个数组表示方块两行
	int  type;					//每个方块的类型
	int  next;					//下一个方块的编号
}form[] =			
{
	{ 0x88, 0xc0, Type_A, 1 },//L
	{ 0xe8, 0x0, Type_A, 2 },
	{ 0xc4, 0x40, Type_A, 3 },
	{ 0x2e, 0x0, Type_A, 0 },

	{ 0x44, 0xc0, Type_B, 5 },//L
	{ 0x8e, 0x0, Type_B, 6 },
	{ 0xc8, 0x80, Type_B, 7 },
	{ 0xe2, 0x0, Type_B, 4 },

	{ 0x8c, 0x40, Type_C, 9 },
	{ 0x6c, 0x0, Type_C, 8 },
	{ 0x4c, 0x80, Type_D, 11 },//z
	{ 0xc6, 0x0, Type_D, 10 },

	{ 0x4e, 0x0, Type_E, 13 },//山
	{ 0x8c, 0x80, Type_E, 14 },
	{ 0xe4, 0x0, Type_E, 15 },
	{ 0x4c, 0x40, Type_E, 12 },

	{ 0x88, 0x88, Type_F, 17 },//I
	{ 0xf0, 0x0, Type_F, 16 },

	{ 0xCC, 0x0, Type_G, 18 },//田
};


#endif // !GAME_PROPERTIES_H



发布了29 篇原创文章 · 获赞 24 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/yyk219/article/details/99172515