• 【C++服务端技术】移动广播


    /*
    基于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);
        }
    }

    https://github.com/jiangguilong2000/gamioo

  • 相关阅读:
    Ural 1996 Cipher Message 3 (生成函数+FFT)
    UVA 12633 Super Rooks on Chessboard (生成函数+FFT)
    HDU 5307 He is Flying (生成函数+FFT)
    BZOJ 2039 人员雇佣 (最小割)
    BZOJ 3158 千钧一发 (最大流->二分图带权最大独立集)
    BZOJ 3144 [HNOI2013]切糕 (最大流+巧妙的建图)
    BZOJ 3774 最优选择 (最小割+二分图)
    BZOJ 3876 [AHOI/JSOI2014]支线剧情 (最小费用可行流)
    BZOJ 3771 Triple (FFT+生成函数+容斥)
    洛谷 P3121 【[USACO15FEB]审查(黄金)Censoring (Gold)】
  • 原文地址:https://www.cnblogs.com/byfei/p/14104073.html
Copyright © 2020-2023  润新知