/// <summary> /// 注册一个 AOI 对象, 同时设置其默认 AOI 半径。注:每个对象都有一个默认的 AOI 半径,凡第一次进入半径范围的其它物体,都会触发 AOI 消息。 /// </summary> /// <param name="self"></param> /// <param name="unit"></param> public static void RegisterUnit(this AOISceneComponent self, AOIUnitComponent unit) { unit.Scene = self; AOICell cell = self.GetAOIGrid(unit.Position); cell.Add(unit); Log.Info("RegisterUnit:" + unit.Id + " Position:" + unit.Position + " grid x:" + cell.posx + ",y:" + cell.posy + " type" + unit.Type + " range" + unit.Range); using (var ListenerGrids = cell.GetNearbyGrid(unit.Range)) { for (int i = 0; i < ListenerGrids.Count; i++) { var item = ListenerGrids[i]; item.AddListener(unit); if (unit.Type == UnitType.Player) { using (var list = item.GetAllUnit()) { for (int j = 0; j < list.Count; j++) { var t = list[j]; Game.EventSystem.Publish(new AOIRegisterUnit() { Receive = unit, Unit = t }); } } } } } }
/// <summary> /// 获取自身为中心指定圈数的所有格子的所有指定类型单位 /// </summary> /// <param name="self"></param> /// <param name="type"></param> /// <returns></returns> public static ListComponent <AOIUnitComponent> GetNearbyUnit(this AOICell self, int turnNum, UnitType type = UnitType.ALL) { var grid = self.GetNearbyGrid(turnNum); if (grid != null) { var res = grid.GetAllUnit(type); grid.Dispose(); return(res); } return(ListComponent <AOIUnitComponent> .Create()); }
/// <summary> /// 改变格子 /// </summary> /// <param name="self"></param> /// <param name="newgrid"></param> public static void ChangeTo(this AOIUnitComponent self, AOICell newgrid) { AOICell oldgrid = self.Cell; Log.Info(self.Id + "From: " + " grid x:" + oldgrid.posx + ",y:" + oldgrid.posy + " ChangeTo:grid x:" + newgrid.posx + ",y:" + newgrid.posy); #region 广播给别人 using (DictionaryComponent <AOIUnitComponent, int> dic = DictionaryComponent <AOIUnitComponent, int> .Create()) { //Remove if (oldgrid.idUnits.ContainsKey(self.Type)) { for (int i = 0; i < oldgrid.ListenerUnits.Count; i++) { var item = oldgrid.ListenerUnits[i]; if (item.Type == UnitType.Player && item != self) { dic.Add(item, -1); } } oldgrid.idUnits[self.Type].Remove(self); self.Cell = null; } else { Log.Error("unit.Type=" + self.Type + "未添加就删除"); } //Add self.Cell = newgrid; if (Define.Debug && newgrid.idUnits[self.Type].Contains(self)) { Log.Error("newgrid.idUnits[self.Type].Contains(self)"); } newgrid.idUnits[self.Type].Add(self); for (int i = 0; i < newgrid.ListenerUnits.Count; i++) { var item = newgrid.ListenerUnits[i]; if (item.Type == UnitType.Player && item != self) { if (dic.ContainsKey(item)) { dic[item] += 1; } else { dic.Add(item, 1); } } } foreach (var item in dic) { if (item.Value > 0) { Game.EventSystem.Publish(new EventType.AOIRegisterUnit() { Receive = item.Key, Unit = self, }); } else if (item.Value < 0) { Game.EventSystem.Publish(new EventType.AOIRemoveUnit() { Receive = item.Key, Unit = self }); } } } #endregion #region 广播给自己 && 刷新监听 var older = oldgrid.GetNearbyGrid(self.Range); var newer = newgrid.GetNearbyGrid(self.Range); DictionaryComponent <AOICell, int> temp = DictionaryComponent <AOICell, int> .Create(); for (int i = 0; i < older.Count; i++) { var item = older[i]; temp[item] = -1; } for (int i = 0; i < newer.Count; i++) { var item = newer[i]; if (temp.ContainsKey(item)) { temp[item] = 0; } else { temp[item] = 1; } } ListComponent <AOIUnitComponent> adder = ListComponent <AOIUnitComponent> .Create(); ListComponent <AOIUnitComponent> remover = ListComponent <AOIUnitComponent> .Create(); foreach (var item in temp) { if (item.Value > 0) { item.Key.AddListener(self); adder.AddRange(item.Key.GetAllUnit()); } else if (item.Value < 0) { item.Key.RemoveListener(self); remover.AddRange(item.Key.GetAllUnit()); } } if (self.Type == UnitType.Player) { for (int i = 0; i < adder.Count; i++) { var item = adder[i]; if (item == self) { continue; } Log.Info("AOIRegisterUnit" + item.Id); Game.EventSystem.Publish(new EventType.AOIRegisterUnit { Receive = self, Unit = item }); } for (int i = 0; i < remover.Count; i++) { var item = remover[i]; if (item == self) { continue; } Log.Info("AOIRemoveUnit" + item.Id); Game.EventSystem.Publish(new EventType.AOIRemoveUnit() { Receive = self, Unit = item }); } } temp.Dispose(); newer.Dispose(); older.Dispose(); adder.Dispose(); remover.Dispose(); #endregion }