/*
基于9宫格的移动广播,进入视野离开视野
1.根据玩家的xy坐标计算玩家移动之前和移动之后的格子id
2.根据格子id计算附近的格子,附近格子里面的玩家成为附近玩家
3.向新减少的格子的玩家发送离开视野,向新增的格子的玩家发送进入视野
*/
bool Room::HandleOnMove( IRole * pRole )
{
if(NULL == pRole)
return false;
Room *pRoom = pRole->GetRoom();
if(NULL == pRoom || pRoom->GetSceneId() == enNewPlayer_SceneId)
{
return false;
}
if(pOwnerScene->sceneInfo.canCrossRole == IS_CAN_CROSS_ROLE)
{
//设置Grid某一个点为1
int pos = GetRoleGridPosByRowCol(pRole->GetRolePos().coord.getX(),pRole->GetRolePos().coord.getY());
if(pos >=0 && pos < m_nRoleGridsSize)
{
if(pRole->GetLastGridPos() >= 0)
{
m_pRoleGrids[pRole->GetLastGridPos()] = 0;
}
pRole->SetLastGridPos(pos);
m_pRoleGrids[pos] = 1;
//Log::Instance()->WriteLog(enLogType_Error, "HandleOnMove m_pRoleGrids[pos]:%d 1", pos);
}
}
Tint32 nOldSceneCellId = pRole->GetSceneCellId();
//计算玩家在哪个单元格
Tint32 TileId = CalcCellId(pRole->GetSceneCoord().getX(),pRole->GetSceneCoord().getY());
if(TileId < m_nCellSize && TileId >= 0)
{
if(nOldSceneCellId < m_nCellSize && nOldSceneCellId >= 0)
{
if(nOldSceneCellId != TileId)
{
tagCellList CellList = GetDiffCell(&m_cells[nOldSceneCellId], &m_cells[TileId]);
for (Tint32 i=CellList.nCount-1; i >=0 ; i--)
{
CellList.m_Cells[i]->BroadcastCellLeaveMsg(pRole,false,true);
}
m_cells[nOldSceneCellId].OnLeave(pRole);
m_cells[TileId].OnEnter(pRole);
tagCellList EnterCellList = GetDiffCell(&m_cells[TileId], &m_cells[nOldSceneCellId]);
for (Tint32 i=EnterCellList.nCount-1; i >=0 ; i--)
{
EnterCellList.m_Cells[i]->SendCellEnterMsg(pRole,false);
}
pRole->SetSceneCellId(TileId);
}
}
if(pRole->getIsMove())
{
if(cellSend[TileId] == 0) //防止一个格子重复广播
{
m_cells[TileId].SyncCoord();
cellSend[TileId] = 1;
}
}
}
return true;
}
void CSceneCell::SyncCoord()
{
Tint32 tmpSelfRoleCount;
IRole* tmpSelfRoles[MAX_PLAYER_POS_CHANGE_COUNT + 1];
tmpSelfRoleCount = GetSelfRoleListToArray(tmpSelfRoles, MAX_PLAYER_POS_CHANGE_COUNT);
if(tmpSelfRoleCount == 0)
return;
if(tmpSelfRoleCount > MAX_PLAYER_POS_CHANGE_COUNT)
tmpSelfRoleCount = MAX_PLAYER_POS_CHANGE_COUNT;
MsgPushRoleMove RoleMove;
for (Tint32 i=0; i < tmpSelfRoleCount; i++)
{
IRole* pRole = tmpSelfRoles[i];
if(pRole->getIsMove())
{
pRole->setIsMove(false);
MsgStructMove* Move = RoleMove.add_move_list();
Move->set_role_type(pRole->GetRoleType());
Move->set_tile_x(pRole->GetSceneCoord().getX());
Move->set_tile_y(pRole->GetSceneCoord().getY());
char buf[64] = "";
if(pRole->GetRoleType() == GAME_PLAYER)
sprintf(buf, "%lld", ((GamePlayer*)pRole)->GetGUID());
else
sprintf(buf, "%d", pRole->GetRoleId());
Move->set_role_id(buf);
Move->set_move_speed(pRole->GetMoveSpeed());
}
}
if(RoleMove.move_list_size() == 0)
{
return;
}
vector<GamePlayer*> NearPlayers = GetNearPlayerList();
//每个Cell只发数据给相邻的Cell,这样就确保每个对象只接收到一次数据
tagNetMsg sendMsg;
sendMsg.BuffLen = RoleMove.ByteSize();
RoleMove.SerializePartialToArray(sendMsg.buff,RoleMove.ByteSize());
for(vector<GamePlayer*>::iterator itPlayer = NearPlayers.begin();itPlayer != NearPlayers.end();++ itPlayer)
{
GamePlayer* TmpRole = *itPlayer;
TmpRole->Send
Msg(GAME_PLAYER_LOCATION_NOTIFY,sendMsg.BuffLen,sendMsg);
}
}