联机版的连连看源代码

8号了,水饺还没馊,就着点凉水继续写作。

话说连连看这个小游戏可以联机玩吗,如果玩的时候自己实在眼拙连不上,想要借助猪队友之力应该也是可以的吧。

联机可以有两种模式,一种是合作模式,没有加多线程锁一类的东西,谁先点到消除谁的。另一种是竞争模式,右下角显示对手局面,比比看谁消的快。

同样可以有自动挂机算法,方便npc参战。

显示上采用统一的架构,可以平面显示,也可以任意视角3D显示。

 

代码比较简单

游戏类:

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

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

enum MiniLLKCmd
{
	CMD_ShuffleLLK,//开局洗牌
	CMD_RefreshLLK,//无可连接时刷牌
	CMD_Link      ,      
	CMD_GameOver  ,
	CMD_Restart   ,
};
const char* LLKCmdToString(int enumeration);

class LLKPlayer;
class LLKPlayerRole;

#define BLANK     -1                  //空方块(没有任何动物)
#define FRONTWIDTH	    41			    //前面方块的宽度
#define FRONTHEIGHT	    51			    //前面方块的高度
#define BKWIDTH	        46					//背景方块的宽度
#define BKHEIGHT        56					//背景方块的高度

//单人 双人休闲
//人机
//双人 四人比赛
//双人组队 比赛
class MiniGameLLK:public MiniGame
{
public:
	MiniGameLLK();
	virtual ~MiniGameLLK();

	virtual bool KeepResource(bool once,int& circle,String& nextTip);
	virtual bool Start();
	virtual bool Stop();
	virtual bool Render();
	virtual void RenderUI();
	virtual bool Update();
	virtual bool Free();
	virtual bool IsEnd();

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

	void  UpdateGameRect();

	LLKPlayer* GetTurnPlayer();	

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

	void ShuffleCard();     //开局洗牌
	void RefreshCard();     //无可连接时刷牌
public:
		
	//给定的2方块是否可连通消除
	bool CheckLink(const vec2I& p1,const vec2I& p2,int& cornerNum,vec2I& corner1,vec2I& corner2);

	//直接连通
	bool IsLinkX(int x,int y1,int y2);
	bool IsLinkY(int x1,int x2,int y);

	//1直角连通
	bool OneCornerLink(int x1,int y1,int x2,int y2,vec2I& corner);
	//2拐角连通
	bool TwoCornerLink(int x1,int y1,int x2,int y2,vec2I& corner1,vec2I& corner2);

	bool YThrough(int x,int y,bool bAdd);
	bool XThrough(int x,int y,bool bAdd);

	bool LineThrough(int x1,int x2,int y1,int y2);

	vec2 GetBlockCenPos(const vec2I& pos);
	vec2I Pos2Cell(const vec2I& pos);
	void FindTip();

	int  GetMapData(const vec2I& point);
	bool SendLink(int roomSlot,const vec2I& point1,const vec2I& point2);

	RectF   m_gameRect;
	char*	m_mapData;     
	int		m_nRow;		  //行数
	int		m_nCol;		  //列数     
	int     m_level;      //

	vec2I	m_pointTip1;        
	vec2I	m_pointTip2;   

	TexturePtr m_texBack;
	TexturePtr m_textureMan[14];	//十四种图标
	TexturePtr m_texture3DFrames;	
	TexturePtr m_textureFocusFrames;
	TexturePtr m_textureTipFrames;
	TexturePtr m_textureAnimal;	
	TexturePtr m_textureLine;	

	TexturePtr m_thinkTexture[4];

	LLKPlayerRole* m_myRolePlayer;
};
extern MiniGameLLK* G_LLKGame;
#endif 

//========================================================
//  @Date:     2016.05
//  @File:     SourceDemoClient/LLK/MiniGameLLK.cpp
//  @Brief:     MiniGameLLK
//  @Author:     LouLei
//  @Email:  twopointfive@163.com
//  @Copyright (Crapell) - All Rights Reserved
//========================================================
 
#include "General/Pch.h"
#include "General/Window.h"
#include "General/Timer.h"
#include "Gui/GuiMgr.h"
#include "Gui/RpgGuis.h"
#include "Input/InputMgr.h"
#include "LLK/LLKPlayer.h"
#include "LLK/MiniGameLLK.h"
#include "Render/RendDriver.h"
#include "Render/Shader.h"
#include "LLK/MiLLK_PlayGui.h"
#include "Rpg/SyncGameInfo.h"
#include "Packet/PacketMiniGame.h"
#include "Net/PacketList.h"
#include "General/Pce.h"
#include "Render/MC_MovieClip.h"
#include "Render/Camera.h"


MiniGameLLK* G_LLKGame;


MiniGameLLK::MiniGameLLK()
:m_mapData(NULL)
{
	G_LLKGame = this;
	CmdEnumToString = LLKCmdToString;
}

