14-zinx-Golang-MMO项目构建与用户上线

2023-10-23 08:59

本文主要是介绍14-zinx-Golang-MMO项目构建与用户上线,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

目录

  • 前言
  • 一、构建项目
  • 二、用户上线流程
    • 1 - 实现思路
    • 2 - 定义proto协议
    • 3 - 玩家Player模块
    • 4 - 实现上线业务
  • 三、目录结构与完整源码

前言

  • 前面我们已经介绍完AOI算法与Protobuf协议,接下来正式进入MMO游戏后端的开发

一、构建项目

在这里插入图片描述

  • 目录结构:创建⼀个项⽬ mmo_game ,在项⽬内分别创建⼏个⽂件夹 api , conf , core , game_client , pb等
    • apis:主要是注册⼀些mmo业务的⼀些Router处理业务
    • conf:存放mmo_game的一些配置文件,比如“zinx.json”
    • core:存放一些核心算法或者游戏控制等模块
    • game_client:存放游戏客户端
    • pb:存放一些protobuf的协议文件和go文件
      在这里插入图片描述
  • main.go
package mainimport "zinx/znet"func main() {//创建zinx server句柄s := znet.NewServer("MMO Game Zinx")//连接创建和销毁的HOOK钩子函数//注册一些路由业务//启动服务s.Serve()
}
  • ** conf ⽂件添加 zinx.conf**
在这里插入代码片{"Name":"MMO Game Zinx","Host": "0.0.0.0","TcpPort":8999,"MaxConn":3000,"WorkerPoolSize":10
}
  • 在 pb 下创建msg.proto
syntax="proto3"; //Proto协议
package pb; //当前包名
option csharp_namespace="Pb"; //给C#提供的选项
option go_package = "./";
  • 在 pb下创建build.sh编译指令脚本
#!/bin/bash
protoc --go_out=. *.proto

二、用户上线流程

在这里插入图片描述

1 - 实现思路

在这里插入图片描述

2 - 定义proto协议

  • msg.proto:上线的业务会涉及到MsgID:1 和 MsgID:200 两个消息
syntax = "proto3"; //Proto协议
package pb; //当前包名
option csharp_namespace = "Pb"; //给C#提供的选项
option go_package = "./";//同步玩家ID
message SyncPid{int32 Pid = 1;    //服务器新生成玩家ID
}//位置信息
message Position{float X = 1;float Y = 2;float Z = 3;float V = 4;
}//广播消息
message BroadCast{int32 Pid = 1;int32 Tp = 2;  //1-世界聊天,2-玩家位置 3-动作 4-移动之后的坐标信息更新oneof Data {string Content = 3;   //玩家的聊天信息Position P = 4;       //广播玩家的位置int32 ActionData = 5; //玩家具体的动作}
}

3 - 玩家Player模块

  • src/mmo_game_zinx/core/player.go
    • Plyaer类中有当前玩家的ID,和当前玩家与客户端绑定的conn,还有就是地图的坐标信, NewPlayer()提供初始化玩家⽅法
    • 以给 Player 提供⼀个 SendMsg() ⽅法,供客户端发送消息;SendMsg() 是将发送的数据,通过proto序列化,然后再调⽤ Zinx 框架的SendMsg⽅法发送给对⽅客户端
package coreimport ("fmt""google.golang.org/protobuf/proto""math/rand""sync""zinx/ziface"
)//玩家对象
type Player struct {Pid  int32              //玩家IDConn ziface.IConneciton //当前玩家的连接(用于和客户端的连接)X    float32            //平面的x坐标Y    float32            //高度Z    float32            //平面y坐标(注意不是Y)V    float32            //旋转的0-360角度
}/*Player ID 生成器
*/
var PidGen int32 = 1  //用来生产玩家ID的计数器
var IdLock sync.Mutex //保护PidGen的Mutex//创建一个玩家的方法
func NewPlayer(conn ziface.IConneciton) *Player {//生成一个玩家IDIdLock.Lock()id := PidGenPidGen++IdLock.Unlock()//创建一个玩家对象p := &Player{Pid:  id,Conn: conn,X:    float32(160 + rand.Intn(10)), //随机在160坐标点 基于X轴若干偏移Y:    0,Z:    float32(140 + rand.Intn(20)), //随机在140坐标点,基于Y轴若干偏移V:    0,                            //角度为0}return p
}/*提供一个发送给客户端消息的方法主要是将pb的protobuf数据序列化之后,再调用zinx的SendMsg方法
*/
func (p *Player) SendMsg(msgId uint32, data proto.Message) {//将proto Message结构体序列化 转换成二进制msg, err := proto.Marshal(data)if err != nil {fmt.Println("marshal msg err: ", err)return}//将二进制文件 通过zinx框架的sendmsg将数据发送给客户端if p.Conn == nil {fmt.Println("connection in player is nil")return}if err := p.Conn.SendMsg(msgId, msg); err != nil {fmt.Println("Player SendMsg error!")return}return
}

4 - 实现上线业务

  • src/mmo_game_zinx/main.go
    • 在Server的main⼊⼝,给链接绑定⼀个创建之后的hook⽅法,因为上线的时候是服务器⾃动回复客户端玩家ID和坐标,那么需要我们在连接创建完毕之后,⾃动触发,正好我们可以利⽤ Zinx 框架的 SetOnConnStart ⽅法
