目录
1.项目进度回顾
2.完善整体架构
3.AOI网格思路
4.网络AOI数据结构
5.游戏世界类添加,删除和构造
6.AOI查找实现
7.GAMEROLE类结合AOI
8.登陆时发送ID和姓名
9.登陆时发送周围玩家位置
10.玩家上线完成
11.玩家下线处理
1.项目进度回顾
2.完善整体架构
3.AOI网格思路
4.网络AOI数据结构
5.游戏世界类添加,删除和构造
6.AOI查找实现
7.GAMEROLE类结合AOI
8.登陆时发送ID和姓名
9.登陆时发送周围玩家位置
10.玩家上线完成
#pragma once
#include <list>
#include <vector>
/*拥有横纵坐标的对象*/
class Player {
public:
virtual int GetX() = 0;
virtual int GetY() = 0;
};
class Grid {
public:
std::list<Player *> m_players;
};
/*游戏世界矩形*/
class AOIWorld
{
int x_begin = 0;
int x_end = 0;
int y_begin = 0;
int y_end = 0;
int x_count = 0;
int y_count = 0;
int x_width = 0;
int y_width = 0;
public:
std::vector<Grid> m_grids;
/*通过构造函数指定矩形的大小和分割粒度*/
AOIWorld(int _x_begin, int _x_end, int _y_begin, int _y_end, int _x_count, int _y_count);
virtual ~AOIWorld();
/*获取周围玩家*/
std::list<Player *> GetSrdPlayers(Player *_player);
/*添加玩家到AOI网格*/
bool AddPlayer(Player *_player);
/*摘除玩家*/
void DelPlayer(Player *_player);
};
11.玩家下线处理
#include "GameRole.h"
#include "GameMsg.h"
#include <iostream>
#include "AOIWorld.h"
#include "msg.pb.h"
#include "GameProtocol.h"
#include "GameChannel.h"
using namespace std;
/*创建游戏世界全局对象*/
static AOIWorld world(0, 400, 0, 400, 20, 20);
GameMsg * GameRole::CreateIDNameLogin()
{
pb::SyncPid *pmsg = new pb::SyncPid();
pmsg->set_pid(iPid);
pmsg->set_username(szName);
GameMsg *pRet = new GameMsg(GameMsg::MSG_TYPE_LOGIN_ID_NAME, pmsg);
return pRet;
}
GameMsg * GameRole::CreataSrdPlayers()
{
pb::SyncPlayers *pMsg = new pb::SyncPlayers();
auto srd_list = world.GetSrdPlayers(this);
for (auto single : srd_list)
{
auto pPlayer = pMsg->add_ps();
auto pRole = dynamic_cast<GameRole *>(single);
pPlayer->set_pid(pRole->iPid);
pPlayer->set_username(pRole->szName);
auto pPostion = pPlayer->mutable_p();
pPostion->set_x(pRole->x);
pPostion->set_y(pRole->y);
pPostion->set_z(pRole->z);
pPostion->set_v(pRole->v);
}
GameMsg *pret = new GameMsg(GameMsg::MSG_TYPE_SRD_POSTION, pMsg);
return pret;
}
GameMsg * GameRole::CreateSelfPostion()
{
pb::BroadCast *pMsg = new pb::BroadCast();
pMsg->set_pid(iPid);
pMsg->set_username(szName);
pMsg->set_tp(2);
auto pPosition = pMsg->mutable_p();
pPosition->set_x(x);
pPosition->set_y(y);
pPosition->set_z(z);
pPosition->set_v(v);
GameMsg *pret = new GameMsg(GameMsg::MSG_TYPE_BROADCAST, pMsg);
return pret;
}
GameMsg * GameRole::CreateIDNameLogoff()
{
pb::SyncPid *pmsg = new pb::SyncPid();
pmsg->set_pid(iPid);
pmsg->set_username(szName);
GameMsg *pRet = new GameMsg(GameMsg::MSG_TYPE_LOGOFF_ID_NAME, pmsg);
return pRet;
}
GameRole::GameRole()
{
szName = "Tom";
x = 100;
z = 100;
}
GameRole::~GameRole()
{
}
bool GameRole::Init()
{
/*添加自己到游戏世界*/
bool bRet = false;
/*设置玩家ID为当前连接的fd*/
iPid = m_pProto->m_channel->GetFd();
bRet = world.AddPlayer(this);
if (true == bRet)
{
/*向自己发送ID和名称*/
auto pmsg = CreateIDNameLogin();
ZinxKernel::Zinx_SendOut(*pmsg, *m_pProto);
/*向自己发送周围玩家的位置*/
pmsg = CreataSrdPlayers();
ZinxKernel::Zinx_SendOut(*pmsg, *m_pProto);
/*向周围玩家发送自己的位置*/
auto srd_list = world.GetSrdPlayers(this);
for (auto single : srd_list)
{
pmsg = CreateSelfPostion();
auto pRole = dynamic_cast<GameRole *>(single);
ZinxKernel::Zinx_SendOut(*pmsg, *(pRole->m_pProto));
}
}
return bRet;
}
/*处理游戏相关的用户请求*/
UserData * GameRole::ProcMsg(UserData & _poUserData)
{
/*测试:打印消息内容*/
GET_REF2DATA(MultiMsg, input, _poUserData);
for (auto single : input.m_Msgs)
{
cout << "type is" << single->enMsgType << endl;
cout << single->pMsg->Utf8DebugString() << endl;
}
return nullptr;
}
void GameRole::Fini()
{
/*向周围玩家发送下线消息*/
auto srd_list = world.GetSrdPlayers(this);
for (auto single : srd_list)
{
auto pMsg = CreateIDNameLogoff();
auto pRole = dynamic_cast<GameRole *>(single);
ZinxKernel::Zinx_SendOut(*pMsg, *(pRole->m_pProto));
}
world.DelPlayer(this);
}
int GameRole::GetX()
{
return (int)x;
}
int GameRole::GetY()
{
return (int)z;
}