MiniGameLLK::~MiniGameLLK()
{
	G_LLKGame = NULL;
}

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

	G_TextureMgr->AddTexture(m_texBack            ,"data/minigame/llk/backframe.png");
	G_TextureMgr->AddTexture(m_texture3DFrames    ,"data/minigame/llk/frames.png");
	G_TextureMgr->AddTexture(m_textureFocusFrames ,"data/minigame/llk/frameselected.png");
	G_TextureMgr->AddTexture(m_textureTipFrames   ,"data/minigame/llk/frametip.png");
	G_TextureMgr->AddTexture(m_textureAnimal      ,"data/minigame/llk/animal.png");
	G_TextureMgr->AddTexture(m_textureLine        ,"data/minigame/llk/line.png");

	m_pointTip1 = vec2I(BLANK,BLANK);
	m_pointTip2 = vec2I(BLANK,BLANK);

	m_nRow=7;
	m_nCol=12;
	m_level = 1;

	m_mapData=new char[m_nRow*m_nCol];


	if (m_bHost)
	{
		//生成随机地图
		ShuffleCard();
		C2SPacketMiniGameCmd packet;
		packet.WriteHeader();
		packet.WriteValue(CMD_ShuffleLLK);  
		packet.WriteArray(m_mapData,m_nRow*m_nCol);        //发送seed level row col即可
		G_MiniGame->SendPacketToOther(&packet);
	}
	else
	{
		//
		for(int i=0;i<m_nCol*m_nRow;i++)
		{
			m_mapData[i] = 0;//BLANK;
		}
	}

	m_gameState= MS_Gamming;

	for(int i = 0; i < m_allPlayerNum; i++)
	{
		MyRoomPlayerInfo* playerInfo = G_SyncMyRoomInfo->GetPlayerFromIndex(i);
		if(playerInfo)
		{

		}
//		dynamic_cast<LLKPlayer*>(m_miniPlayer[i])->m_side = i==0?SideRed:SideBlack;
		//dynamic_cast<LLKPlayer*>(m_miniPlayer[i])->m_side = i==0?SideBlack:SideRed;

		m_miniPlayer[i]->Start();
	}

	//
	if (m_movieScene == NULL)
	{
		LoadConfig loader(LoadConfig::GenDonotReShrinkBound, true, true);
		m_movieScene = new RendSys::MovieClip;
		m_movieScene->LoadFromFile("data/minigame/llk/board.movie", &loader);

		Frame frame;
		frame.SetPos(m_startPos);
		m_movieScene->SetProgramFrame(&frame);
		m_movieScene->Advance();
	}

	if (m_movieScene->IsLoadComplete() == false)
	{
		m_gameState = MS_End;
		return false;
	}

	UpdateGameRect();

	//进入miniplaygui,(选人、选关卡都已在房间里进行完毕)。
	if(GetStyle()) G_GuiMgr->PushGui(GetStyle()->playGUI.c_str(),GL_DIALOG);

	//设置摄像机
	CameraCtrlerTarget* ctrler = new CameraCtrlerTarget;
	ctrler->SetDistToTar(60);
	ctrler->SetTarPos(m_startPos);
	G_Camera->PushCtrler(ctrler);	
	G_Camera->SetEuler(0, -60, 0);
	//片头摄像机
	PushIntroCamera();

	return true;
}
MiniPlayer* MiniGameLLK::CreatePlayer()
{
	return new LLKPlayer;
}

MiniPlayer* MiniGameLLK::CreateRobot()
{
	return new LLKPlayerRobot;
}

MiniPlayer* MiniGameLLK::CreateRole()
{
	m_myRolePlayer = new LLKPlayerRole;
	return m_myRolePlayer;
}
bool MiniGameLLK::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); 
	}
	SafeDeleteArray(m_mapData);
	return MiniGame::Stop();
}

void MiniGameLLK::ShuffleCard()
{
	//生成随机地图  42种动物图案
	//必须正好匹配n套
	int n = 4; //2 3 4 6  (7*12整除)
	int index = 0;
	for(int  i=0;i<(m_nCol*m_nRow)/n;i++)
	{
		for(int j=0;j<n;j++)
		{
			m_mapData[index++] = i;
		}
	}


	//刷牌  随机i-1中的任意一个数与i交换
	for (int i = 2; i < m_nRow*m_nCol; i++)
	{
		int ran = Rand()%i;
		char temp = m_mapData[ran];
		m_mapData[ran] = m_mapData[i];
		m_mapData[i] = temp;
	}
}

void MiniGameLLK::RefreshCard()
{
	G_LLKGame->PlaySound__("data/sound/event_levelup.wav");
	//刷牌  随机i-1中的任意一个数与i交换
	for (int i = 2; i < m_nRow*m_nCol; i++)
	{
		int ran = Rand()%i;
		char temp = m_mapData[ran];
		m_mapData[ran] = m_mapData[i];
		m_mapData[i] = temp;
	}
}

LLKPlayer* MiniGameLLK::GetTurnPlayer()
{
	return dynamic_cast<LLKPlayer*>(m_miniPlayer[m_curSide]);
	//for(int i = 0; i < m_allPlayerNum; i++)
	//{
	//	LLKPlayer* player = dynamic_cast<LLKPlayer*>(m_miniPlayer[i]);
	//	if (player->m_side == m_curSide)
	//	{
	//		return player;
	//	}
	//}
	return NULL;
}


bool MiniGameLLK::KeepResource(bool once,int& circle,String& nextTip)
{

	G_TextureMgr->AddTexture(m_thinkTexture[0],"data/minigame/poker/think00.png");
	G_TextureMgr->AddTexture(m_thinkTexture[1],"data/minigame/poker/think01.png");
	G_TextureMgr->AddTexture(m_thinkTexture[2],"data/minigame/poker/think02.png");
	G_TextureMgr->AddTexture(m_thinkTexture[3],"data/minigame/poker/think03.png");
	return true;
}

