private void BeginGame() { mCurrentFrame = 1; mBegin = true; //游戏开始 mFrameTime = 0; //服务器添加命令 for (int i = 0; i < 3; ++i) { Monster monster = new Monster(mMonsterId++); mMonsterList.Add(monster); monster.mLifeEntity.name = "Server " + monster.Id; monster.mLifeEntity.type = 2;//Boss monster.Position = new UnityEngine.Vector3Int(((i + 1) * (i % 2 == 0 ? -3 : 3)) * 10000, 1 * 10000, -10 * 10000); CMD_CreateMonster data = new CMD_CreateMonster(); data.Id = SERVER_ROLEID;//服务器也参与整局游戏,负责发送一些全局命令,比如Buff、怪物生成 data.Monster = ProtoTransfer.Get(monster.mLifeEntity); data.Position = ProtoTransfer.Get(monster.Position); data.Direction = ProtoTransfer.Get(monster.Direction); Command cmd = new Command(); cmd.Set(CommandID.CreateMonster, data); AddCommand(cmd); } }
/// <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); } }
private void OnReceiveReady(Session client, BroadPlayerReady recvData) { if (recvData == null || client == null) { return; } int readyCount = 0; for (int i = 0; i < mPlayerList.Count; ++i) { Player player = mPlayerList[i]; if (recvData.RoleId == player.Roleid && client == player.Client) { player.Position = ProtoTransfer.Get(recvData.Position); player.Direction = ProtoTransfer.Get(recvData.Direction); player.SetReady(); } //广播玩家准备(包括自己) if (mProtocol == Protocol.UDP) { player.SendUdp(MessageID.BroadRoomOperation, recvData); } else if (mProtocol == Protocol.KCP) { player.SendKcp(MessageID.BroadRoomOperation, recvData); } if (player.Ready) { readyCount++; } } if (mBegin == false) { //所有的玩家都准备好了,可以开始同步 if (readyCount >= mPlayerList.Count) { mFrameDic = new Dictionary <long, Dictionary <int, List <Command> > >(); BroadBattleGameStart sendData = new BroadBattleGameStart(); sendData.BattleID = mBattleId; sendData.RandSeed = mRandSeed; sendData.UdpPort = ServerConfig.UDP_PORT; sendData.FrameInterval = mFrameInterval; BroadCast(MessageID.BroadBattleStart, sendData, true); BeginGame(); } } else //断线重连 { Player user = GetPlayer(recvData.RoleId); if (user != null) { BroadBattleGameStart sendData = new BroadBattleGameStart(); sendData.BattleID = mBattleId; sendData.RandSeed = mRandSeed; sendData.UdpPort = ServerConfig.UDP_PORT; sendData.FrameInterval = mFrameInterval; //user.SendUdp(MessageID.GM_BEGIN_BC, sendData); /* * GM_Frame_BC frameData = new GM_Frame_BC(); * * //给他发送当前帧之前的数据 * for (long frame = 1; frame < mCurrentFrame - 1; ++frame) * { * if (mFrameDic.ContainsKey(frame)) * { * frameData.frame = frame; * frameData.frametime = 0; * var it = mFrameDic[frame].GetEnumerator(); * while (it.MoveNext()) * { * for (int i = 0, count = it.Current.Value.Count; i < count; ++i) * { * GMCommand cmd = ProtoTransfer.Get(it.Current.Value[i]); * * frameData.command.Add(cmd); * } * } * user.SendUdp(MessageID.GM_FRAME_BC, frameData); * } * } */ } } }