联机版俄罗斯方块带自动挂机源码

这是一款联机版俄罗斯方块游戏。共配置了13种方块。支持ai挂机功能。双人比赛,右下角显示对手的进度。

每消除一行,会给对手投递一个停滞蛛网,暂停对手的进度。连续消除多行时,投递停滞蛛网 + 快进,停滞1秒后跟着有1秒快进。

ai挂机功能使用的算法是遍历方块的旋转和位置,找出最佳着陆点。挂机算法还有一些可改进的地方,比如没考虑快满时来不及变换的情况,没考虑绕过阻挡后横移消除,没考虑同nextbar的配合。

停滞蛛网飞到右下角(对手右下角消除时飞出停滞蛛网)暂时用图片代替,也可以做成3D特效。

 玩家类:


#ifndef Tetris_h__
#define Tetris_h__


#include "Math/MathLib.h"
#include "Render/Texture.h"

#define BlockNumW 10
#define BlockNumH 20

//条块类型
struct BlockBarStyle 
{
public:
	BlockBarStyle();
	BlockBarStyle(int l, char *str);

	//rot旋转下 xy位置是否实心
	char IsSolid(int x, int y, int rot);

	static const int MaxRot = 4;
	int  m_rotNum;
	int  m_barSize;
	char m_mask[MaxRot][4][4];
	int  ID;

#define MaxBlockColor 12
	static Color colors[MaxBlockColor]; 
};

#define BlockStyleNum 14
extern BlockBarStyle BlockStyles[BlockStyleNum];

class TetrisPlayer;
//一个条块
class BlockBar 
{
public:
	BlockBar();
	void  SetStyle(BlockBarStyle *style);
	void  Render(bool fast);
	void  DrawUI(const vec2I& pos);
	//mov后是否触底
	bool  IsCollide (const vec2I& mov=vec2I(0, 0), int rot = -1);
	//是否超出边框
	bool  IsOutBoard(const vec2I& mov=vec2I(0, 0), int rot = -1);

	//move的得分
	float Score(const vec2I& mov=vec2I(0, 0), int rot = -1);

	void  Rotate(int nTimes = 1);
	bool  Move(const vec2I& mov);

	int   m_ID;
	vec2I m_point;
	int   m_curRot;
	//Color m_color;
	BlockBarStyle* m_style;
	TetrisPlayer*  m_owner;
};

//游戏状态
enum TetrisState
{
	Gaming,
	Vanishing,   //消除中
	ReLifing,    //重生中
	TimeFrozen,  //时间被对手停滞
	TimeFrozenTurble, //时间被对手停滞+停滞后激进
};


#define VanishTime 2.0f
#define FrozenTime 1.0f
#define FrozenTurbleTime 2.0f
#define RelifeTime 4.0f

class SoundChannel;
//玩家
class TetrisPlayer: public MiniPlayer
{
public:
	TetrisPlayer();
	virtual ~TetrisPlayer();
	virtual bool Start();
	virtual void Update();
	virtual void Render();
	void  RenderBlocks();

	virtual void  NewBlock();

	//是否超出边框
	bool IsOutBoard(const vec2I& pos);
	//触底后检查消除
	void CheckVanishing();
	//放入
	void PutinCurBlockBar();
	//新的一条命
	void LifeDown();

	RectF GetBlockRect(const vec2I& point);

	//当前条块
	BlockBar *m_curBlockBar;
	//预览下一条块
	BlockBar *m_nextBlockBar;
	//颜色
	int m_blockMap[BlockNumH][BlockNumW];

	TetrisState m_state;
	float m_stateTime;
	//难度
	int   m_diffcuty;
	//
	int   m_vanishLine;

	//连消
	int   m_continueNum;

	//主动快进 带拖尾
	bool  m_fast;

	//时间停滞特效 显示蛛网
	MovieClip* m_movieFrozen;
	//被动快进特效 无拖尾 显示乱流
	MovieClip* m_movieTurble;

	RectF m_blockRect;
	vec2  m_blockExtend;

	double m_diffcultTime;
	
	SoundChannel*  m_sound;
};

//机器人
class TetrisPlayerRobot:public TetrisPlayer
{
public:
	TetrisPlayerRobot();
	virtual bool  Start();
	virtual void  Update();
	virtual void  Render();

	virtual void  NewBlock();

	void FindBestPoint();
	void SetWorkingWithAI(bool working);

	vec2I  m_bestPoint;
	int    m_bestRot;
	float  m_bestScore;
	bool   m_workingWithAI;	
	double m_thinkTime;
};

//玩家
class TetrisPlayerRole:public TetrisPlayerRobot
{
public:
	virtual bool Start();
	virtual void Update();
};

#endif


//========================================================
//  @Date:     2016.05
//  @File:     SourceDemoClient/Chess/MiniGameTetris.cpp
//  @Brief:     MiniGameTetris
//  @Author:     LouLei
//  @Email:  twopointfive@163.com
//  @Copyright (Crapell) - All Rights Reserved
//========================================================

#include "General/Pch.h"
#include "Gui/GuiMgr.h"
#include "Gui/RpgGuis.h"
#include "Input/InputMgr.h"
#include "MiniGameTetris.h"
#include "Render/RendDriver.h"
#include "Render/Font.h"
#include "Tetris/Tetris.h"
#include "Packet/PacketMiniGame.h"
#include "Sound/ChannelSound.h"
#include "General/Timer.h"
#include "General/Pce.h"
#include "General/Regulator.h"
#include "Math/MathLib.h"

Regulator LastKeyDownTime(8);
#define BarSize m_style->m_barSize


BlockBarStyle::BlockBarStyle(int size, char *str)
{
	m_barSize = size;
	memset(m_mask, 0, sizeof(m_mask));
	//构建方块
	for(int h = 0; h < size; h++)
	{
		for(int w = 0; w < size; w++)
		{
			m_mask[0][h][w] = str[h * size + w] - '0';
		}
	}
	//构建旋转
	for(int r = 1; r < MaxRot; r++)
	{
		for(int h = 0; h < m_barSize; h++)
		{
			for(int w = 0; w < m_barSize; w++)
			{
				m_mask[r][h][w] = m_mask[r - 1][w][m_barSize - 1 - h];
			}
		}
	}
	//旋转数 todo 还有可能是1
	m_rotNum = 2;
	for(int h = 0; h < m_barSize; h++)
	{
		for(int w = 0; w < m_barSize; w++)
		{
			if(m_mask[0][h][w] != m_mask[2][h][w])
			{
				m_rotNum = 4;//不对称
				break;
			}
		}
	}
}

BlockBarStyle::BlockBarStyle()
{
	m_barSize = 0;
}

char BlockBarStyle::IsSolid(int x, int y, int rot)
{
	//rot旋转时 xy位置是否实心
	if (x<0 || x>=m_barSize)
	{
		return false;
	}
	if (y<0 || y>=m_barSize)
	{
		return false;
	}
	return m_mask[rot][y][x];
}
Color BlockBarStyle::colors[MaxBlockColor] = 
{
	Color::red        ,//无效 red还未初始化
};
//==================^_^==================^_^==================^_^==================^_^
BlockBar::BlockBar()
:m_curRot(0)
{

}

