// 乐观帧同步 ---->以服务器时间为准 只要时间到 无论这帧是否包含所有玩家操作 都进行 广播进行帧驱动 private void OnOptimisticFrame(Session client, PlayerFrameCommand recvData) { int roleId = recvData.RoleId; long frame = recvData.Frame; Debug.Log(string.Format("Receive roleid={0} serverframe:{1} clientframe:{2} command:{3}", roleId, mCurrentFrame, frame, recvData.Commands.Count), ConsoleColor.DarkYellow); if (mFrameDic.ContainsKey(mCurrentFrame) == false) { mFrameDic[mCurrentFrame] = new Dictionary <int, List <Command> >(); } for (int i = 0; i < recvData.Commands.Count; ++i) { //乐观模式以服务器收到的时间为准 Command frameData = new Command(recvData.Commands[i].Frame, recvData.Commands[i].Type, recvData.Commands[i].Data.ToByteArray(), mFrameTime); if (mFrameDic[mCurrentFrame].ContainsKey(roleId) == false) { mFrameDic[mCurrentFrame].Add(roleId, new List <Command>()); } mFrameDic[mCurrentFrame][roleId].Add(frameData); } }
// 帧同步 ----->收到所有玩家的操作帧之后 进行帧的驱动 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); } }