16-zinx-Golang-MMO-上线位置信息同步

前言

  • 之前我们已经实现了玩家的世界聊天,能看到聊天但是无法看到周围的玩家,接来就要实现玩家的位置信息同步

一、上线位置信息同步思路

在这里插入图片描述
在这里插入图片描述

二、上线位置信息同步实现

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的上线

在这里插入图片描述

四、目录结构与完整源码

在这里插入图片描述

点击下载完整源码:mmo_game_zinxV3.0
点击下载对应客户端:mmo_game_u3d_client

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

无休止符

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值