bool  BlockBar::Move(const vec2I& mov)
{
	Assert(0<=m_curRot&&m_curRot<4,"0<=m_curRot&&m_curRot<4");
	if(IsOutBoard(mov))
	{
		return false;
	}
	if(IsCollide(mov))
	{
		return false;
	}
	m_point += mov;
	return true;
}

void  BlockBar::Rotate(int nTimes /*= 1*/)
{
	int nextRot = (m_curRot + nTimes + m_style->m_rotNum) % m_style->m_rotNum;
	if(IsCollide(vec2I(0, 0), nextRot))
	{
		return;
	}
	if(IsOutBoard(vec2I(0, 0), nextRot))
	{
		//todo 旋转后移入边框
		return;
	}
	m_curRot = nextRot;
}

bool  BlockBar::IsCollide(const vec2I& mov, int rot /*= -1*/)
{
	if (rot==-1)
	{
		rot = m_curRot;
	}
	for(int h = 0; h < BarSize; h++)
	{
		for(int w = 0; w < BarSize; w++)
		{
			if (m_style->IsSolid(w, h, rot))
			{
				vec2I pos = m_point + vec2I(w, h) + mov;
				if(pos.y>=BlockNumH)
				{
					return true;//接触底框
				}
				if(m_owner->m_blockMap[pos.y][pos.x])
				{
					return true;//接触块
				}
			}
		}
	}
	return false;
}

bool  BlockBar::IsOutBoard(const vec2I& mov, int rot /*= -1*/)
{
	if (rot==-1)
	{
		rot = m_curRot;
	}
	for(int h = 0; h < BarSize; h++)
	{
		for(int w = 0; w < BarSize; w++)
		{
			if (m_style->IsSolid(w, h, rot))
			{
				vec2I pos = m_point + vec2I(w, h) + mov;
				if(m_owner->IsOutBoard(pos))
				{
					return true;
				}
			}
		}
	}
	return false;
}

float BlockBar::Score(const vec2I& mov, int rot /*= -1*/)
{
	if (rot==-1)
	{
		rot = m_curRot;
	}
	float score = 0;
	vec2I pos = m_point + mov;

	bool fullLine[BlockNumH];
	for(int h = BlockNumH-1; h >=0; h--)
	{
		fullLine[h] = true;
		for(int w = 0; w < BlockNumW; w++)
		{
			if(!(m_owner->m_blockMap[h][w]!=0
				||m_style->IsSolid(w-pos.x, h-pos.y, rot)
				)
				)
			{
				fullLine[h] = false;
				break;
			}
		}
	}

	for(int h = BlockNumH-1; h >=0; h--)
	{
		for(int w = 0; w < BlockNumW; w++)
		{
			if(m_owner->m_blockMap[h][w]!=0
				||m_style->IsSolid(w-pos.x, h-pos.y, rot)
				)
			{
				score += 10*sqrt(float(h));
			}
			else
			{
				for (int j=h-1;j>=0;j--)
				{
					if ((m_owner->m_blockMap[j][w]!=0
						||m_style->IsSolid(w-pos.x, j-pos.y, rot)
						)
						&&fullLine[j] == false//可消除不算遮盖
						)
					{
						score -= 6;//空挡被遮盖 惩罚
						break;
					}
				}
			}
		}
	}

	return score;
}

void  BlockBar::DrawUI(const vec2I& pos)
{
	int h, w;
	for(h = 0; h < BarSize; h++)
	{
		for(w = 0; w < BarSize; w++)
		{
			if (m_style->IsSolid(w, h, m_curRot))
			{
				RectF rect(pos.x+w*28,pos.y+h*28,28,28);

				G_TetrisGame->m_blockIconN[0]->Bind();
				G_RendDriver->DrawTextureRect(rect);
			}
		}
	}
}

void  BlockBar::Render(bool fast)
{
	
	if (fast)
	{
		//拖尾
		G_RendDriver->Color3f(1,1,1);
		G_RendDriver->BlendFunc(Blend_Additive);
		RectF rect;

		G_TetrisGame->m_blockTail->Bind();
		for(int h = 0; h < BarSize; h++)
		{
			for(int w = 0; w < BarSize; w++)
			{
				if (m_style->IsSolid(w, h, m_curRot))
				{
					vec2I pos = m_point+vec2I(w,h );
					rect = m_owner->GetBlockRect(pos);
					if(!m_owner->IsOutBoard(pos))
					{
						rect.height += (rect.y - m_owner->m_blockRect.y);
						rect.y = m_owner->m_blockRect.y;
						G_RendDriver->DrawTextureRect(rect,RectF(((G_Timer->GetCurrentFrame()/4+w)%4)*0.25f,1,0.25f,1));
					}
				}
			}
		}

		G_RendDriver->BlendFunc(Blend_Filter);
		G_RendDriver->Color4f(1,1,1,1);
	}
	
	//方块
	Color& color = BlockBarStyle::colors[m_ID % MaxBlockColor];
	G_RendDriver->Color4fv(&color.r);
	for(int h = 0; h < BarSize; h++)
	{
		for(int w = 0; w < BarSize; w++)
		{
			if (m_style->IsSolid(w, h, m_curRot))
			{
				vec2I pos = m_point+vec2I(w,h );
				if(!m_owner->IsOutBoard(pos))
				{
					G_TetrisGame->m_blockIconN[0]->Bind();
					G_RendDriver->DrawTextureRect(m_owner->GetBlockRect(pos));
				}
			}
		}
	}


	//描边
	G_RendDriver->Color3f(1,1,1);
	G_RendDriver->BlendFunc(Blend_Additive);
	RectF rect;
	for(int h = 0; h < BarSize; h++)
	{
		for(int w = 0; w < BarSize; w++)
		{
			if (m_style->IsSolid(w, h, m_curRot))
			{
				vec2I pos = m_point+vec2I(w,h );
				rect = m_owner->GetBlockRect(pos);

				if(!m_owner->IsOutBoard(pos))
				{
					if (m_style->IsSolid(w, h-1, m_curRot)==false)
					{
						G_TetrisGame->m_blockBorder[0]->Bind();
						G_RendDriver->DrawTextureRect(rect);
					}
					if (m_style->IsSolid(w, h+1, m_curRot)==false)
					{
						G_TetrisGame->m_blockBorder[1]->Bind();
						G_RendDriver->DrawTextureRect(rect);
					}
					if (m_style->IsSolid(w-1, h, m_curRot)==false)
					{
						G_TetrisGame->m_blockBorder[2]->Bind();
						G_RendDriver->DrawTextureRect(rect);
					}
					if (m_style->IsSolid(w+1, h, m_curRot)==false)
					{
						G_TetrisGame->m_blockBorder[3]->Bind();
						G_RendDriver->DrawTextureRect(rect);
					}

				}
			}
		}
	}

	G_RendDriver->BlendFunc(Blend_Filter);
	G_RendDriver->Color4f(1,1,1,1);
}

