基于GoLang的MMO游戏服务器(四)
世界聊天
- 首先定义世界聊天的路由方法
具体实现
type WorldChatAPI struct {
znet.BaseRouter
}
func (wca WorldChatAPI) Handle(request ziface.IRequest) {
pid, err := request.GetConnection().GetProperty("pid")
if err != nil {
fmt.Println(err)
return
}
protoMsg := &Pb.Talk{}
err = proto.Unmarshal(request.GetData(), protoMsg)
if err != nil {
fmt.Println(err)
return
}
player := core.WorldMgrObj.GetPlayerByPid(pid.(int32))
player.Talk(protoMsg.Content)
}
func (p *Player) Talk(context string) {
protoMsg := &Pb.BroadCase{
Pid: p.Pid,
Tp: 1,
Data: &Pb.BroadCase_Content{
Content: context,
},
}
players := WorldMgrObj.GetAllPlayers()
for _, player := range players {
player.SendMsg(200, protoMsg)
}
}
让周围玩家显示当前玩家,当前玩家显示其它玩家
- 当玩家接入成功后,在回调中添加同步玩家方法
- 告知其它玩家我上线
- 告知我其它玩家位置信息
func (p *Player) SyncSurrounding() {
playerIDs := WorldMgrObj.AoiMgr.GetSurroundPlayersByPos(p.X, p.Z)
if playerIDs != nil && len(playerIDs) > 0 {
// 告知其它玩家我上线
protoMsg := &Pb.BroadCase{
Pid: p.Pid,
Tp: 2,
Data: &Pb.BroadCase_P{
P: &Pb.Position{
X: p.X,
Y: p.Y,
Z: p.Z,
V: p.V,
}},
}
players := make([]*Pb.Player, 0, len(playerIDs))
for i := 0; i < len(playerIDs); i++ {
player := WorldMgrObj.GetPlayerByPid(int32(playerIDs[i]))
players = append(players, &Pb.Player{
Pid: int32(playerIDs[i]),
P: &Pb.Position{
X: player.X,
Y: player.Y,
Z: player.Z,
V: player.V,
},
})
player.SendMsg(200, protoMsg)
}
// 告知我其它玩家位置信息
protoMsg1 := &Pb.SyncPlayers{Ps: players}
p.SendMsg(202, protoMsg1)
}
}
同步玩家移动
type MoveAPI struct {
znet.BaseRouter
}
func (m MoveAPI) Handle(request ziface.IRequest) {
protoMsg := &Pb.Position{}
err := proto.Unmarshal(request.GetData(), protoMsg)
if err != nil {
fmt.Println(err)
return
}
pid, err := request.GetConnection().GetProperty("pid")
if err != nil {
fmt.Println(err)
return
}
player := core.WorldMgrObj.GetPlayerByPid(pid.(int32))
if player == nil {
return
}
player.UpdatePos(protoMsg.X, protoMsg.Y, protoMsg.Z, protoMsg.V)
}
func (p *Player) UpdatePos(x, y, z, v float32) {
p.X = x
p.Y = y
p.Z = z
p.V = v
protoMsg := &Pb.BroadCase{
Pid: p.Pid,
Tp: 4,
Data: &Pb.BroadCase_P{
P: &Pb.Position{
X: x,
Y: y,
Z: z,
V: v,
},
},
}
playerIDs := WorldMgrObj.AoiMgr.GetSurroundPlayersByPos(x, z)
for i := 0; i < len(playerIDs); i++ {
player := WorldMgrObj.GetPlayerByPid(int32(playerIDs[i]))
player.SendMsg(200, protoMsg)
}
}
同步玩家下线功能
- 添加连接断开回调函数
- Offline方法具体实现
func (p *Player) Offline() {
playerIDs := WorldMgrObj.AoiMgr.GetSurroundPlayersByPos(p.X, p.Z)
protoMsg := &Pb.SyncPid{Pid: p.Pid}
for i := 0; i < len(playerIDs); i++ {
player := WorldMgrObj.GetPlayerByPid(int32(playerIDs[i]))
player.SendMsg(201, protoMsg)
}
WorldMgrObj.RemovePlayerByPid(p.Pid)
}