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();
}
完