void  BlockBar::SetStyle(BlockBarStyle *style)
{
	m_style = style;
}


//==================^_^==================^_^==================^_^==================^_^
TetrisPlayer::TetrisPlayer()
:m_curBlockBar(NULL)
,m_nextBlockBar(NULL)
,m_diffcuty(0)
,m_state(Gaming)
,m_vanishLine(0)
,m_stateTime(0)
,m_continueNum(0)
,m_diffcultTime(0)
,m_fast(false)
{
	m_sound = new SoundChannel;
}

TetrisPlayer::~TetrisPlayer()
{
	SafeDelete(m_sound);
}

bool  TetrisPlayer::Start()
{
	m_diffcuty = 1;
	m_liveNum = 2;
	m_score = 0;
	m_diffcultTime = G_Timer->GetAccumTime();

	memset(m_blockMap, 0, sizeof(m_blockMap));

	if(m_nextBlockBar==NULL)
		m_nextBlockBar = new BlockBar();
	m_nextBlockBar->m_owner = this;
	m_nextBlockBar->m_style = &BlockStyles[Rand() % BlockStyleNum];

	if(m_curBlockBar==NULL)
		m_curBlockBar = new BlockBar();
	m_curBlockBar->m_owner = this;
	NewBlock();

	m_state = Gaming;
	return true;
}

bool  TetrisPlayer::IsOutBoard(const vec2I& pos)
{
	return pos.x < 0 || pos.y < 0 || pos.x >= BlockNumW || pos.y >= BlockNumH;
}

//触底后检查消除
void  TetrisPlayer::CheckVanishing()
{
	//检测
	m_vanishLine = -1;
	for(int h = BlockNumH-1; h >=0; h--)
	{
		bool fullLine = true;
		for(int w = 0; w < BlockNumW; w++)
		{
			if(m_blockMap[h][w]==0)
			{
				fullLine = false;
				break;
			}
		}
		if(fullLine)
		{
			m_vanishLine = h;
			break;
		}
	}

	if(m_vanishLine!=-1)
	{
		m_sound->PlaySound__("data/sound/skill_ziyu.wav");
		m_state = Vanishing;
		m_stateTime = 0;
		//m_continueNum++;

		//因为只有两个玩家 暂时放在这里 无需同步了
		TetrisPlayer* otherPlayer = G_TetrisGame->GetOtherPlayer(this);
		if (otherPlayer->m_state==Gaming
			||otherPlayer->m_state==TimeFrozen)
		{
			if (m_continueNum>0)
			{
				otherPlayer->m_state = TimeFrozenTurble;
			}
			else
			{
				otherPlayer->m_state = TimeFrozen;
			}
			otherPlayer->m_stateTime = 0;
		}
	}
	else
	{
		m_state = Gaming;
		m_continueNum = 0;
	}
}

void  TetrisPlayer::PutinCurBlockBar()
{
	//放入
	for(int h = 0; h < m_curBlockBar->BarSize; h++)
	{
		for(int w = 0; w < m_curBlockBar->BarSize; w++)
		{
			if (m_curBlockBar->m_style->IsSolid(w, h, m_curBlockBar->m_curRot))
			{
				vec2I pos = m_curBlockBar->m_point+vec2I(w,h);
				if(!IsOutBoard(pos))
				{
					m_blockMap[pos.y][pos.x]  = m_curBlockBar->m_ID;
				}
			}
		}
	}
}
//新的一条命
void  TetrisPlayer::LifeDown()
{
	if(m_liveNum>1)
	{
		m_liveNum --;
		m_state = ReLifing;
		m_stateTime = 0;
	}
	else
	{
		G_TetrisGame->m_bEndGame = true;
	}
	m_sound->PlaySound__("data/sound/tetris/tetris_relife.wav");
}

