服务器客户端同步 之 关于跳帧问题

网上有很多同步方案, 我看了下,都比较麻烦,新人也看不懂,老人也不要看。于是我简单写了一下,方便大家快速上手。

做之前,服务端 必须是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帧。类似

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

然后,我把服务器发过来的 Frame乘以  10;对应起来;

客户端逻辑处理有三个方式,等待,正常运行,跳帧。

等待是因为 客户端执行完毕所有帧,服务端帧还没过来,这个时候需要等待,也可以做暂停。

跳帧是  通过判断 客户端帧 和 服务端帧 差 大于 10帧。 那么就 遍历,使得快速 让 客户端和服务端差距只有 10帧以内。

最后结果:  前面数据是  客户端当前帧,后面是 服务端帧

结尾等待是 我把服务器关了,客户端自然等待了。

最后代码:非常短

    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++;
    }

祝大家好运!

posted on 2019-08-21 11:45  太粗难进  阅读(582)  评论(0编辑  收藏  举报