package mainimport ("fmt""mmo_game_zinx/core""zinx/ziface""zinx/znet"
)//当前客户端建立连接之后的hook函数
func OnConnectionAdd(conn ziface.IConneciton) {//创建一个Player对象player := core.NewPlayer(conn)//给客户端发送MsgID:1的消息: 同步当前Player的ID给客户端player.SyncPid()//给客户端发送MsgID:200的消息: 同步当前Player的初始位置给客户端player.BroadCastStartPosition()fmt.Println("=====> Player pid = ", player.Pid, " is arrived <=====")
}func main() {//创建zinx server句柄s := znet.NewServer("MMO Game Zinx")//连接创建和销毁的HOOK钩子函数s.SetOnConnStart(OnConnectionAdd)//注册一些路由业务//启动服务s.Serve()
}
  • src/mmo_game_zinx/core/player.go
    • 之前的流程分析,那么在客户端建⽴连接过来之后,Server要⾃动的回复给客户端⼀个玩家ID,同时也要讲当前玩家的坐标发送给客户端。所以我们这⾥⾯给Player定制了两个⽅法Player.SyncPid() 和 Player.BroadCastStartPosition()
//告知客户端玩家Pid,同步已经生成的玩家ID给客户端
func (p *Player) SyncPid() {//组建MsgID:0 的proto数据proto_msg := &pb.SyncPid{Pid: p.Pid,}//将消息发送给客户端p.SendMsg(1, proto_msg)
}//广播玩家自己的出生地点
func (p *Player) BroadCastStartPosition() {//组建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,},},}//将消息发送给客户端p.SendMsg(200, proto_msg)
}

在这里插入图片描述

三、目录结构与完整源码

在这里插入图片描述
点击下载完整源码:mmo_game_zinxV1.0.rar
点击下载对应客户端:mmo_game_u3d_client

这篇关于14-zinx-Golang-MMO项目构建与用户上线的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/266832

相关文章

golang panic 函数用法示例详解

《golangpanic函数用法示例详解》在Go语言中,panic用于触发不可恢复的错误,终止函数执行并逐层向上触发defer,最终若未被recover捕获,程序会崩溃,recover用于在def... 目录1. panic 的作用2. 基本用法3. recover 的使用规则4. 错误处理建议5. 常见错

Vue项目的甘特图组件之dhtmlx-gantt使用教程和实现效果展示(推荐)

《Vue项目的甘特图组件之dhtmlx-gantt使用教程和实现效果展示(推荐)》文章介绍了如何使用dhtmlx-gantt组件来实现公司的甘特图需求,并提供了一个简单的Vue组件示例,文章还分享了一... 目录一、首先 npm 安装插件二、创建一个vue组件三、业务页面内 引用自定义组件:四、dhtmlx

SpringBoot项目注入 traceId 追踪整个请求的日志链路(过程详解)

《SpringBoot项目注入traceId追踪整个请求的日志链路(过程详解)》本文介绍了如何在单体SpringBoot项目中通过手动实现过滤器或拦截器来注入traceId,以追踪整个请求的日志链... SpringBoot项目注入 traceId 来追踪整个请求的日志链路,有了 traceId, 我们在排

golang字符串匹配算法解读

《golang字符串匹配算法解读》文章介绍了字符串匹配算法的原理,特别是Knuth-Morris-Pratt(KMP)算法,该算法通过构建模式串的前缀表来减少匹配时的不必要的字符比较,从而提高效率,在... 目录简介KMP实现代码总结简介字符串匹配算法主要用于在一个较长的文本串中查找一个较短的字符串(称为

SpringBoot中整合RabbitMQ(测试+部署上线最新完整)的过程

《SpringBoot中整合RabbitMQ(测试+部署上线最新完整)的过程》本文详细介绍了如何在虚拟机和宝塔面板中安装RabbitMQ,并使用Java代码实现消息的发送和接收,通过异步通讯,可以优化... 目录一、RabbitMQ安装二、启动RabbitMQ三、javascript编写Java代码1、引入

部署Vue项目到服务器后404错误的原因及解决方案

《部署Vue项目到服务器后404错误的原因及解决方案》文章介绍了Vue项目部署步骤以及404错误的解决方案,部署步骤包括构建项目、上传文件、配置Web服务器、重启Nginx和访问域名,404错误通常是... 目录一、vue项目部署步骤二、404错误原因及解决方案错误场景原因分析解决方案一、Vue项目部署步骤

golang内存对齐的项目实践

《golang内存对齐的项目实践》本文主要介绍了golang内存对齐的项目实践,内存对齐不仅有助于提高内存访问效率,还确保了与硬件接口的兼容性,是Go语言编程中不可忽视的重要优化手段,下面就来介绍一下... 目录一、结构体中的字段顺序与内存对齐二、内存对齐的原理与规则三、调整结构体字段顺序优化内存对齐四、内

TP-Link PDDNS服将于务6月30日正式停运:用户需转向第三方DDNS服务

《TP-LinkPDDNS服将于务6月30日正式停运:用户需转向第三方DDNS服务》近期,路由器制造巨头普联(TP-Link)在用户群体中引发了一系列重要变动,上个月,公司发出了一则通知,明确要求所... 路由器厂商普联(TP-Link)上个月发布公告要求所有用户必须完成实名认证后才能继续使用普联提供的 D

配置springboot项目动静分离打包分离lib方式

《配置springboot项目动静分离打包分离lib方式》本文介绍了如何将SpringBoot工程中的静态资源和配置文件分离出来,以减少jar包大小,方便修改配置文件,通过在jar包同级目录创建co... 目录前言1、分离配置文件原理2、pom文件配置3、使用package命令打包4、总结前言默认情况下,

python实现简易SSL的项目实践

《python实现简易SSL的项目实践》本文主要介绍了python实现简易SSL的项目实践,包括CA.py、server.py和client.py三个模块,文中通过示例代码介绍的非常详细,对大家的学习... 目录运行环境运行前准备程序实现与流程说明运行截图代码CA.pyclient.pyserver.py参