bool MiniGameLLK::Render()
{
	if (m_3dMode)
	{
		G_RendDriver->EndUI();
		if(m_movieScene==NULL
			||m_movieScene->IsLoadComplete()==false)
			return false;

		m_movieScene->RendClip();
		G_RendDriver->PushMatrix();
		G_RendDriver->MultMatrix(mat2Dto3D);
	}
	else
	{
		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_texBack->Bind();
		G_RendDriver->DrawTextureRect(BoardRect2D);
	}

	G_RendDriver->DepthMask(false);

	if (G_ShaderMgr&& G_ShaderMgr->m_curEffect)
	{
		G_ShaderMgr->MapChangeParm();
	}

	//G_RendDriver->SetRenderStateEnable(RS_DEPTH_TEST,false);//可能穿透桌子
	for(int i=0;i<m_nRow;i++)
	{
		for(int j=0;j<m_nCol;j++)
		{			
			if(m_mapData[i*m_nCol+j]==BLANK)
			{
				continue;
			}
			//绘制方块边框
			m_texture3DFrames->Bind();
			int ran = int((sin(1.23f*i+3.2f)+sin(1.789f*j))*100000)%6;
			G_RendDriver->DrawTextureRect(RectF(m_gameRect.x+j*FRONTWIDTH,m_gameRect.y+i*FRONTHEIGHT,BKWIDTH,BKHEIGHT),RectF(0,ran/6.0f,1,1.0f/6));

			//绘制动物 42种动物图案
			m_textureAnimal->Bind();
			G_RendDriver->DrawTextureRect(RectF(m_gameRect.x+j*FRONTWIDTH,m_gameRect.y+i*FRONTHEIGHT,FRONTWIDTH-2,FRONTHEIGHT-12),
				RectF(0,m_mapData[i*m_nCol+j]/42.0f,1,1.0f/42));

		}
	}

	//
	if(m_pointTip1.x!=BLANK
		&&m_mapData[m_pointTip1.y*m_nCol+m_pointTip1.x]!=BLANK)
	{
		//绘制提示效果
		m_textureTipFrames->Bind();
		G_RendDriver->DrawTextureRect(RectF(m_gameRect.x+m_pointTip1.x*FRONTWIDTH,m_gameRect.y+m_pointTip1.y*FRONTHEIGHT,BKWIDTH,BKHEIGHT));
	}
	if(m_pointTip2.x!=BLANK
		&&m_mapData[m_pointTip2.y*m_nCol+m_pointTip2.x]!=BLANK)
	{
		//绘制提示效果
		m_textureTipFrames->Bind();
		G_RendDriver->DrawTextureRect(RectF(m_gameRect.x+m_pointTip2.x*FRONTWIDTH,m_gameRect.y+m_pointTip2.y*FRONTHEIGHT,BKWIDTH,BKHEIGHT));
	}

	画等级
	//m_rectLevel = RectF(BoardRect2D.x+633, BoardRect2D.y+36, 39, 23);
	//if(m_rectLevel.IsPointIn(G_Mouse->GetMousePos()))
	//{
	//	G_RendDriver->Color4f(1, 1, 0, 1);
	//}
	//else
	//{
	//	G_RendDriver->Color4f(1, 0, 0, 1);
	//}
	//m_texLcdNumber->Bind();
	//DrawLcd(3,m_Level+1, m_rectLevel);
	//G_RendDriver->Color4f(1, 1, 1, 1);

	//画时间和得分
	m_texLcdNumber->Bind();
	G_RendDriver->Color4f(1, 0, 0, 1);
	DrawLcd(3,m_gameTime, RectF(BoardRect2D.x +623, BoardRect2D.y+223, 39, 23));
	//DrawLcd(4,m_stepNum, RectF(BoardRect2D.x+633, BoardRect2D.y +89, 52, 23));


	G_RendDriver->DepthMask(true);

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

	if (m_3dMode)
	{
		G_RendDriver->PopMatrix();
	}
	else
	{
		G_RendDriver->EndUI();
		G_ShaderMgr->PopShader();
	}
	return true;
}

void MiniGameLLK::RenderUI()
{
	Render();
}
bool MiniGameLLK::Update()
{
	MiniGame::Update();
	UpdateGameRect();

	m_turnTime += G_Timer->GetStepTimeLimited();

	for(int i = 0; i < m_allPlayerNum; i++)
	{
		dynamic_cast<LLKPlayer*>(m_miniPlayer[i])->Update();
	}

	if(m_pointTip1.x==BLANK
		||m_mapData[m_pointTip1.y*m_nCol+m_pointTip1.x]==BLANK
		||m_pointTip2.x==BLANK
		||m_mapData[m_pointTip2.y*m_nCol+m_pointTip2.x]==BLANK)
	{
		FindTip();
	}

	bool gameEnd = true;
	for(int i=0;i<m_nRow*m_nCol;i++)
	{
		if(m_mapData[i] != BLANK)
		{
			gameEnd = false;
		}
	}

	if (gameEnd)
	{
		m_gameState = MS_End;
	}
	else
	{
		if (m_bHost
			&&m_pointTip1.x==BLANK)
		{
			//无可连接
			RefreshCard();
			C2SPacketMiniGameCmd packet;
			packet.WriteHeader();
			packet.WriteValue(CMD_RefreshLLK);  
			packet.WriteArray(m_mapData,m_nRow*m_nCol);        //发送seed level row col即可
			G_MiniGame->SendPacketToOther(&packet);
			//清除连线
		}
	}
	return true;
}

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

