前言
- 之前我们已经实现了玩家的世界聊天,能看到聊天但是无法看到周围的玩家,接来就要实现玩家的位置信息同步
一、上线位置信息同步思路
二、上线位置信息同步实现
1 - 新增proto协议
- src/mmo_game_zinx/pb/msg.proto:这⾥涉及到了MsgID:202消息,我们应该在proto⽂件中,再添加两个消息
//同步玩家的显示数据
message SyncPlayers{
repeated Player ps=1;
}
//玩家信息
message Player{
int32 Pid=1;
Position P=2;
}
2 - 同步玩家上线的位置消息
- src/mmo_game_zinx/main.go:增加调用同步周边玩家
player.SyncSurrounding()
//当前客户端建立连接之后的hook函数
func OnConnecionAdd(conn ziface.IConneciton) {
//创建一个Player对象
player := core.NewPlayer(conn)
//给客户端发送MsgID:1的消息: 同步当前Player的ID给客户端
player.SyncPid()
//给客户端发送MsgID:200的消息: 同步当前Player的初始位置给客户端
player.BroadCastStartPosition()
//将当前新上线的玩家添加到WorldManager中
core.WorldMgrObj.AddPlayer(player)
//将该连接绑定一个Pid 玩家ID的属性
conn.SetProperty("pid", player.Pid)
//同步周边玩家,告知他们当前玩家已经上线,广播当前玩家的位置信息
player.SyncSurrounding()
fmt.Println("=====> Player pid = ", player.Pid, " is arrived <=====")
}
- src/mmo_game_zinx/core/player.go:实现方法 —— 同步玩家上线的位置信息
//同步玩家上线的位置消息
func (p *Player) SyncSurrounding() {
// 1 获取当前玩家周围的玩家有哪些(九宫格)
pids := WorldMgrObj.AoiMgr.GetPidsByPos(p.X, p.Z)
fmt.Println("SyncSurounding.. player ids = ", pids)
players := make([]*Player, 0, len(pids))
for _, pid := range pids {
players = append(players, WorldMgrObj.GetPlayerByPid(int32(pid)))
}
// 2 将当前玩家的位置信息通过MsgID:200 发给周围的玩家(让其他玩家看到自己)
//2.1 组建MsgID:200 proto数据
proto_msg := &pb.BroadCast{
Pid: p.Pid,
Tp: 2, // Tp2 代表广播坐标
Data: &pb.BroadCast_P{
P: &pb.Position{
X: p.X,
Y: p.Y,
Z: p.Z,
V: p.V,
},
},
}
//2.2 全部周围的玩家都向格子的客户端发送200消息,proto_msg
for _, player := range players {
player.SendMsg(200, proto_msg)
}
// 3 将周围的全部玩家的位置信息发送给当前的玩家MsgID:202 客户端(让自己看到其他玩家)
//3.1 组建MsgID:202 proto数据
//3.1.1 制作pb.Player slice
players_proto_msg := make([]*pb.Player, 0, len(players))
for _, player := range players {
//制作一个message Player
p := &pb.Player{
Pid: player.Pid,
P: &pb.Position{
X: player.X,
Y: player.Y,
Z: player.Z,
V: player.V,
},
}
players_proto_msg = append(players_proto_msg, p)
}
//3.1.2 封装SyncPlayer protobuf数据
SyncPlayers_proto_msg := &pb.SyncPlayers{
Ps: players_proto_msg[:],
}
//3.2 将组建好的数据发送给当前玩家的客户端
p.SendMsg(202, SyncPlayers_proto_msg)
}
三、测试结论
- 测试截图:可以看到每个player都可以看到其他player的上线