服務器客戶端同步 之 關於跳幀問題

網上有不少同步方案, 我看了下,都比較麻煩,新人也看不懂,老人也不要看。因而我簡單寫了一下,方便你們快速上手。json

作以前,服務端 必須是udp 通信,這個我很少解釋,我用的是lidgren 通信框架,不知道的,能夠看我過去的文章。服務器

代碼思路,服務器每秒 發一次,能夠用線程作。框架

  public static void Confrontation()
        {
            while (true)
            {
                Thread.Sleep(1000);
                Output("目前" + Frame);
                List<NetConnection> all = s_server.Connections; // get copy
                //   all.Remove(msg.SenderConnection);
                if (all.Count > 0)
                {
                    NetOutgoingMessage om = s_server.CreateMessage();
                    JsonDatas message = new JsonDatas();
                    message.jsons["type"] = "5";
                    message.jsons["msg"] = Frame;
                    string json = JsonConvert.SerializeObject(message);
                    om.Write(json);
                    s_server.SendMessage(om, all, NetDeliveryMethod.ReliableOrdered, 0);
                }
                if (Frame%7==0)
                {
                    Frame += 2;
                }
                else
                {
                    Frame++;
                }
            }
        }

這個是 線程裏面的方法,all是表明全部在線 用戶 套接字端口。 數據是 json格式,方便客戶端判斷。Frame是 幀,每秒加1,最後我 Frame%7 是爲了方便 跳幀測試,也就是說,到7倍數幀時候,個人幀 不是 加1,而是加2,讓客戶端 來判斷,須要跳幀。測試

 

再看看客戶端,由於客戶端 在 updata裏面是 一秒60幀,我把他變成 一秒10幀。相似spa

 if (GameModel.getInstance().Rate == 6)
        {
            GameModel.getInstance().Rate = 0;
}   GameModel.getInstance().Rate++;

而後,我把服務器發過來的 Frame乘以  10;對應起來;線程

客戶端邏輯處理有三個方式,等待,正常運行,跳幀。code

等待是由於 客戶端執行完畢全部幀,服務端幀還沒過來,這個時候須要等待,也能夠作暫停。server

跳幀是  經過判斷 客戶端幀 和 服務端幀 差 大於 10幀。 那麼就 遍歷,使得快速 讓 客戶端和服務端差距只有 10幀之內。blog

最後結果:  前面數據是  客戶端當前幀,後面是 服務端幀get

結尾等待是 我把服務器關了,客戶端天然等待了。

最後代碼:很是短

    void Update()
    {
        if (FrameBool && GameModel.getInstance().LogicalFrame > 0)
        {
            Frame = GameModel.getInstance().LogicalFrame;
            FrameBool = false;
        }
        if (FrameBool == false)
        {
            OnSetShaderFrame();
        }
    }

    //總負責 戰鬥 邏輯處理
    public void OnSetShaderFrame()
    {
        if (GameModel.getInstance().Rate == Rate)
        {
            GameModel.getInstance().Rate = 0;

            if (GameModel.getInstance().LogicalFrame == Frame)//幀相同,客戶端等待
            {
                Debug.Log("-><color=#E88748>" + Frame + "客戶端等待 " + GameModel.getInstance().LogicalFrame + "</color>");
            }
            else
            {
                Debug.Log("-><color=#90E848>" + Frame + "邏輯幀 " + GameModel.getInstance().LogicalFrame + "</color>");
                Frame++;//執行完畢 幀加一

                if (GameModel.getInstance().LogicalFrame - Frame > 7)//超過1秒 ,6幀 一秒
                {
                    for (int i = 0; i < (GameModel.getInstance().LogicalFrame - Frame); i++)//保留當前6幀,其餘跳幀
                    {
                        Debug.Log("-><color=#E84848>" + Frame + "跳幀執行 " + GameModel.getInstance().LogicalFrame + "</color>");
                        Frame++;//執行完畢 幀加一
                    }
                }
            }

        }
        GameModel.getInstance().Rate++;
    }

祝你們好運!

相關文章
相關標籤/搜索