void  TetrisPlayer::Update()
{
	if(G_TetrisGame->m_bEndGame)
		return;

	switch(m_state)
	{
	case TimeFrozen:
		m_stateTime+=G_Timer->GetStepTimeLimited();
		if(m_stateTime>FrozenTime)
		{
			m_state = Gaming;
		}
		break;
	case Gaming:
		{
			float stepTime = 1.0f / m_diffcuty;
			if (G_Timer->GetAccumTime() - m_diffcultTime >= stepTime)
			{
				//触底后还有stepTime的横移反应时间
				if (m_curBlockBar->IsCollide(vec2I(0, 1)))
				{
					PutinCurBlockBar();
					CheckVanishing();//消除
					NewBlock();      //生成新的
				}
			}
		}
		break;
	case TimeFrozenTurble:
		{
			//更复杂的做法: 使用进度控制器列表
			m_stateTime+=G_Timer->GetStepTimeLimited();
			if(m_stateTime<FrozenTime)
			{
			}
			else if(m_stateTime<FrozenTurbleTime)
			{
				float stepTime = 1.0f / m_diffcuty/2.0f;
				if (G_Timer->GetAccumTime() - m_diffcultTime >= stepTime)
				{
					//触底后还有stepTime的横移反应时间
					if (m_curBlockBar->IsCollide(vec2I(0, 1)))
					{
						PutinCurBlockBar();
						CheckVanishing();//消除
						NewBlock();      //生成新的
					}
				}
			}
			else 
			{
				m_state = Gaming;
			}
		}
		break;
	case Vanishing:
		{
			m_stateTime+=G_Timer->GetStepTimeLimited();
			//闪2秒
			if(m_stateTime>VanishTime)
			{
				m_continueNum++;
				//消除一行满的

				//降
				for(int w = 0; w < BlockNumW; w++)
				{
					for(int ith = m_vanishLine; ith > 0; ith--)
					{
						int upblock = m_blockMap[ith-1][w];
						m_blockMap[ith][w] = upblock;
					}
				}

				//增加分数?
				//m_score += 2 * continueNum - 1;
				m_score += m_continueNum * m_continueNum;

				//增加难度
				if( m_score >= m_diffcuty * m_diffcuty * 10)
				{
					if(m_diffcuty <= 6)
						m_diffcuty ++;
				}
				//增加生命
				if( m_score >= 50 * (m_liveNum + 1))
				{
					if(m_liveNum <= 6)
						m_liveNum ++;
				}

				CheckVanishing();
			}
		}
		break;
	case ReLifing:
		m_stateTime +=G_Timer->GetStepTimeLimited();
		//闪秒
		if(m_stateTime>RelifeTime)
		{
			m_state = Gaming;
			for(int i = BlockNumH - 1; i >= 0; i--)
			{
				for(int j = BlockNumW - 1; j >= 0; j--)
				{
					m_blockMap[i][j] = 0;
				}
			}
		}
		break;
	}
}
void  TetrisPlayer::Render()
{
	G_RendDriver->Color3f(1,1,1);
	//block back
	for(int h = 0; h < BlockNumH; h++)
	{
		for(int w = 0; w < BlockNumW; w++)
		{
			G_TetrisGame->m_blockBack->Bind();
			G_RendDriver->DrawTextureRect(GetBlockRect(vec2I(w,h )));
		}
	}

	//player block
	switch(m_state)
	{
	case TimeFrozen:
		{
			RenderBlocks();
			m_curBlockBar->Render(false);

			//todo 可以使用movie
			//m_movieFrozen->Advance(); 
			//m_movieFrozen->RendClip();

			//时间停滞
			G_TetrisGame->m_timePause2->Bind();
			RectF rect = GetBlockRect(vec2I(1, 5));
			rect.width = m_blockExtend.x*8;
			rect.height = m_blockExtend.y*8;
			G_RendDriver->DrawTextureRect(rect);
		}
		break;
	case TimeFrozenTurble:
		{
			if (m_stateTime<TimeFrozen)
			{
				RenderBlocks();
				m_curBlockBar->Render(false);

				//时间停滞
				G_TetrisGame->m_timePause2->Bind();
				RectF rect = GetBlockRect(vec2I(1, 5));
				rect.width = m_blockExtend.x*8;
				rect.height = m_blockExtend.y*8;
				G_RendDriver->DrawTextureRect(rect);
			}
			else
			{
				//时间乱流
				G_TetrisGame->m_timeTurble->Bind();
				RectF rect = GetBlockRect(vec2I(3, 10));
				rect.width = m_blockExtend.x*4;
				rect.height = m_blockExtend.y*8;
				G_RendDriver->DrawTextureRect(rect);

				RenderBlocks();
				m_curBlockBar->Render(false);
			}
		}
		break;
	case Gaming:
		{
			RenderBlocks();
			m_curBlockBar->Render(m_fast);
		}
		break;
	case Vanishing:
		{
			RenderBlocks();

			//m_curBlockBar->Draw(); 已经put
			//  每秒闪3次
			bool flash = (int(m_stateTime*3))%2;
			if (flash)
			{
				G_RendDriver->BlendFunc(Blend_Additive);
				G_TetrisGame->m_blockIconH[0]->Bind();
			}
			else
			{
				G_RendDriver->BlendFunc(Blend_Filter);
				G_TetrisGame->m_blockIconN[0]->Bind();
			}
			for(int w = 0; w < BlockNumW; w++)
			{
				int ID = m_blockMap[m_vanishLine][w];
				G_RendDriver->Color4fv(&BlockBarStyle::colors[ID % MaxBlockColor].r);
				G_RendDriver->DrawTextureRect(GetBlockRect(vec2I(w, m_vanishLine)));
			}
			G_RendDriver->Color3f(1,1,1);


			//todo 可以使用movie定制更酷炫的动画
			//闪电
			G_RendDriver->BlendFunc(Blend_Additive);
			G_TetrisGame->m_lightning->Bind();
			RectF rect = GetBlockRect(vec2I(0, m_vanishLine));
			rect.width = m_blockRect.width;
			G_RendDriver->DrawTextureRect(rect,RectF(m_stateTime*2.0f,0,1,1));
			G_RendDriver->BlendFunc(Blend_Filter);

			//对手时间停滞
			G_TetrisGame->m_timePause->Bind();
			rect = GetBlockRect(vec2I(1, m_vanishLine));
			rect.width = m_blockExtend.x*8;
			rect.height = m_blockExtend.y*2;
			G_RendDriver->DrawTextureRect(rect);
		}
		break;
	case ReLifing:
		{
			//todo 可以使用movie定制更酷炫的动画
			//m_curBlockBar->Draw(); 
			int line = 0;
			if (m_stateTime<RelifeTime/2)
			{
				RenderBlocks();
				line = m_stateTime/(RelifeTime/2.1f)*BlockNumH;
			}
			else
			{
				line = (2-(m_stateTime/(RelifeTime/2.1f)))*BlockNumH;
			}

			for(int i = 0; i < line&&i<BlockNumH; i++)
			{
				for(int j = 0; j < BlockNumW; j++)
				{
					G_TetrisGame->m_blockIconN[0]->Bind();
					G_RendDriver->DrawTextureRect(GetBlockRect(vec2I(j,i )));
				}
			}
		}
		break;
	}

}

void  TetrisPlayer::RenderBlocks()
{
	for(int h = 0; h < BlockNumH; h++)
	{
		for(int w = 0; w < BlockNumW; w++)
		{
			if (m_blockMap[h][w]>0)
			{
				G_TetrisGame->m_blockIconN[0]->Bind();

				int ID = m_blockMap[h][w];
				G_RendDriver->Color4fv(&BlockBarStyle::colors[ID % MaxBlockColor].r);
				G_RendDriver->DrawTextureRect(GetBlockRect(vec2I(w,h )));
			}
		}
	}

	//描边
	G_RendDriver->Color3f(1,1,1);
	G_RendDriver->BlendFunc(Blend_Additive);
	RectF rect;
	for(int h = 0; h < BlockNumH; h++)
	{
		for(int w = 0; w < BlockNumW; w++)
		{
			rect = GetBlockRect(vec2I(w,h ));
			int id = m_blockMap[h][w];
			if (id>0)
			{
				if (h==0 ||
					(h>0 && m_blockMap[h-1][w]!=id)
					)
				{
					G_TetrisGame->m_blockBorder[0]->Bind();
					G_RendDriver->DrawTextureRect(rect);
				}
				if (h==BlockNumH-1 ||
					(h<BlockNumH-1 && m_blockMap[h+1][w]!=id)
					)
				{
					G_TetrisGame->m_blockBorder[1]->Bind();
					G_RendDriver->DrawTextureRect(rect);
				}
				if (w==0 ||
					(w>0 && m_blockMap[h][w-1]!=id)
					)
				{
					G_TetrisGame->m_blockBorder[2]->Bind();
					G_RendDriver->DrawTextureRect(rect);
				}
				if (w==BlockNumW-1 ||
					(w<BlockNumW-1 && m_blockMap[h][w+1]!=id)
					)
				{
					G_TetrisGame->m_blockBorder[3]->Bind();
					G_RendDriver->DrawTextureRect(rect);
				}
			}
		}
	}

	G_RendDriver->BlendFunc(Blend_Filter);
	G_RendDriver->Color4f(1,1,1,1);
}

RectF TetrisPlayer::GetBlockRect(const vec2I& point)
{
	return RectF(m_blockRect.x+point.x*m_blockExtend.x,m_blockRect.y+point.y*m_blockExtend.y,m_blockExtend.x,m_blockExtend.y);
}


void  TetrisPlayer::NewBlock()
{
	BlockBarStyle* style = m_nextBlockBar->m_style;
	m_curBlockBar->SetStyle(style);
	m_curBlockBar->m_curRot = Rand() % style->m_rotNum;
	m_curBlockBar->m_point = vec2I(4, 0);
//	m_curBlockBar->m_color = (&Color::red)[Rand() % 12];
	static int ID = 1;
	m_curBlockBar->m_ID = ++ ID;

	m_nextBlockBar->SetStyle(&BlockStyles[Rand() % BlockStyleNum]);
	//m_nextBlockBar->SetStyle(&BlockStyles[12]);

	if(m_curBlockBar->IsCollide(vec2I(0, 0)))
	{
		//刚生成就触底=》结束
		//同步清除,自己计算可能不同步?
		LifeDown();
	}
}

