/// <summary> /// 添加玩家 没有空位时检查游戏开始 /// </summary> /// <param name="gamer"></param> public static void Add(this Moba5V5Room self, Gamer gamer) { int seatIndex = self.GetEmptySeat(); //玩家需要获取一个座位坐下 if (seatIndex >= 0) { self.gamers[seatIndex] = gamer; self.isReadys[seatIndex] = false; self.seats[gamer.UserID] = seatIndex; } else { Log.Error("房间已满无法加入"); } //房间满员时 通知客户端加载场景 if (self.GetEmptySeat() == -1) { //为房间添加游戏组件 if (self.GetComponent <MobaControllerComponent>() == null) { self.AddComponent <MobaControllerComponent>().RoomReady(); } } }
/// <summary> /// 加入房间 /// </summary> /// <param name="self"></param> /// <param name="room"></param> /// <param name="matcher"></param> public static void JoinRoom(this Moba5V5Component self, Moba5V5Room room, Gamer gamer) { //玩家可能掉线 if (gamer == null) { return; } //玩家绑定待机房间 机器人不用绑定房间 if (gamer.UserID != 0) { self.Waiting.Add(gamer.UserID, room); } //为玩家添加座位 机器人也有座位 room.Add(gamer); //通知Gate服务器玩家匹配成功 参数:Gamer的InstanceId //Gate服务器将Actor类消息转发给Gamer if (gamer.UserID != 0) { ActorMessageSenderComponent actorProxyComponent = Game.Scene.GetComponent <ActorMessageSenderComponent>(); ActorMessageSender gamerActorProxy = actorProxyComponent.Get(gamer.ActorIDofUser); gamerActorProxy.Send(new B1002_Match5V5Sucess_M2G() { ActorIDofGamer = gamer.InstanceId }); } }
/// <summary> /// 检查匹配状态 每当有新排队玩家加入时执行一次 /// </summary> /// <param name="self"></param> public static void MatchingCheck(this Moba5V5Component self) { //如果有空房间 且 正在排队的玩家>0 Moba5V5Room room = self.GetFreeRoom(); if (room != null) { while (self.MatchingQueue.Count > 0 && room.Count < self.StartNumber) { self.JoinRoom(room, self.MatchingQueue.Dequeue()); } } //else 如果没有空房间 且 正在排队的玩家>=开局人数 else if (self.MatchingQueue.Count >= self.StartNumber) { //创建新房间 room = ComponentFactory.Create <Moba5V5Room>(); room.AddComponent <MailBoxComponent>(); self.FreeRooms.Add(room.Id, room); while (self.MatchingQueue.Count > 0 && room.Count < self.StartNumber) { self.JoinRoom(room, self.MatchingQueue.Dequeue()); } } }
/// <summary> /// 房间满员时通知客户端加载场景 /// </summary> /// <param name="self"></param> public static void RoomReady(this MobaControllerComponent self) { Moba5V5Room room = self.GetParent <Moba5V5Room>(); //机器人设置为已准备 for (int i = 0; i < room.gamers.Length; i++) { if (room.gamers[i].UserID == 0) { room.isReadys[i] = true; } } //向玩家发送加载请求 等待玩家准备 self.HeroList = BattleHelp.GetRandomTeam(10); //排除一个时:9, new List<long>() { mainId } A1004_CreateMoba5V5Secene_M2C message = new A1004_CreateMoba5V5Secene_M2C(); for (int i = 0; i < self.HeroList.Count; i++) { message.Gamers.Add(new GamerInfo() { UserID = room.gamers[i].UserID, HeroID = self.HeroList[i], Index = i + 1 }); } room.Broadcast(message); }
/// <summary> /// 玩家移动房间广播 index当前移动进度 offset发送坐标的数量 /// </summary> public static void BroadcastPath(this GamerPathComponent self, List <Vector3> path, int index, int offset) { Gamer gamer = self.GetParent <Gamer>(); Vector3 unitPos = gamer.Position; A1006_PathfindingResult_M2C pathfindingResult = new A1006_PathfindingResult_M2C(); pathfindingResult.X = unitPos.x; //当前位置 pathfindingResult.Y = unitPos.y; pathfindingResult.Z = unitPos.z; pathfindingResult.UserID = gamer.UserID; for (int i = 0; i < offset; ++i) //预测的坐标个数 先广播后移动 不包含当前坐标 { if (index + i >= self.ABPath.Result.Count) //预测坐标的序列不能大于坐标总数 { break; } Vector3 v = self.ABPath.Result[index + i]; pathfindingResult.Xs.Add(v.x); pathfindingResult.Ys.Add(v.y); pathfindingResult.Zs.Add(v.z); } //找到玩家所在房间进行广播 Moba5V5Room room = Game.Scene.GetComponent <Moba5V5Component>().GetGamingRoom(gamer); room.Broadcast(pathfindingResult); }
/// <summary> /// 刷新士兵 /// </summary> public static async ETVoid SpawnArmy(this MobaControllerComponent self) { TimerComponent timerComponent = Game.Scene.GetComponent <TimerComponent>(); long instanceId = self.InstanceId; Moba5V5Room room = self.GetParent <Moba5V5Room>(); //刷新初始波士兵 await timerComponent.WaitAsync(10000); room.Broadcast(new A1009_NewArmyWave_M2C()); self.wave += 1; while (true) { await timerComponent.WaitAsync(35000); //士兵每波刷新周期 if (self.InstanceId != instanceId) { return; } if (self.isGameOver) { return; } if (self.wave > 6) { room.Broadcast(new A1009_NewArmyWave_M2C()); } else //第7波开始刷新炮车 { room.Broadcast(new A1010_NewArmyWave_M2C()); } self.wave += 1; //波次+1 } }
/// <summary> /// 刷新野怪 /// </summary> public static async ETVoid SpawnWild(this MobaControllerComponent self) { TimerComponent timerComponent = Game.Scene.GetComponent <TimerComponent>(); Moba5V5Room room = self.GetParent <Moba5V5Room>(); await timerComponent.WaitAsync(30000); room.Broadcast(new A1011_SpawnMonster_M2C()); }
/// <summary> /// 获取玩家座位索引 /// </summary> /// <param name="id"></param> /// <returns></returns> public static int GetGamerSeat(this Moba5V5Room self, long id) { if (self.seats.TryGetValue(id, out int seatIndex)) { return(seatIndex); } return(-1); }
/// <summary> /// 返回玩家是否已准备 玩家不在房间时返回false /// </summary> /// <param name="self"></param> /// <param name="gamer"></param> /// <returns></returns> public static bool IsGamerReady(this Moba5V5Room self, Gamer gamer) { int seatIndex = self.GetGamerSeat(gamer.UserID); if (seatIndex > 0) { return(self.isReadys[seatIndex]); } return(false); }
/// <summary> /// 获取房间中的玩家 /// </summary> /// <param name="id"></param> /// <returns></returns> public static Gamer GetGamerFromUserID(this Moba5V5Room self, long id) { int seatIndex = self.GetGamerSeat(id); if (seatIndex >= 0) { return(self.gamers[seatIndex]); } return(null); }
/// <summary> /// 获取空座位 没有空位时返回-1 /// </summary> /// <returns>返回座位索引,没有空座位时返回-1</returns> public static int GetEmptySeat(this Moba5V5Room self) { for (int i = 0; i < self.gamers.Length; i++) { if (self.gamers[i] == null) { return(i); } } return(-1); }
/// <summary> /// 移除玩家并返回 玩家离开房间 /// </summary> /// <param name="id"></param> /// <returns></returns> public static Gamer Remove(this Moba5V5Room self, long id) { int seatIndex = self.GetGamerSeat(id); if (seatIndex >= 0) { Gamer gamer = self.gamers[seatIndex]; self.gamers[seatIndex] = null; self.seats.Remove(id); return(gamer); } return(null); }
/// <summary> /// 广播消息 通知客户端 /// </summary> /// <param name="message"></param> public static void Broadcast(this Moba5V5Room self, IActorMessage message) { foreach (Gamer gamer in self.gamers) { //如果玩家不存在或者不在线 if (gamer == null || gamer.isOffline || gamer.UserID == 0) { continue; } ActorMessageSenderComponent actorProxyComponent = Game.Scene.GetComponent <ActorMessageSenderComponent>(); ActorMessageSender actorProxy = actorProxyComponent.Get(gamer.ActorIDofClient); actorProxy.Send(message); } }
/// <summary> /// 当收到玩家准备消息时 检查游戏是否可以开始 /// </summary> /// <param name="self"></param> public static void CheckGameStart(this MobaControllerComponent self) { Moba5V5Room room = self.GetParent <Moba5V5Room>(); bool isOK = true; for (int i = 0; i < room.isReadys.Length; i++) { //遍历所有准备状态 任何一个状态为false结果都是false if (room.isReadys[i] == false) { isOK = false; } } if (isOK) { self.GameStart(); } }
protected override void Run(Gamer gamer, A1007_GamerReadyMoba5V5_C2M message) { Moba5V5Component moba = Game.Scene.GetComponent <Moba5V5Component>(); Moba5V5Room room = moba.GetWaitingRoom(gamer); if (room != null) { //找到玩家的座位顺序 设置其准备状态为真 int seatIndex = room.GetGamerSeat(gamer.UserID); if (seatIndex >= 0) { room.isReadys[seatIndex] = true; //检测开始游戏 room.GetComponent <MobaControllerComponent>().CheckGameStart(); } else { Log.Error("玩家不在正确的座位上"); } } }
/// <summary> /// 所有玩家已就绪游戏开始 /// </summary> /// <param name="self"></param> public static void GameStart(this MobaControllerComponent self) { //正式开始游戏前的准备 Moba5V5Room room = self.GetParent <Moba5V5Room>(); Moba5V5Component moba = Game.Scene.GetComponent <Moba5V5Component>(); //更改房间状态为游戏中 moba.FreeRooms.Remove(room.Id); moba.GamingRooms.Add(room.Id, room); //更改玩家状态为游戏中 for (int i = 0; i < room.gamers.Length; i++) { if (room.gamers[i].UserID != 0) { Gamer gamer = room.gamers[i]; moba.Waiting.Remove(gamer.UserID); moba.Playing.Add(gamer.UserID, room); } } //服务端加载游戏逻辑 for (int i = 0; i < room.gamers.Length; i++) { room.gamers[i].AddComponent <GamerMoveComponent>(); room.gamers[i].AddComponent <GamerPathComponent>(); room.gamers[i].Position = new Vector3(-10, 0, -10); } //开始服务端游戏计时 self.isGameStarted = true; self.gameStartTime = TimeHelper.ClientNow(); self.lastFrameCostTime = self.gameStartTime; self.SpawnArmy().NoAwait(); //周期刷新士兵 self.SpawnWild().NoAwait(); //刷新野怪 room.Broadcast(new A1008_GameStart_M2C()); }