<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                企業??AI智能體構建引擎,智能編排和調試,一鍵部署,支持知識庫和私有化部署方案 廣告
                ### 6.2用戶上線流程 好了,那么我們第一次就要嘗試將客戶端的MMO游戲和移動端做一次上線測試了。 我們第一個測試用戶上線的流程比較簡單: ![](https://img.kancloud.cn/52/3a/523a745e09356d53711bcc4b02e8a769_1024x768.jpeg)A\)定義proto協議 我們從圖中可以看到,上線的業務會涉及到MsgID:1 和 MsgID:200 兩個消息,根據我們上一個章節的介紹,我們需要在msg.proto中定義出兩個proto類型,并且聲稱對應的go代碼. > mmo\_game/pb/msg.proto ```go syntax="proto3"; //Proto協議 package pb; //當前包名 option csharp_namespace="Pb"; //給C#提供的選項 //同步客戶端玩家ID message SyncPid{ int32 Pid=1; } //玩家位置 message Position{ float X=1; float Y=2; float Z=3; float V=4; } //玩家廣播數據 message BroadCast{ int32 Pid=1; int32 Tp=2; oneof Data { string Content=3; Position P=4; int32 ActionData=5; } } ``` 執行build.sh生成對應的`msg.pb.go`代碼. #### B\)創建Player模塊 1. 首先我們先創建一個Player玩家模塊 > mmo\_game/core/player.go ```go //玩家對象 type Player struct { Pid int32 //玩家ID Conn ziface.IConnection //當前玩家的連接 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的互斥機制 //創建一個玩家對象 func NewPlayer(conn ziface.IConnection) *Player { //生成一個PID IdLock.Lock() id := PidGen PidGen ++ IdLock.Unlock() p := &Player{ Pid : id, Conn:conn, X:float32(160 + rand.Intn(10)),//隨機在160坐標點 基于X軸偏移若干坐標 Y:0, //高度為0 Z:float32(134 + rand.Intn(17)), //隨機在134坐標點 基于Y軸偏移若干坐標 V:0, //角度為0,尚未實現 } return p } ``` Plyaer類中有當前玩家的ID,和當前玩家與客戶端綁定的conn,還有就是地圖的坐標信,`NewPlayer()`提供初始化玩家方法。 1. 由于`Player`經常需要和客戶端發送消息,那么我們可以給`Player`提供一個`SendMsg()`方法,供客戶端發送消息 > mmo\_game/core/player.go ```go /* 發送消息給客戶端, 主要是將pb的protobuf數據序列化之后發送 */ func (p *Player) SendMsg(msgId uint32, data proto.Message) { fmt.Printf("before Marshal data = %+v\n", data) //將proto Message結構體序列化 msg, err := proto.Marshal(data) if err != nil { fmt.Println("marshal msg err: ", err) return } fmt.Printf("after Marshal data = %+v\n", msg) if p.Conn == nil { fmt.Println("connection in player is nil") return } //調用Zinx框架的SendMsg發包 if err := p.Conn.SendMsg(msgId, msg); err != nil { fmt.Println("Player SendMsg error !") return } return } ``` 這里要注意的是,`SendMsg()`是將發送的數據,通過proto序列化,然后再調用`Zinx`框架的SendMsg方法發送給對方客戶端. #### C\)實現上線業務 我們先在Server的main入口,給鏈接綁定一個創建之后的hook方法,因為上線的時候是服務器自動回復客戶端玩家ID和坐標,那么需要我們在連接創建完畢之后,自動觸發,正好我們可以利用`Zinx`框架的`SetOnConnStart`方法. > mmo\_game/server.go ```go package main import ( "fmt" "zinx/ziface" "zinx/zinx_app_demo/mmo_game/core" "zinx/znet" ) //當客戶端建立連接的時候的hook函數 func OnConnecionAdd(conn ziface.IConnection) { //創建一個玩家 player := core.NewPlayer(conn) //同步當前的PlayerID給客戶端, 走MsgID:1 消息 player.SyncPid() //同步當前玩家的初始化坐標信息給客戶端,走MsgID:200消息 player.BroadCastStartPosition() fmt.Println("=====> Player pidId = ", player.Pid, " arrived ====") } func main() { //創建服務器句柄 s := znet.NewServer() //注冊客戶端連接建立和丟失函數 s.SetOnConnStart(OnConnecionAdd) //啟動服務 s.Serve() } ``` 根據我們之前的流程分析,那么在客戶端建立連接過來之后,Server要自動的回復給客戶端一個玩家ID,同時也要講當前玩家的坐標發送給客戶端。所以我們這里面給Player定制了兩個方法`Player.SyncPid()`和`Player.BroadCastStartPosition()` `SyncPid()`則為發送`MsgID:1`的消息,將當前上線的用戶ID發送給客戶端 > mmo\_game/core/player.go ```go //告知客戶端pid,同步已經生成的玩家ID給客戶端 func (p *Player) SyncPid() { //組建MsgId0 proto數據 data := &pb.SyncPid{ Pid:p.Pid, } //發送數據給客戶端 p.SendMsg(1, data) } ``` `BroadCastStartPosition()`則為發送`MsgID:200`的廣播位置消息,雖然現在沒有其他用戶,不是廣播,但是當前玩家自己的坐標也是要告知玩家的。 > mmo\_game/core/player.go ```go //廣播玩家自己的出生地點 func (p *Player) BroadCastStartPosition() { msg := &pb.BroadCast{ Pid:p.Pid, Tp:2,//TP2 代表廣播坐標 Data: &pb.BroadCast_P{ &pb.Position{ X:p.X, Y:p.Y, Z:p.Z, V:p.V, }, }, } p.SendMsg(200, msg) } ``` #### D\)測試用戶上線業務 ```bash $cd mmo_game/ $go run server.go ``` 啟動服務端程序。 然后再windows終端打開`client.exe` > 注意,要確保windows和啟動服務器的Linux端要能夠ping通,為了方便測試,建議將Linux的防火墻設置為關閉狀態,或者要確保服務器的端口是開放的,以免耽誤調試 ![](/assets/15-zinx游戲案例-客戶端登錄.png) 在此處輸入服務器的IP地址,和服務器`zinx.json`配置的端口號。然后點擊Connect。 ![](/assets/16-zinx游戲案例-上線登錄成功.png)如果游戲界面順利進入,并且已經顯示為`Player_1`玩家ID,表示等錄成功,并且我們在服務端也可以看到一些調試信息。操作WASD也可以進行玩家移動。如果沒有顯示玩家ID或者為`TextView`則為登錄失敗,我們需要再針對協議的匹配進行調試。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看