//==================^_^==================^_^==================^_^==================^_^
TetrisPlayerRobot::TetrisPlayerRobot()
:m_workingWithAI(false)	
,m_thinkTime(0)
{

}
bool TetrisPlayerRobot::Start()
{
	TetrisPlayer::Start();
	m_workingWithAI = true;
	m_thinkTime     = G_Timer->GetAccumTime();
	FindBestPoint();
	return true;
}

void TetrisPlayerRobot::Render()
{
	TetrisPlayer::Render();

	char buf[256];
	sprintf(buf,"bestScore = %.1f",m_bestScore);
	G_FontMgr->TextAtPos(m_blockRect.GetPos(),buf);
}

void TetrisPlayerRobot::Update()
{
	TetrisPlayer::Update();


	if(G_TetrisGame->m_bEndGame)
		return;

	bool move = false;

	switch(m_state)
	{
	case Gaming:
		{
			float stepTime = 1.0f / m_diffcuty;
			if (G_Timer->GetAccumTime() - m_diffcultTime >= stepTime)
			{
				//触底后还有stepTime的横移反应时间
				if (m_curBlockBar->IsCollide(vec2I(0, 1))==false)
				{
					//未触底 自动下降
					m_curBlockBar->Move(vec2I(0, 1));
					m_diffcultTime = G_Timer->GetAccumTime();
					move = true;
				}
			}
		}
		break;
	case TimeFrozenTurble:
		{
			//更复杂的做法: 使用进度控制器列表
			m_stateTime+=G_Timer->GetStepTimeLimited();
			if(m_stateTime<FrozenTime)
			{
			}
			else if(m_stateTime<FrozenTurbleTime)
			{
				float stepTime = 1.0f / m_diffcuty/2.0f;
				if (G_Timer->GetAccumTime() - m_diffcultTime >= stepTime)
				{
					//触底后还有stepTime的横移反应时间
					if (m_curBlockBar->IsCollide(vec2I(0, 1))==false)
					{
						//未触底 自动下降
						m_curBlockBar->Move(vec2I(0, 1));
						m_diffcultTime = G_Timer->GetAccumTime();
						move = true;
					}
				}
			}
		}
		break;
	case Vanishing:
		{
			m_stateTime+=G_Timer->GetStepTimeLimited();
			//闪2秒
			if(m_stateTime>VanishTime)
			{
				m_continueNum++;
				//消除一行满的

				//降
				for(int w = 0; w < BlockNumW; w++)
				{
					for(int ith = m_vanishLine; ith > 0; ith--)
					{
						int upblock = m_blockMap[ith-1][w];
						m_blockMap[ith][w] = upblock;
					}
				}

				//增加分数?
				//m_score += 2 * continueNum - 1;
				m_score += m_continueNum * m_continueNum;

				//增加难度
				if( m_score >= m_diffcuty * m_diffcuty * 10)
				{
					if(m_diffcuty <= 6)
						m_diffcuty ++;
				}
				//增加生命
				if( m_score >= 50 * (m_liveNum + 1))
				{
					if(m_liveNum <= 6)
						m_liveNum ++;
				}

				CheckVanishing();
			}
		}
		break;
	
	}


	if (m_workingWithAI)
	{
		switch(m_state)
		{
		case Gaming:
			{
			
				if (m_curBlockBar->m_curRot == m_bestRot
					&&m_curBlockBar->m_point.x == m_bestPoint.x)
				{
					if (m_fast)
					{
						m_diffcuty = 6;
						//if (G_Timer->GetAccumTime() - m_thinkTime >= 0.1f)
						if (G_Timer->GetAccumTime() - m_thinkTime >= 0.01f)
						{
							m_thinkTime = G_Timer->GetAccumTime();
							{
								m_curBlockBar->Move(vec2I(0, 1));
								move = true;
							}
						}
					}
				}
				else
				{
					if (G_Timer->GetAccumTime() - m_thinkTime >= 0.5f *(m_fast?0.1f:1.0f))
						//if (G_Timer->GetAccumTime() - m_thinkTime >= 0.05f)
					{
						m_thinkTime = G_Timer->GetAccumTime();
						if (m_curBlockBar->m_curRot < m_bestRot)
						{
							if (abs(m_curBlockBar->m_curRot-m_bestRot) < 2)//0~12
								m_curBlockBar->Rotate(1);
							else
								m_curBlockBar->Rotate(-1);//0~3
							move = true;
						}
						else if (m_curBlockBar->m_curRot > m_bestRot)
						{
							if (abs(m_curBlockBar->m_curRot-m_bestRot) < 2)
								m_curBlockBar->Rotate(-1);
							else
								m_curBlockBar->Rotate(1);
							move = true;
						}

						if (m_curBlockBar->m_point.x < m_bestPoint.x)
						{
							m_curBlockBar->Move(vec2I(1, 0));
							move = true;
						}
						else if (m_curBlockBar->m_point.x > m_bestPoint.x)
						{
							m_curBlockBar->Move(vec2I(-1, 0));
							move = true;
						}
					}
				}
			}
			break;
		}
	}

	if (move == true)
	{
		//同步bar的移动
		C2SPacketMiniGameCmd packet;
		packet.WriteHeader();
		packet.WriteValue(CMD_CurBlockBar);  
		packet.WriteValue(m_roomSlot);
		packet.WriteValue(m_curBlockBar->m_point.x); 
		packet.WriteValue(m_curBlockBar->m_point.y);
		packet.WriteValue(m_curBlockBar->m_curRot);
		packet.WriteValue(m_curBlockBar->m_style->ID);
		G_MiniGame->SendPacketToOther(&packet);

		m_sound->PlaySound__("data/sound/ui_click.wav");
	}
}

void TetrisPlayerRobot::FindBestPoint()
{
	//不考虑来不及变换的情况

	//不考虑绕过阻挡后横移

	//不考虑同nextbar配合

	m_bestRot = 0;
	m_bestPoint.x = 4;
	m_bestScore = -MaxFloat;

	vec2I mov;
	int startY = m_curBlockBar->m_point.y;
	int rotNum = m_curBlockBar->m_style->m_rotNum;//2 or 4
	for (int rot=0;rot<rotNum;rot++)
	{
		//for (int x=0;x<BlockNumW;x++)
		for (int x=-m_curBlockBar->BarSize;x<BlockNumW+m_curBlockBar->BarSize;x++)
		{
			mov.x = x - m_curBlockBar->m_point.x;
			mov.y = 0;
			if (m_curBlockBar->IsOutBoard(mov,rot))
			{
				//左右出框 无法到达
				continue;
			}

			if (m_curBlockBar->IsCollide(mov,rot))
			{
				//已经接触 无法到达
				continue;
			}

			for (int y=startY;y<BlockNumH;y++)
			{
				mov.y = y - m_curBlockBar->m_point.y;
				if (m_curBlockBar->IsCollide(mov+vec2I(0,1),rot)==true) //将要触底
				{
					float score = m_curBlockBar->Score(mov,rot);
					if (score > m_bestScore)
					{
						m_bestScore = score;
						m_bestRot = rot;
						m_bestPoint = vec2I(x,y);
					}
					break;
				}
			}
		}
	}
}

