一、移动位置与广播思路
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/8c0a922ce5e44f4527975345226009c6.png)
二、移动位置同步
1 - 移动api
- src/mmo_game_zinx/apis/move.go
package apis
import (
"fmt"
"google.golang.org/protobuf/proto"
"mmo_game_zinx/core"
pb "mmo_game_zinx/pb"
"zinx/ziface"
"zinx/znet"
)
type MoveApi struct {
znet.BaseRouter
}
func (m *MoveApi) Handle(request ziface.IRequest) {
proto_msg := &pb.Position{}
err := proto.Unmarshal(request.GetData(), proto_msg)
if err != nil {
fmt.Println("Move : Position Unmarshal error ", err)
return
}
pid, err := request.GetConnection().GetProperty("pid")
if err != nil {
fmt.Println("GetProperty pid error, ", err)
return
}
fmt.Printf("Player pid = %d, move(%f,%f,%f,%f)\n", pid, proto_msg.X, proto_msg.Y, proto_msg.Z, proto_msg.V)
player := core.WorldMgrObj.GetPlayerByPid(pid.(int32))
player.UpdatePos(proto_msg.X, proto_msg.Y, proto_msg.Z, proto_msg.V)
}
2 - 广播当前玩家的移动信息
- src/mmo_game_zinx/core/player.go
func (p *Player) UpdatePos(x float32, y float32, z float32, v float32) {
p.X = x
p.Y = y
p.Z = z
p.V = v
proto_msg := &pb.BroadCast{
Pid: p.Pid,
Tp: 4,
Data: &pb.BroadCast_P{
P: &pb.Position{
X: p.X,
Y: p.Y,
Z: p.Z,
V: p.V,
},
},
}
players := p.GetSuroundingPlayers()
for _, player := range players {
player.SendMsg(200, proto_msg)
}
}
func (p *Player) GetSuroundingPlayers() []*Player {
pids := WorldMgrObj.AoiMgr.GetPidsByPos(p.X, p.Z)
players := make([]*Player, 0, len(pids))
for _, pid := range pids {
players = append(players, WorldMgrObj.GetPlayerByPid(int32(pid)))
}
return players
}
3 - main中添加移动路由
- src/mmo_game_zinx/main.go
func main() {
s := znet.NewServer("MMO Game Zinx")
s.SetOnConnStart(OnConnecionAdd)
s.AddRouter(2, &apis.WorldChatApi{})
s.AddRouter(3, &apis.MoveApi{})
s.Serve()
}
三、测试结论
- 通过测试:我们可以看到任何的客户端移动都会同步到其他客户端,说明位置同步实现没有问题
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/7b76ac62668c1afe2eee2a85116f12a2.png)
四、目录结构与完整源码
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/b35bfe28d5463dfa1565b25263b4595b.png)
点击下载完整源码:mmo_game_zinxV4.0
点击下载对应客户端:mmo_game_u3d_client