bool MiniGameLLK::IsEnd()
{
	return m_gameState == MS_End;
}

int  MiniGameLLK::ProcessPacketCmd(PacketBase* packet)
{
	int cmd;
	packet->ReadValue(cmd);
	switch(cmd)
	{
	case CMD_ShuffleLLK:
		{
			//todo 只发自己的牌
			packet->ReadArray(m_mapData,m_nRow*m_nCol);
		}
		return 1;
	case CMD_RefreshLLK:
		{
			G_LLKGame->PlaySound__("data/sound/event_levelup.wav");
			//todo 只发自己的牌
			packet->ReadArray(m_mapData,m_nRow*m_nCol);
			//清除连线
		}
		return 1;
	case CMD_Link:
		{
			int roomSlot;
			vec2I point1,point2;
			packet->ReadValue(roomSlot);
			packet->ReadValue(point1);
			packet->ReadValue(point2);
	
			LLKPlayer* player = dynamic_cast<LLKPlayer*>(GetPlayerFromSlot(roomSlot));
			if (player)
			{
				int cornerNum;
				vec2I corner1;
				vec2I corner2;
				if (CheckLink(point1,point2,cornerNum,corner1,corner2))
				{
					//双人同时操作,统一在服务发回消息后再真正消除,这样才能保证每个人的消除序列是完全一样的。
					//否则可能在延迟的若干ms内正好消除了别人已经消除过的块
					G_LLKGame->PlaySound__("data/sound/ui_quit.wav");
					player->m_point1 = point1;
					player->m_point2 = point2;
					player->m_cornerNum = cornerNum;
					player->m_corner[0] = corner1;
					player->m_corner[1] = corner2;
					m_mapData[point1.y*m_nCol+point1.x]=BLANK;
					m_mapData[point2.y*m_nCol+point2.x]=BLANK;
					m_turnTime = 0;
				}
				else
				{
					int a = 0;
					G_LLKGame->PlaySound__("data/sound/ui_disable.wav");
				}
			}
		}
		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;
}



//X直接连通
bool MiniGameLLK::IsLinkX(int x, int y1,int y2)
{
	//保证y1的值小于y2
	if(y1>y2)
	{
		Swap(y1,y2);
	}

	//直通 	
	for(int i=y1+1;i<=y2;i++)
	{
		if(i==y2)
			return true;
		
		if(m_mapData[i*m_nCol+x]!=BLANK)
			break;
	}
	return false;
}

//Y直接连通
bool MiniGameLLK::IsLinkY(int x1,int x2,int y)
{
	if(x1>x2)
	{
		Swap(x1,x2);
	}
	//直通
	for(int i=x1+1;i<=x2;i++)
	{
		if(i==x2)
			return true;
		
		if(m_mapData[y*m_nCol+i]!=BLANK)
			break;
	}
	return false;
}

// 是否直线通
bool MiniGameLLK::LineThrough(int x1,int y1,int x2,int y2)
{
	if (x1==x2)
	{
		if(y1>y2)
			Swap(y1,y2);
		for(int i=y1;i<=y2;i++)
		{
			if(m_mapData[i*m_nCol+x1]!=BLANK)
				return false;
			if(i==y2)
				return true;
		}
	}
	else if(y1==y2)
	{
		if(x1>x2)
			Swap(x1,x2);
		for(int x=x1;x<=x2;x++)
		{
			if(m_mapData[y1*m_nCol+x]!=BLANK)
				return false;
			if(x==x2)
				return true;
		}
	}
	return false;
}

//  1直角连通
bool MiniGameLLK::OneCornerLink(int x1, int y1,int x2, int y2,vec2I& corner)
{
	if(x1>x2)
	{
		Swap(x1,x2);
		Swap(y1,y2);
	}
	bool link = false;
	if(y2<y1)
	{
		if(LineThrough(x1+1,y1,x2,y1)&&LineThrough(x2,y2+1,x2,y1))//右上
		{
			corner = vec2I(x2,y1);
			link = true;
		}
		if(LineThrough(x1,y2,x1,y1-1)&&LineThrough(x1,y2,x2-1,y2))//上右
		{
			corner = vec2I(x1,y2);
			link = true;
		}
	}	
	else
	{
		if(LineThrough(x1+1,y1,x2,y1)&&LineThrough(x2,y1,x2,y2-1))
		{
			corner = vec2I(x2,y1);
			link = true;
		}
		if(LineThrough(x2-1,y2,x1,y2)&&LineThrough(x1,y2,x1,y1+1))
		{
			corner = vec2I(x1,y2);
			link = true;	
		}
	}
	return link;
}

//  2直角连通
bool MiniGameLLK::TwoCornerLink(int x1, int y1, int x2, int y2,vec2I& corner1,vec2I& corner2)
{
	//右通
	if(XThrough(x1+1,y1,true)&&XThrough(x2+1,y2,true))
	{
		int x = max(x1+1,x2+1);
		for (;x<m_nCol;x++)
		{
			if (LineThrough(x,y1,x,y2))
			{
				break;
			}
		}
		corner1 = vec2I(x,y1);
		corner2 = vec2I(x,y2);
		return true;
	}
	//左通
	if(XThrough(x1-1,y1,false)&&XThrough(x2-1,y2,false))
	{
		int x = min(x1-1,x2-1);
		for (;x>=0;x--)
		{
			if (LineThrough(x,y1,x,y2))
			{
				break;
			}
		}
		corner1 = vec2I(x,y1);
		corner2 = vec2I(x,y2);
		return true;
	}
	//上通
	if(YThrough(x1,y1-1,false)&&YThrough(x2,y2-1,false))
	{
		int y = min(y1-1,y2-1);
		for (;y>=0;y--)
		{
			if (LineThrough(x1,y,x2,y))
			{
				break;
			}
		}
		corner1 = vec2I(x1,y);
		corner2 = vec2I(x2,y);
		return true;
	}
	//下通
	if(YThrough(x1,y1+1,true)&&YThrough(x2,y2+1,true))
	{
		int y = max(y1+1,y2+1);
		for (;y<m_nRow;y++)
		{
			if (LineThrough(x1,y,x2,y))
			{
				break;
			}
		}
		corner1 = vec2I(x1,y);
		corner2 = vec2I(x2,y);
		return true;
	}

	bool swapx = false;
	if(x1>x2)
	{
		swapx = true;
		Swap(x1,x2);
		Swap(y1,y2);
	}

	//右
	int x;
	for( x=x1+1;x<m_nCol;x++)
	{
		if(m_mapData[y1*m_nCol+x]>-1)
			break;
		if(OneCornerLink(x,y1,x2,y2,corner2))
		{
			corner1 = vec2I(x,y1);
			if(swapx)Swap(corner1,corner2);
			return true;
		}
	}
	//左
	for(x=x1-1;x>-1;x--)
	{
		if(m_mapData[y1*m_nCol+x]!=BLANK)
			break;
		if(OneCornerLink(x,y1,x2,y2,corner2))
		{
			corner1 = vec2I(x,y1);
			if(swapx)Swap(corner1,corner2);
			return true;
		}
	}
	//上
	int y;
	for( y=y1-1;y>-1;y--)
	{
		if(m_mapData[y*m_nCol+x1]!=BLANK)
			break;
		if(OneCornerLink(x1,y,x2,y2,corner2))
		{
			corner1 = vec2I(x1,y);
			if(swapx)Swap(corner1,corner2);
			return true;
		}
	}
	//下
	for(y=y1+1;y<m_nRow;y++)
	{
		if(m_mapData[y*m_nCol+x1]!=BLANK)
			break;
		if(OneCornerLink(x1,y,x2,y2,corner2))
		{
			corner1 = vec2I(x1,y);
			if(swapx)Swap(corner1,corner2);
			return true;
		}
	}

	return false;
}

bool MiniGameLLK::XThrough(int x, int y, bool bAdd)
{
	if(bAdd)
	{
		for(int i=x;i<m_nCol;i++)
			if(m_mapData[y*m_nCol+i]!=BLANK)
				return false;
	}
	else
	{
		for(int i=0;i<=x;i++)
			if(m_mapData[y*m_nCol+i]!=BLANK)
				return false;
	}
	return true;
}

bool MiniGameLLK::YThrough(int x, int y,bool bAdd)
{
	if(bAdd)
	{
		for(int i=y;i<m_nRow;i++)
			if(m_mapData[i*m_nCol+x]!=BLANK)
				return false;
	}
	else
	{
		for(int i=0;i<=y;i++)
			if(m_mapData[i*m_nCol+x]!=BLANK)
				return false;
	}
	return true;
}

//  判断选中的两个方块是否可以消除
bool MiniGameLLK::CheckLink(const vec2I& p1,const vec2I& p2,int& cornerNum,vec2I& corner1,vec2I& corner2)
{
	cornerNum = -1;
	if (p1.x==p2.x && p1.y==p2.y)
	{
		return false;
	}

	if(GetMapData(p1)!=GetMapData(p2))
		return false;

	if(GetMapData(p1)==BLANK)
		return false;

	//X直连
	if(p1.x==p2.x)
	{
		if(IsLinkX(p1.x,p1.y,p2.y))
		{
			cornerNum = 0;
			return true;
		}
	}
	//Y直连
	else if(p1.y==p2.y)
	{
		if(IsLinkY(p1.x,p2.x,p1.y))
		{
			cornerNum = 0;
			return true;
		}
	}

	//一个转弯直角的联通
	if(OneCornerLink(p1.x,p1.y,p2.x,p2.y,corner1))
	{
		cornerNum = 1;
		return true;
	}
	//两个转弯直角的联通
	else if(TwoCornerLink(p1.x,p1.y,p2.x,p2.y,corner1,corner2))
	{
		cornerNum = 2;
		return true;
	}
	return false;
}

vec2 MiniGameLLK::GetBlockCenPos(const vec2I& pos)
{
	return vec2(m_gameRect.x+pos.x*FRONTWIDTH,m_gameRect.y+pos.y*FRONTHEIGHT)+vec2(BKWIDTH,BKHEIGHT)*0.5f;
}

void MiniGameLLK::FindTip()
{
	vec2I p1(BLANK,BLANK);
	vec2I p2(BLANK,BLANK);
	m_pointTip1 = p1;
	m_pointTip2 = p2;
	int cornerNum;
	vec2I corner1,corner2;
	int block;
	for(int i=0;i<m_nRow;i++)
	{
		for(int j=0;j<m_nCol;j++)
		{			
			block = m_mapData[i*m_nCol+j];
			if(block!=BLANK)
			{
				p1 = vec2I(j,i);
				for(int i2=0;i2<m_nRow;i2++)
				{
					for(int j2=0;j2<m_nCol;j2++)
					{			
						if(m_mapData[i2*m_nCol+j2]==block)
						{
							p2 = vec2I(j2,i2);
							if (CheckLink(p1,p2,cornerNum,corner1,corner2))
							{
								m_pointTip1 = p1;
								m_pointTip2 = p2;
								return;
							}
						}
					}
				}
			}
		}
	}
}

vec2I MiniGameLLK::Pos2Cell(const vec2I& pos)
{
	vec2I point;
	point.x = pos.x -m_gameRect.x;
	point.y = pos.y -m_gameRect.y;

	//1.计算鼠标点击方块的的位置
	int x=point.x/FRONTWIDTH+(point.x%FRONTWIDTH?1:0)-1;
	int y=point.y/FRONTHEIGHT+(point.y%FRONTHEIGHT?1:0)-1;

	if(x<m_nCol&&y<m_nRow)
	{
		return vec2I(x,y);
	}
	return vec2I(-1,-1);
}

int  MiniGameLLK::GetMapData(const vec2I& point)
{
	if(point.x>=0 && point.x<m_nCol)
		return m_mapData[point.y*m_nCol+point.x];
	
	return BLANK;
}

bool MiniGameLLK::SendLink(int roomSlot,const vec2I& point1,const vec2I& point2)
{
	//双人同时操作,统一在服务发回消息后再真正消除,这样才能保证每个人的消除序列是完全一样的。
	C2SPacketMiniGameCmdAll packet;  
	packet.WriteHeader();
	packet.WriteValue(CMD_Link);  
	packet.WriteValue(roomSlot); 
	packet.WriteValue(point1); 
	packet.WriteValue(point2); 
	//G_MiniGame->SendPacketToOther(&packet);
	G_MiniGame->SendPacketToAll(&packet);

#ifdef MiniUnitTest
	//单元测试
	if (IsUnitTesting())
	{
		S2CPacketMiniGameCmd res;
		res.CopyPacket(&packet);
		res.m_res = 0;
		res.SeekPos(PacketBase::HeadSize);
		ProcessPacketCmd(&res);
	}
#endif
	return true;
}

void MiniGameLLK::UpdateGameRect()
{
	float width__  = m_texBack->GetWidth(); 
	float height_  = m_texBack->GetHeight(); 
	SetBoardRect(RectF((G_Window->m_iWidth-width__)/2,(G_Window->m_iHeight-height_)/2,width__,height_), 
		RectF(m_startPos.x-50,m_startPos.z-33,100,66),
		//RectF(m_startPos.x-55,m_startPos.z-38,110,74),
		m_startPos.y+10.1f);

	{
		RectF temp(BoardRect2D.x+28,BoardRect2D.y+25,535,457);
		m_gameRect.width  = m_nCol*FRONTWIDTH +15;
		m_gameRect.height = m_nRow*FRONTHEIGHT+15;
		//if (m_gameRect.width>BoardRect2D.width)
		//{
		//}
		m_gameRect.x = temp.x + (temp.width -m_gameRect.width )*0.5f;
		m_gameRect.y = temp.y + (temp.height-m_gameRect.height)*0.5f;
	}
}


const char* LLKCmdToString(int enumeration)
{
	switch(enumeration)
	{
	case CMD_ShuffleLLK:return "CMD_ShuffleLLK";		
	case CMD_RefreshLLK:return "CMD_RefreshLLK";		
	case CMD_Link      :return "CMD_Link      ";		
	case CMD_GameOver  :return "CMD_GameOver  ";		
	case CMD_Restart   :return "CMD_Restart   ";		
	default             :return "CMD_unknow";
	}
	return "CMD_unknow";
}

玩家类: 

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

#ifndef  __LLKPlayer__H__
#define  __LLKPlayer__H__

#include "Rpg/MiniGame.h"


class LLKPlayer: public MiniPlayer
{
public:
	LLKPlayer();
	virtual ~LLKPlayer();

	virtual bool Start();
	//virtual bool Stop();
	virtual void Update();

	virtual void Render();

	int     m_side;       //
	vec2I	m_point1;     //鼠标选中的方块
	vec2I	m_point2;  

	int     m_cornerNum;
	vec2I   m_corner[2];
};


class LLKPlayerRobot: public LLKPlayer
{
public:
	LLKPlayerRobot();
	virtual ~LLKPlayerRobot();

	//virtual bool Start();
	virtual bool Stop();
	virtual void Update();
	void Think();
	bool m_workingWithAI;

};


class LLKPlayerRole: public LLKPlayerRobot
{
public:
	LLKPlayerRole();
	virtual ~LLKPlayerRole();

	//virtual bool Start();
	virtual bool Stop();
	virtual void Update();
	virtual void Render();

};

#endif

//========================================================
//  @Date:     2016.05
//  @File:     SourceDemoClient/CarRacing/RacingCar.cpp
//  @Brief:     RacingCar
//  @Author:     LouLei
//  @Email:  twopointfive@163.com
//  @Copyright (Crapell) - All Rights Reserved
//========================================================
 
#include "General/Pch.h"
#include "General/Window.h"
#include "LLK/LLKPlayer.h"
#include "LLK/MiniGameLLK.h"
#include "General/Timer.h"
#include "Rpg/SyncGameInfo.h"
#include "Sound/SoundManager.h"
#include "Packet/PacketMiniGame.h"
#include "Render/RendDriver.h"
#include "General/Pce.h"
#include "Input/InputMgr.h"
#include "Gui/GuiMgr.h"

LLKPlayer::LLKPlayer()
{
}
LLKPlayer::~LLKPlayer()
{
}


bool LLKPlayer::Start()
{
	MiniPlayer::Start();
	m_point1= vec2I(BLANK,BLANK);
	m_cornerNum = -1;
	return true;
}

void LLKPlayer::Update()
{
	MiniPlayer::Update();

}

void LLKPlayer::Render()
{
	显示思考中
	//if(G_LLKGame->GetGameState()==MS_Gamming
	//	&&G_LLKGame->m_curSide == m_side)
	//{
	//	//m_ctrlThink->SetVisible(true);
	//	int index = int(G_Timer->GetAccumTime()*10)%4;
	//	Texture* texture = G_LLKGame->m_thinkTexture[index];
	//	texture->Bind();

	//	//if(m_screenPos == SP_Down)
	//	if(dynamic_cast<LLKPlayerRole*>(this))
	//	{
	//		G_RendDriver->DrawTextureRect(vec2(G_Window->m_iWidth-G_LLKGame->Offset.x ,  G_Window->m_iHeight- G_LLKGame->Offset.y-texture->GetHeight()));
	//	}
	//	else
	//	{
	//		G_RendDriver->DrawTextureRect(vec2(G_Window->m_iWidth-G_LLKGame->Offset.x ,  G_LLKGame->Offset.y));
	//	}
	//}

	G_RendDriver->DepthMask(false);

	选中
	if(m_point1.x!=BLANK
		&&G_LLKGame->GetMapData(m_point1)!=BLANK)
	{
		//绘制选中效果
		G_LLKGame->m_textureFocusFrames->Bind();
		vec2 pos = G_LLKGame->GetBlockCenPos(m_point1);
		G_RendDriver->DrawTextureRect(RectF(pos.x-BKWIDTH/2,pos.y-BKHEIGHT/2,BKWIDTH,BKHEIGHT));
	}

	G_LLKGame->m_textureLine->Bind();
	if (m_cornerNum==0)
	{
		//G_RendDriver->DrawLine(G_LLKGame->GetBlockCenPos(m_point1),G_LLKGame->GetBlockCenPos(m_point2));
		RectF rect;
		rect.FromPoint(G_LLKGame->GetBlockCenPos(m_point1),G_LLKGame->GetBlockCenPos(m_point2));
		rect.MergePoint(G_LLKGame->GetBlockCenPos(m_point1)+vec2(5,5));
		G_RendDriver->DrawTextureRect(rect,RectF(0,0,1,1),ET_FITFRAME);
	}
	else if (m_cornerNum==1)
	{
		//G_RendDriver->DrawLine(G_LLKGame->GetBlockCenPos(m_point1),G_LLKGame->GetBlockCenPos(m_corner[0]));
		//G_RendDriver->DrawLine(G_LLKGame->GetBlockCenPos(m_corner[0]),G_LLKGame->GetBlockCenPos(m_point2));
		RectF rect;
		rect.FromPoint(G_LLKGame->GetBlockCenPos(m_point1),G_LLKGame->GetBlockCenPos(m_corner[0]));
		rect.MergePoint(G_LLKGame->GetBlockCenPos(m_point1)+vec2(5,5));
		G_RendDriver->DrawTextureRect(rect,RectF(0,0,1,1),ET_FITFRAME);

		rect.FromPoint(G_LLKGame->GetBlockCenPos(m_corner[0]),G_LLKGame->GetBlockCenPos(m_point2));
		rect.MergePoint(G_LLKGame->GetBlockCenPos(m_corner[0])+vec2(5,5));
		G_RendDriver->DrawTextureRect(rect,RectF(0,0,1,1),ET_FITFRAME);
	}
	else if (m_cornerNum==2)
	{
		//G_RendDriver->DrawLine(G_LLKGame->GetBlockCenPos(m_point1),G_LLKGame->GetBlockCenPos(m_corner[0]));
		//G_RendDriver->DrawLine(G_LLKGame->GetBlockCenPos(m_corner[0]),G_LLKGame->GetBlockCenPos(m_corner[1]));
		//G_RendDriver->DrawLine(G_LLKGame->GetBlockCenPos(m_corner[1]),G_LLKGame->GetBlockCenPos(m_point2));

		RectF rect;
		rect.FromPoint(G_LLKGame->GetBlockCenPos(m_point1),G_LLKGame->GetBlockCenPos(m_corner[0]));
		rect.MergePoint(G_LLKGame->GetBlockCenPos(m_point1)+vec2(5,5));
		G_RendDriver->DrawTextureRect(rect,RectF(0,0,1,1),ET_FITFRAME);

		rect.FromPoint(G_LLKGame->GetBlockCenPos(m_corner[0]),G_LLKGame->GetBlockCenPos(m_corner[1]));
		rect.MergePoint(G_LLKGame->GetBlockCenPos(m_corner[0])+vec2(5,5));
		G_RendDriver->DrawTextureRect(rect,RectF(0,0,1,1),ET_FITFRAME);

		rect.FromPoint(G_LLKGame->GetBlockCenPos(m_corner[1]),G_LLKGame->GetBlockCenPos(m_point2));
		rect.MergePoint(G_LLKGame->GetBlockCenPos(m_corner[1])+vec2(5,5));
		G_RendDriver->DrawTextureRect(rect,RectF(0,0,1,1),ET_FITFRAME);
	}
	G_RendDriver->DepthMask(true);
}



LLKPlayerRobot::LLKPlayerRobot()
{
	m_workingWithAI = true;
}
LLKPlayerRobot::~LLKPlayerRobot()
{
}
void LLKPlayerRobot::Update()
{
	if(G_LLKGame->GetGameState() == MS_End)
	{
		return;
	}


	if (/*G_LLKGame->m_curSide == m_side
		&& */G_LLKGame->GetTurnTime()>3.0f //思考时间
		)
	{
		Think();
	}
}
void LLKPlayerRobot::Think()
{
	PROFILEFUN("MiniGameLLK::Think();",0.0f,ALWAYSHIDE);

	vec2I p1(BLANK,BLANK);
	vec2I p2(BLANK,BLANK);
	m_point1 = p1;
	m_point2 = p2;
	m_cornerNum = -1;
	int cornerNum;
	vec2I corner1,corner2;
	int block;
	//for(int i=0;i<G_LLKGame->m_nRow;i++)
	for(int i=G_LLKGame->m_nRow-1;i>=0;i--)
	{
		for(int j=0;j<G_LLKGame->m_nCol;j++)
		{			
			block = G_LLKGame->GetMapData(vec2I(j,i));
			if(block!=BLANK)
			{
				p1 = vec2I(j,i);
				for(int i2=0;i2<G_LLKGame->m_nRow;i2++)
				{
					for(int j2=0;j2<G_LLKGame->m_nCol;j2++)
					{			
						if(G_LLKGame->GetMapData(vec2I(j2,i2))==block)
						{
							p2 = vec2I(j2,i2);
							if (G_LLKGame->CheckLink(p1,p2,cornerNum,corner1,corner2))
							{
								//双人同时操作,统一在服务发回消息后再真正消除,这样才能保证每个人的消除序列是完全一样的。
								m_cornerNum = -1;
								//G_LLKGame->PlaySound__("data/sound/ui_quit.wav");
								//m_point1 = p1;
								//m_point2 = p2;
								//G_LLKGame->m_mapData[point1.y*m_nCol+point1.x]=BLANK;
								//G_LLKGame->m_mapData[point2.y*m_nCol+point2.x]=BLANK;
								//G_LLKGame->m_turnTime = 0;

								G_LLKGame->SendLink(m_roomSlot,p1,p2);

								return;
							}
						}
					}
				}
			}
		}
	}
}


LLKPlayerRole::LLKPlayerRole()
{
	m_workingWithAI = false;
}
LLKPlayerRole::~LLKPlayerRole()
{
}

void LLKPlayerRole::Update()
{
	if(m_workingWithAI)
	{
		LLKPlayerRobot::Update();
	}
	else
	{
		vec2 pos = G_LLKGame->GetMousePos();

		if (G_LLKGame->IsButtonDowning(MOUSE_LEFT))
		{
			vec2I point = G_LLKGame->Pos2Cell(vec2I(pos.x,pos.y));

			//鼠标点击方块
			if(point.x>=0&&G_LLKGame->GetMapData(point)!= BLANK)
			{
				//尚未记录第一个方块 || 已经消除
				if(m_point1.x==BLANK
					||G_LLKGame->GetMapData(m_point1)==BLANK)
				{
					G_LLKGame->PlaySound__("data/sound/ui_click.wav");
					m_point1=point;
					m_cornerNum = -1;
				}
				else
				{ 
					//是否点击的方块非本身
					if(m_point1.x!=point.x||m_point1.y!=point.y)
					{

						if (G_LLKGame->CheckLink(m_point1,point,m_cornerNum,m_corner[0],m_corner[1]))
						{
							//双人同时操作,统一在服务发回消息后再真正消除,这样才能保证每个人的消除序列是完全一样的。
							m_cornerNum = -1;
							//G_LLKGame->PlaySound__("data/sound/ui_quit.wav");
							//m_point1 = m_point1;
							//m_point2 = point;
							//G_LLKGame->m_mapData[point1.y*m_nCol+point1.x]=BLANK;
							//G_LLKGame->m_mapData[point2.y*m_nCol+point2.x]=BLANK;
							//G_LLKGame->m_turnTime = 0;
							
							G_LLKGame->SendLink(m_roomSlot,m_point1,point);
						}
						else
						{
							G_LLKGame->PlaySound__("data/sound/ui_disable.wav");
							//改变选中的方块
							m_point1= vec2I(BLANK,BLANK);
						}
					}
					else
					{
						//点击上一方块 取消选中
						m_cornerNum = -1;
						m_point1= vec2I(BLANK,BLANK);
					}

				}
			}
		}
	}

}

void LLKPlayerRole::Render()
{
	LLKPlayer::Render();
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值