void TetrisPlayerRobot::SetWorkingWithAI(bool working)
{
	m_workingWithAI = working;
	if (working)
	{
		FindBestPoint();//可能中途切换
	}
}

void TetrisPlayerRobot::NewBlock()
{
	TetrisPlayer::NewBlock();
	if (m_workingWithAI)
	{
		FindBestPoint();
	}
}

//==================^_^==================^_^==================^_^==================^_^
bool TetrisPlayerRole::Start()
{
	TetrisPlayer::Start();
	m_workingWithAI = false;
	return true;
}

void TetrisPlayerRole::Update()
{
	if(G_TetrisGame->m_bEndGame)
		return;

	if (m_workingWithAI==true)
	{
		TetrisPlayerRobot::Update();
		return;
	}

	TetrisPlayer::Update();

	switch(m_state)
	{
	case Gaming:
		{
			vec2I oldPoint = m_curBlockBar->m_point;
			int oldRot = m_curBlockBar->m_curRot;

			if (G_TetrisGame->IsKeyDowning(KeyUp))
			{
				m_curBlockBar->Rotate();
				LastKeyDownTime.ResetReady();
			}
			else if (G_TetrisGame->IsKeyDowning(KeyLeft))
			{
				m_curBlockBar->Move(vec2I(-1, 0));
				LastKeyDownTime.ResetReady();
			}
			else if (G_TetrisGame->IsKeyDowning(KeyRight))
			{
				m_curBlockBar->Move(vec2I(1, 0));
				LastKeyDownTime.ResetReady();
			}
			else if (G_TetrisGame->IsKeyDowning(KeyDown))
			{
				if( false == m_curBlockBar->Move(vec2I(0, 2)) )
					m_curBlockBar->Move(vec2I(0, 1));
				LastKeyDownTime.ResetReady();
			}
			else if (LastKeyDownTime.IsReady())
			{
				if (G_TetrisGame->IsKeyPressed(KeyUp))
				{
					m_curBlockBar->Rotate();
				}
				if (G_TetrisGame->IsKeyPressed(KeyLeft))
				{
					m_curBlockBar->Move(vec2I(-1, 0));
				}
				if (G_TetrisGame->IsKeyPressed(KeyRight))
				{
					m_curBlockBar->Move(vec2I(1, 0));
				}
				if (G_TetrisGame->IsKeyPressed(KeyDown))
				{
					if( false == m_curBlockBar->Move(vec2I(0, 2)) )
						m_curBlockBar->Move(vec2I(0, 1));
				}
			}

			if ((oldPoint-m_curBlockBar->m_point).Length()>_EPSILON
				||oldRot != m_curBlockBar->m_curRot)
			{
				//同步bar的移动
				C2SPacketMiniGameCmd packet;
				packet.WriteHeader();
				packet.WriteValue(CMD_CurBlockBar); 
				packet.WriteValue(m_roomSlot);
				packet.WriteValue(m_curBlockBar->m_point.x); 
				packet.WriteValue(m_curBlockBar->m_point.y);
				packet.WriteValue(m_curBlockBar->m_curRot);
				packet.WriteValue(m_curBlockBar->m_style->ID);
				G_MiniGame->SendPacketToOther(&packet);

				m_sound->PlaySound__("data/sound/ui_click.wav");
			}
		}
		break;
	}
}

游戏类:

//========================================================
//  @Date:     2016.05
//  @File:     SourceDemoClient/Chess/MiniGameTetris.h
//  @Brief:     MiniGameTetris
//  @Author:     LouLei
//  @Email:  twopointfive@163.com
//  @Copyright (Crapell) - All Rights Reserved
//========================================================
 
#ifndef  __MiniGameTetris__H__
#define  __MiniGameTetris__H__

#include "Math/MathLib.h"
#include "Render/Texture.h"
#include "Rpg/MiniGame.h"

//双人方块 右下角显示别的玩家进度
//每消除一行 给对手投递一个停滞蛛网到右下角(对手右下角消除时飞出停滞蛛网)
//连消 产生停滞蛛网 + 快进乱流
//对手死亡(右下角表现)

//有些命令没有发送,暂时自己计算,同步情况尚可
enum MiniTetrisCmd
{
	CMD_NewBlockBar, //新bar
	CMD_CurBlockBar, //下降bar
	CMD_Vanishing  , //消除中
	CMD_ReLifing   , //重生中  
	CMD_TimeFrozen , //冻结      
	CMD_GameOver   ,
	CMD_Restart    ,
};
const char* TetrisCmdToString(int enumeration);

class TetrisPlayer;
class TetrisPlayerRole;
class MiniGameTetris:public MiniGame
{
public:
	MiniGameTetris();
	virtual ~MiniGameTetris();

	virtual bool Start();
	virtual bool ReStart();
	virtual bool Stop();
	virtual bool Render();
	virtual void RenderUI();
	virtual bool Update();
	virtual bool Free();
	virtual bool IsEnd();
	virtual void OnSize();

	//三种类型结构
	virtual MiniPlayer*  CreatePlayer();
	virtual MiniPlayer*  CreateRobot ();
	virtual MiniPlayer*  CreateRole  ();

	TetrisPlayer* GetOtherPlayer(TetrisPlayer* self);
	//处理游戏网络命令包
	virtual int  ProcessPacketCmd(PacketBase* packet);
	//virtual const char* CmdToString(const char* stream,int len);

//private:	
	TexturePtr m_blockIconN[4];	//图标
	TexturePtr m_blockIconH[4];	//图标
	TexturePtr m_blockBack;	
	TexturePtr m_blockBorder[4];	
	TexturePtr m_blockTail;	
	TexturePtr m_lightning;	
	TexturePtr m_lifeIcon;	
	TexturePtr m_diffcutyIcon;	
	TexturePtr m_frameTex;	
	TexturePtr m_timePause;	
	TexturePtr m_timePause2;
	TexturePtr m_timeTurble;	

	RectF m_gameRect;
	RectF m_scorePannelRect;
	TetrisPlayerRole* m_myRolePlayer;

	bool m_bEndGame;

};
extern MiniGameTetris* G_TetrisGame;
#endif 

//========================================================
//  @Date:     2016.05
//  @File:     SourceDemoClient/Chess/MiniGameTetris.cpp
//  @Brief:     MiniGameTetris
//  @Author:     LouLei
//  @Email:  twopointfive@163.com
//  @Copyright (Crapell) - All Rights Reserved
//========================================================
 
