diff --git a/zinx_app_demo/mmo_game/api/move.go b/zinx_app_demo/mmo_game/api/move.go new file mode 100644 index 0000000..452480f --- /dev/null +++ b/zinx_app_demo/mmo_game/api/move.go @@ -0,0 +1,42 @@ +package api + +import ( + "fmt" + "github.com/golang/protobuf/proto" + "zinx/ziface" + "zinx/zinx_app_demo/mmo_game/core" + "zinx/zinx_app_demo/mmo_game/pb" + "zinx/znet" +) + +//玩家移动 +type MoveApi struct { + znet.BaseRouter +} + + +func (*MoveApi) Handle(request ziface.IRequest) { + //1. 将客户端传来的proto协议解码 + msg := &pb.Position{} + err := proto.Unmarshal(request.GetData(), msg) + if err != nil { + fmt.Println("Move: Position Unmarshal error ", err) + return + } + + //2. 得知当前的消息是从哪个玩家传递来的,从连接属性pid中获取 + pid, err := request.GetConnection().GetProperty("pid") + if err != nil { + fmt.Println("GetProperty pid error", err) + request.GetConnection().Stop() + return + } + + fmt.Printf("user pid = %d , move(%f,%f,%f,%f)", pid, msg.X, msg.Y, msg.Z, msg.V) + + //3. 根据pid得到player对象 + player := core.WorldMgrObj.GetPlayerByPid(pid.(int32)) + + //4. 让player对象发起移动位置信息广播 + player.UpdatePos(msg.X, msg.Y, msg.Z, msg.V) +} diff --git a/zinx_app_demo/mmo_game/core/player.go b/zinx_app_demo/mmo_game/core/player.go index 58cd485..5c84a76 100644 --- a/zinx_app_demo/mmo_game/core/player.go +++ b/zinx_app_demo/mmo_game/core/player.go @@ -150,6 +150,51 @@ func (p *Player) Talk(content string) { } +//广播玩家位置移动 +func (p *Player) UpdatePos(x float32, y float32, z float32, v float32) { + //更新玩家的位置信息 + p.X = x + p.Y = y + p.Z = z + p.V = v + + //组装protobuf协议,发送位置给周围玩家 + msg := &pb.BroadCast{ + Pid:p.Pid, + Tp:4, //4- 移动之后的坐标信息 + Data: &pb.BroadCast_P{ + P:&pb.Position{ + X:p.X, + Y:p.Y, + Z:p.Z, + V:p.V, + }, + }, + } + + //获取当前玩家周边全部玩家 + players := p.GetSurroundingPlayers() + //向周边的每个玩家发送MsgID:200消息,移动位置更新消息 + for _, player := range players { + player.SendMsg(200, msg) + } +} + +//获得当前玩家的AOI周边玩家信息 +func (p *Player) GetSurroundingPlayers() []*Player { + //得到当前AOI区域的所有pid + pids := WorldMgrObj.AoiMgr.GetPidsByPos(p.X, p.Z) + + //将所有pid对应的Player放到Player切片中 + players := make([]*Player, 0, len(pids)) + for _, pid := range pids { + players = append(players, WorldMgrObj.GetPlayerByPid(int32(pid))) + } + + return players +} + + /* 发送消息给客户端, 主要是将pb的protobuf数据序列化之后发送 diff --git a/zinx_app_demo/mmo_game/pb/msg.proto b/zinx_app_demo/mmo_game/pb/msg.proto index 7106d9d..7838cd8 100644 --- a/zinx_app_demo/mmo_game/pb/msg.proto +++ b/zinx_app_demo/mmo_game/pb/msg.proto @@ -18,7 +18,7 @@ message Position{ //玩家广播数据 message BroadCast{ int32 Pid=1; - int32 Tp=2; //1-世界聊天 2-玩家位置 + int32 Tp=2; //1-世界聊天 2-玩家位置 3 动作 4 移动之后坐标信息更新 oneof Data { string Content=3; //聊天的信息 Position P=4; //广播用户的位置 diff --git a/zinx_app_demo/mmo_game/server.go b/zinx_app_demo/mmo_game/server.go index e3c37ee..ff24ba6 100644 --- a/zinx_app_demo/mmo_game/server.go +++ b/zinx_app_demo/mmo_game/server.go @@ -35,6 +35,7 @@ func main() { //注册路由 s.AddRouter(2, &api.WorldChatApi{}) + s.AddRouter(3, &api.MoveApi{}) //启动服务 s.Serve()