/// <summary> /// 按固定频率向客户端广播帧 /// </summary> private void SendFrame() { long frame = mCurrentFrame++; int playerCount = 0; //当前帧有多少个客户端发了命令 BroadPlayerFrameCommand sendData = new BroadPlayerFrameCommand(); sendData.Frame = frame; sendData.Frametime = mFrameTime; if (mFrameDic.ContainsKey(frame)) { Dictionary <int, List <Command> > frames = mFrameDic[frame]; playerCount = frames.Count; var it = frames.GetEnumerator(); // 循环访问构造器 while (it.MoveNext()) { for (int i = 0, count = it.Current.Value.Count; i < count; ++i) { OperationCommand cmd = ProtoTransfer.Get(it.Current.Value[i]); sendData.Commands.Add(cmd); } } } //不显示那么多log if (frame % 30 == 0 || sendData.Commands.Count > 0) { Debug.Log(string.Format("Send frame:{0} user count:{1} command count:{2}", frame, playerCount, sendData.Commands.Count), ConsoleColor.Gray); } BroadCast(MessageID.BroadCmdFrame, sendData, true); }
// 帧同步 ----->收到所有玩家的操作帧之后 进行帧的驱动 private void OnLockStepFrame(Session client, PlayerFrameCommand recvData) { long frame = recvData.Frame; int roleId = recvData.RoleId; if (recvData.Commands.Count > 0 || frame % 30 == 0) { Debug.Log(string.Format("Receive {0} serverframe:{1} clientframe:{2} command:{3}", roleId, mCurrentFrame, frame, recvData.Commands.Count), ConsoleColor.DarkGray); } if (mFrameDic.ContainsKey(frame) == false) { // 添加到当前帧的玩家操作指令中 mFrameDic.Add(frame, new Dictionary <int, List <Command> >()); } var frames = mFrameDic[frame]; //当前帧的服务器命令 if (frames.ContainsKey(SERVER_ROLEID) == false) { frames.Add(SERVER_ROLEID, new List <Command>()); } //该玩家是否发送了当前帧 if (frames.ContainsKey(roleId) == false) { frames.Add(roleId, new List <Command>()); } for (int i = 0; i < recvData.Commands.Count; ++i) { Command cmd = new Command(recvData.Commands[i].Frame, recvData.Commands[i].Type, recvData.Commands[i].Data.ToByteArray(), recvData.Commands[i].Frametime); frames[roleId].Add(cmd); } //当所有玩家都发送了该帧,就可以广播了 //减去1是因为服务器命令也在当前帧中 if (frames.Count - 1 >= mPlayerList.Count) { BroadPlayerFrameCommand sendData = new BroadPlayerFrameCommand(); sendData.Frame = frame; sendData.Frametime = mFrameTime; var it = frames.GetEnumerator(); while (it.MoveNext()) { for (int i = 0, count = it.Current.Value.Count; i < count; ++i) { OperationCommand cmd = ProtoTransfer.Get(it.Current.Value[i]); sendData.Commands.Add(cmd); } } BroadCast(MessageID.BroadCmdFrame, sendData, true); mCurrentFrame = frame + 1; } else { Debug.Log(string.Format("Waiting {0} frame:{1} count:{2} current:{3} ", roleId, frame, mFrameDic[frame].Count, mPlayerList.Count), ConsoleColor.Red); } }