服务器客户端同步 之 关于跳帧问题
网上有很多同步方案, 我看了下,都比较麻烦,新人也看不懂,老人也不要看。于是我简单写了一下,方便大家快速上手。
做之前,服务端 必须是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++; }
祝大家好运!