#include "General/Pch.h"
#include "General/Window.h"
#include "Gui/GuiMgr.h"
#include "Gui/RpgGuis.h"
#include "Input/InputMgr.h"
#include "MiniGameTetris.h"
#include "Render/RendDriver.h"
#include "Render/Shader.h"
#include "Render/Font.h"
#include "Tetris/Tetris.h"
#include "Net/PacketList.h"
#include "Rpg/SyncGameInfo.h"
#include "General/Pce.h"

MiniGameTetris* G_TetrisGame = NULL;
BlockBarStyle BlockStyles[BlockStyleNum];

MiniGameTetris::MiniGameTetris()
{
	G_TetrisGame = this;
	CmdEnumToString = TetrisCmdToString;
}

MiniGameTetris::~MiniGameTetris()
{
	G_TetrisGame = NULL;
}

bool MiniGameTetris::Start()
{
	m_myRolePlayer = NULL;
	if(!MiniGame::Start())
		return false;

	G_TextureMgr->AddTexture(m_blockIconN[0],"data/minigame/Tetris/block0_n.png");
	G_TextureMgr->AddTexture(m_blockIconH[0],"data/minigame/Tetris/block0_h.png");
	G_TextureMgr->AddTexture(m_blockBack,"data/minigame/Tetris/blockback.png");
	G_TextureMgr->AddTexture(m_blockTail,"data/minigame/Tetris/tail.png");
	G_TextureMgr->AddTexture(m_blockBorder[0],"data/minigame/Tetris/blockborder0.png");
	G_TextureMgr->AddTexture(m_blockBorder[1],"data/minigame/Tetris/blockborder1.png");
	G_TextureMgr->AddTexture(m_blockBorder[2],"data/minigame/Tetris/blockborder2.png");
	G_TextureMgr->AddTexture(m_blockBorder[3],"data/minigame/Tetris/blockborder3.png");


	G_TextureMgr->AddTexture(m_lightning,"data/minigame/Tetris/lightning.png");
	G_TextureMgr->AddTexture(m_frameTex,"data/minigame/Tetris/back.png");
	G_TextureMgr->AddTexture(m_lifeIcon,"data/minigame/Tetris/life.png");
	G_TextureMgr->AddTexture(m_diffcutyIcon,"data/minigame/Tetris/diffcuty.png");
	G_TextureMgr->AddTexture(m_timePause,"data/minigame/Tetris/timepause.png");
	G_TextureMgr->AddTexture(m_timePause2,"data/minigame/Tetris/timepause2.png");
	G_TextureMgr->AddTexture(m_timeTurble,"data/minigame/Tetris/ghost2.png");


	//BlockStyles[0] = BlockBarStyle(2, 
	//	"██"
	//	"██");

	//BlockStyles[1] = BlockBarStyle(3, 
	//	"  █  "
	//	"███"
	//	"      ");

	//BlockStyles[2] = BlockBarStyle(3, 
	//	"█    "
	//	"███"
	//	"      ");

	//BlockStyles[3] = BlockBarStyle(3, 
	//	"    █"
	//	"███"
	//	"      ");

	//BlockStyles[4] = BlockBarStyle(3, 
	//	"██  "
	//	"  ██"
	//	"      ");

	//BlockStyles[5] = BlockBarStyle(3, 
	//	"  ██"
	//	"██  "
	//	"      ");

	//BlockStyles[6] = BlockBarStyle(4, 
	//	"  █    "
	//	"  █    "
	//	"  █    "
	//	"  █    ");

	//BlockStyles[7] = BlockBarStyle(2, 
	//	"█  "
	//	"  █");

	//BlockStyles[8] = BlockBarStyle(2, 
	//	"  █"
	//	"██");

	//BlockStyles[9] = BlockBarStyle(3, 
	//	"  █  "
	//	"  █  "
	//	"  █  ");

	//BlockStyles[10] = BlockBarStyle(3, 
	//	"█    "
	//	"  █  "
	//	"    █");

	//BlockStyles[11] = BlockBarStyle(3, 
	//	"█    "
	//	"    █"
	//	"    █");

	//BlockStyles[12] = BlockBarStyle(3, 
	//	"█  █"
	//	"      "
	//	"█  █");

	//BlockStyles[13] = BlockBarStyle(4, 
	//	"  █    "
	//	"  █    "
	//	"  █    "
	//	"████");

	BlockStyles[0] = BlockBarStyle(2, 
		"11"
		"11");

	BlockStyles[1] = BlockBarStyle(3, 
		"010"
		"111"
		"000");

	BlockStyles[2] = BlockBarStyle(3, 
		"100"
		"111"
		"000");

	BlockStyles[3] = BlockBarStyle(3, 
		"001"
		"111"
		"000");

	BlockStyles[4] = BlockBarStyle(3, 
		"110"
		"011"
		"000");

	BlockStyles[5] = BlockBarStyle(3, 
		"011"
		"110"
		"000");

	BlockStyles[6] = BlockBarStyle(4, 
/*		"1000"
		"1000"
		"1000"
		"1000"*/
		"0100"
		"0100"
		"0100"
		"0100");

	BlockStyles[7] = BlockBarStyle(2, 
		"10"
		"01");

	BlockStyles[8] = BlockBarStyle(2, 
		"01"
		"11");

	BlockStyles[9] = BlockBarStyle(3, 
		"010"
		"010"
		"010");

	BlockStyles[10] = BlockBarStyle(3, 
		"100"
		"010"
		"001");

	BlockStyles[11] = BlockBarStyle(3, 
		"100"
		"001"
		"001");

	BlockStyles[12] = BlockBarStyle(3, 
		"101"
		"000"
		"101");

	BlockStyles[13] = BlockBarStyle(4, 
		"0100"
		"0100"
		"0100"
		"1111");

	for (int i=0;i<BlockStyleNum;i++)
	{
		BlockStyles[i].ID = i;
	}

	for (int i=0;i<MaxBlockColor;i++)
	{
		float h, s, l;
		rgb2hsl(Color::colors[i]->r, Color::colors[i]->g, Color::colors[i]->b, h,s,l);
		BlockBarStyle::colors[i].SetFromHLS(h,0.99f,s,1);
	}
	m_gameRect = RectF(G_Window->m_iWidth/2-300,G_Window->m_iHeight/2-300,600,600);
	m_scorePannelRect = RectF(m_gameRect.x+362,m_gameRect.y+19,206,281);

	//
	for(int i = 0; i < m_allPlayerNum; i++)
	{
		TetrisPlayer* player = dynamic_cast<TetrisPlayer*>(m_miniPlayer[i]);

		if (player == m_myRolePlayer)
		{
			RectF blockRect(m_gameRect.x+47,m_gameRect.y+18,293,563);
			player->m_blockRect = blockRect;
			player->m_blockExtend = vec2(blockRect.width/BlockNumW,blockRect.height/BlockNumH);
		}
		else
		{
			RectF blockRect(m_gameRect.x+365,m_gameRect.y+318,205,267);
			player->m_blockRect = blockRect;
			player->m_blockExtend = vec2(blockRect.width/BlockNumW,blockRect.height/BlockNumH);
		}

		m_miniPlayer[i]->Start();
	}

	m_bEndGame=false;

	//进入miniplaygui,(选人、选关卡都已在房间里进行完毕)。
	if(GetStyle()) G_GuiMgr->PushGui(GetStyle()->playGUI.c_str(),GL_DIALOG);
	return true;
}
bool MiniGameTetris::ReStart()
{
	for(int i = 0; i < m_allPlayerNum; i++)
	{
		TetrisPlayer* player = dynamic_cast<TetrisPlayer*>(m_miniPlayer[i]);
		m_miniPlayer[i]->Start();
	}
	m_bEndGame=false;
	return true;
}
MiniPlayer* MiniGameTetris::CreatePlayer()
{
	return new TetrisPlayer;
}

MiniPlayer* MiniGameTetris::CreateRobot()
{
	return new TetrisPlayerRobot;
}

MiniPlayer* MiniGameTetris::CreateRole()
{
	m_myRolePlayer = new TetrisPlayerRole;
	return m_myRolePlayer;
}


bool MiniGameTetris::Stop()
{
	{
		if (m_myPlayer && m_myPlayer->m_liveNum>0)
		{
			G_GuiMgr->GetGui<Rpg_ResultDialog>()->ShowResult(true);
		}
		else
		{
			G_GuiMgr->GetGui<Rpg_ResultDialog>()->ShowResult(false);
		}
		G_GuiMgr->PushGui("Rpg_ResultDialog",GL_DIALOGBOTTOM); 
	}
	return MiniGame::Stop();
}

bool MiniGameTetris::Render()
{
	G_RendDriver->BeginUI();
	G_RendDriver->Color4f(1,1,1,1);
	G_RendDriver->SetRenderStateEnable(RS_BLEND,true);
	G_RendDriver->BlendFunc(Blend_Filter);
	G_ShaderMgr->PushShader();

	m_frameTex->Bind();
	G_RendDriver->DrawTextureRect(m_gameRect);

	const int Left = m_scorePannelRect.x+96;

	得分
	char buf[256];
	//sprintf(buf,"%d", m_myRolePlayer->m_score);
	//G_FontMgr->TextAtPos(vec2(Left,188),buf);

	if (m_myRolePlayer)
	{
		//难度
		for(int i = 0; i < m_myRolePlayer->m_diffcuty; i++)
		{
			m_diffcutyIcon->Bind();
			G_RendDriver->DrawTextureRect(RectF(Left+i*28,m_scorePannelRect.y+200,28,28));
		}

		//生命
		for(int i = 0; i < m_myRolePlayer->m_liveNum; i++)
		{
			m_lifeIcon->Bind();
			G_RendDriver->DrawTextureRect(RectF(Left+i*28,m_scorePannelRect.y+241,28,28));
		}
		//下一个
		m_myRolePlayer->m_nextBlockBar->DrawUI(vec2I(m_scorePannelRect.x+62,m_scorePannelRect.y+80));

	}

	//对手名字
	TetrisPlayer* otherPlayer = GetOtherPlayer(m_myRolePlayer);
	if (otherPlayer)
	{
		sprintf(buf,"%s", otherPlayer->GetPlayerInfo()->playerName);
		G_FontMgr->TextAtPos(vec2(Left,otherPlayer->m_blockRect.y),buf);
	}

	for(int i = 0; i < m_allPlayerNum; i++)
	{
		m_miniPlayer[i]->Render();
	}

	G_RendDriver->EndUI();
	G_ShaderMgr->PopShader();
	return true;
}

void MiniGameTetris::RenderUI()
{
	Render();
}

bool MiniGameTetris::Update()
{
	if(m_bEndGame)
		return true;
	for(int i = 0; i < m_allPlayerNum; i++)
	{
		m_miniPlayer[i]->Update();
	}

	return true;
}

bool MiniGameTetris::Free()
{
	MiniGame::Free();
	return true;
}

bool MiniGameTetris::IsEnd()
{
	return m_bEndGame;
}

int  MiniGameTetris::ProcessPacketCmd(PacketBase* packet)
{
	int cmd;
	packet->ReadValue(cmd);
	switch(cmd)
	{
	case CMD_CurBlockBar:
		{
			int roomSlot;
			packet->ReadValue(roomSlot);
			TetrisPlayer* player = (TetrisPlayer*)this->GetPlayerFromSlot(roomSlot);

			int ID;
			//同步bar的移动
			packet->ReadValue(player->m_curBlockBar->m_point.x); 
			packet->ReadValue(player->m_curBlockBar->m_point.y);
			packet->ReadValue(player->m_curBlockBar->m_curRot);
			packet->ReadValue(ID);
			//省了newblock cmd
			player->m_curBlockBar->m_style = &BlockStyles[ID];
			player->Update(); //连续收到两个消息 前一个不能无效
		}
		break;
	//case CMD_GameOver:
	//	{
	//		int turn = 0;
	//		packet->ReadValue(turn);
	//		m_winnerTurn = turn;
	//		m_turnTime = 0;
	//		m_gameStatus = Resulting;

	//		char sound[256];
	//		if (m_winnerTurn == m_lordTurn)
	//		{
	//			sprintf(sound,"data/sound/poker/play_lord_win");
	//		}
	//		else
	//		{
	//			sprintf(sound,"data/sound/poker/play_farmer_win");
	//		}
	//		if (m_winnerTurn%2) //
	//			strcat(sound,"_femail.wav");
	//		else
	//			strcat(sound,".wav");
	//		m_players[m_winnerTurn]->m_sound->PlaySound__(sound);
	//	}
	//	break;
	//case CMD_Restart:
	//	Free();
	//	Start();
	//	break;
	}
	return 0;
}

TetrisPlayer* MiniGameTetris::GetOtherPlayer(TetrisPlayer* self)
{
	//对手
	for(int i = 0; i < m_allPlayerNum; i++)
	{
		if (self->m_roomSlot != m_miniPlayer[i]->m_roomSlot)
		{
			return (TetrisPlayer*)m_miniPlayer[i];
		}
	}
	return NULL;
}

void MiniGameTetris::OnSize()
{
	m_gameRect = RectF(G_Window->m_iWidth/2-300,G_Window->m_iHeight/2-300,600,600);
	m_scorePannelRect = RectF(m_gameRect.x+362,m_gameRect.y+19,206,281);
}


const char* TetrisCmdToString(int enumeration)
{
	switch(enumeration)
	{
	case CMD_CurBlockBar:return "CMD_CurBlockBar";		
	case CMD_Vanishing  :return "CMD_Vanishing  ";		
	case CMD_ReLifing   :return "CMD_ReLifing   ";		
	case CMD_GameOver   :return "CMD_GameOver   ";		
	case CMD_Restart    :return "CMD_Restart    ";	
	default             :return "CMD_unknow";
	}
	return "CMD_unknow";
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值