EntitiesComponent.cs 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327
  1. using FL.Battle;
  2. using FL.Data;
  3. using FL.Nodes.GameMain;
  4. using System.Collections.Generic;
  5. using XGame;
  6. using XGame.Database;
  7. using XGame.Framework.Asyncs;
  8. using XGame.Framework.Components;
  9. using XGame.Framework.Interfaces;
  10. using XGame.Framework.Map;
  11. using XGame.Framework.Time;
  12. namespace FL.Map.TestMainMap
  13. {
  14. public interface IEntitiesContext
  15. {
  16. IMapAssetModule Asset { get; }
  17. ITimeModule Time { get; }
  18. TestMainMapVM VM { get; }
  19. }
  20. public class EntitiesComponent : Component<IEntitiesContext>, ILateUpdate
  21. {
  22. private PlayerEntityView _player;
  23. private Dictionary<int, PartnerEntityView> _partnerMap = new Dictionary<int, PartnerEntityView>();
  24. /// <summary>
  25. /// 怪物的实例对象
  26. /// </summary>
  27. private Dictionary<int, MonsterEntityView> _monsterMap = new Dictionary<int, MonsterEntityView>();
  28. private TargetSelector _selector;
  29. private ITimer _selectorTimer;
  30. public override int Order => 0;
  31. protected override void OnEnable(object intent)
  32. {
  33. InitSelector();
  34. EventSingle.Instance.AddListener(EventDefine.GameMainMapLoadEntities, OnLoadEntities);
  35. EventSingle.Instance.AddListener(EventDefine.GameMainMapRemoveEntity, OnRemoveEntity);
  36. EventSingle.Instance.AddListener(EventDefine.GameMainMapFindTarget, OnFindTarget);
  37. EventSingle.Instance.AddListener(EventDefine.GameMainMapStartMask, OnStartMask);
  38. }
  39. protected override void OnDisable()
  40. {
  41. EventSingle.Instance.RemoveListener(EventDefine.GameMainMapLoadEntities, OnLoadEntities);
  42. EventSingle.Instance.RemoveListener(EventDefine.GameMainMapRemoveEntity, OnRemoveEntity);
  43. EventSingle.Instance.RemoveListener(EventDefine.GameMainMapFindTarget, OnFindTarget);
  44. EventSingle.Instance.RemoveListener(EventDefine.GameMainMapStartMask, OnStartMask);
  45. ClearSelector();
  46. Context.VM.Camera.Target = null;
  47. Context.Asset.Recycle(_player);
  48. foreach (var partner in _partnerMap.Values)
  49. {
  50. Context.Asset.Recycle(partner);
  51. }
  52. _partnerMap.Clear();
  53. foreach (var monster in _monsterMap.Values)
  54. {
  55. Context.Asset.Recycle(monster);
  56. }
  57. _monsterMap.Clear();
  58. }
  59. protected override void OnDispose()
  60. {
  61. }
  62. void ILateUpdate.LateUpdate(int millisecond)
  63. {
  64. Context.VM.UpdateMapMoveTime(millisecond);
  65. Context.VM.Camera.OnLateUpdate(millisecond);
  66. }
  67. #region 事件监听
  68. private void OnLoadEntities(int eventId, object args)
  69. {
  70. var dto = (LoadEntitiesDto)args;
  71. var asyncGroup = new AsyncGroup();
  72. if (dto.player != null)
  73. { // 第一波怪物,玩家不存在时
  74. var playerAsync = Context.Asset.LoadEntity<PlayerEntityView>("Player", Context.VM.PlayerRoot);
  75. playerAsync.On(_ =>
  76. {
  77. var entityView = playerAsync.Result;
  78. if (entityView == null)
  79. {
  80. return;
  81. }
  82. entityView.Entity = dto.player;
  83. Context.VM.Camera.Target = entityView.GetComponent<MoveComponent>();// behaviour.transform;
  84. _player = entityView;
  85. _selector.Register(entityView);
  86. });
  87. playerAsync.Join(asyncGroup);
  88. }
  89. else if (dto.isChapterChanged)
  90. {
  91. Context.VM.Reset();
  92. _player.Reset();
  93. foreach (var item in _partnerMap)
  94. {
  95. item.Value.Reset();
  96. }
  97. }
  98. var partnerCount = dto.partners?.Length ?? 0;
  99. if (partnerCount > 0)
  100. { // 创建伙伴实例
  101. for (var i = 0; i < partnerCount; i++)
  102. {
  103. var partner = dto.partners[i];
  104. var table = PartnerTableRepo.Get(partner.TableId);
  105. var loadAsync = Context.Asset.LoadEntity<PartnerEntityView>(table.Model, Context.VM.PlayerRoot);
  106. loadAsync.On(_ =>
  107. {
  108. var entityView = loadAsync.Result;
  109. if (entityView == null)
  110. {
  111. return;
  112. }
  113. entityView.Entity = partner;
  114. entityView.BodyMirror();
  115. _partnerMap.Add(partner.EntityId, entityView);
  116. _selector.Register(entityView);
  117. });
  118. loadAsync.Join(asyncGroup);
  119. }
  120. }
  121. var monsterCount = dto.monsters?.Length ?? 0;
  122. if (monsterCount > 0)
  123. { // 创建怪物实例
  124. for (var i = 0; i < monsterCount; i++)
  125. {
  126. var monster = dto.monsters[i];
  127. var table = MonsterTableRepo.Get(monster.TableId);
  128. var loadAsync = Context.Asset.LoadEntity<MonsterEntityView>(table.Model, Context.VM.EnemyRoot);
  129. loadAsync.On(_ =>
  130. {
  131. var entityView = loadAsync.Result;
  132. if (entityView == null)
  133. {
  134. return;
  135. }
  136. entityView.Entity = monster;
  137. entityView.Entity = monster;
  138. _monsterMap.Add(monster.EntityId, entityView);
  139. _selector.Register(entityView);
  140. });
  141. loadAsync.Join(asyncGroup);
  142. }
  143. }
  144. asyncGroup.On(_ =>
  145. {
  146. //Entities加载完成,开始移动
  147. if (dto.isPlayerMove)
  148. {
  149. var args = new MoveArgs
  150. {
  151. target = dto.battlePosition,
  152. speed = _player.Entity.Attr.MoveSpeed,
  153. callback = () =>
  154. {
  155. // 玩家移动速度快,先到目标坐标
  156. _player.State = EEntityState.Alert;
  157. _selector.Start(new FindTargetArgs()
  158. {
  159. entityId = _player.Entity.EntityId,
  160. entityType = EEntityType.Monster,
  161. range = 6,
  162. skillId = PlayerData.Instance.skillId
  163. });
  164. if (dto.isChapterChanged)
  165. {
  166. Context.VM.SetFocusPosition(_player.Position);
  167. }
  168. }
  169. };
  170. _player.State = EEntityState.Protected;
  171. _player.MoveTo(args);
  172. foreach (var item in _partnerMap)
  173. {
  174. var entityView = item.Value;
  175. var entity = entityView.Entity;
  176. var table = PartnerTableRepo.Get(entity.TableId);
  177. var tarPosition = dto.battlePosition;
  178. tarPosition += PlayerData.Instance.GetSwordOffset((int)table.Type - 1);
  179. var moveArgs = new MoveArgs
  180. {
  181. target = tarPosition,
  182. speed = entity.Attr.MoveSpeed,
  183. callback = () =>
  184. {
  185. entityView.State = EEntityState.Alert;
  186. _selector.Start(new FindTargetArgs()
  187. {
  188. entityId = entity.EntityId,
  189. entityType = EEntityType.Monster,
  190. range = entity.Attr.AtkRange,
  191. skillId = table.Skill,
  192. });
  193. }
  194. };
  195. entityView.State = EEntityState.Protected;
  196. entityView.MoveTo(moveArgs);
  197. }
  198. }
  199. var monsterCount = dto.monsters?.Length ?? 0;
  200. for (var mIdx = 0; mIdx < monsterCount; mIdx++)
  201. {
  202. var entity = dto.monsters[mIdx];
  203. //var monsterTable = MonsterTableRepo.Get(entity.TableId);
  204. var tarPosition = entity.TargetPosition;
  205. tarPosition.y += (-dto.monsterMoveDistance + entity.Attr.AtkRange + entity.Attr.Radius);
  206. var entityView = _monsterMap[entity.EntityId];
  207. var args = new MoveArgs
  208. {
  209. target = tarPosition,
  210. speed = entity.Attr.MoveSpeed,
  211. delay = dto.monsterMoveDelay,
  212. callback = () =>
  213. {
  214. entityView.State = EEntityState.Alert;
  215. _selector.Start(new FindTargetArgs()
  216. {
  217. entityId = entity.EntityId,
  218. entityType = EEntityType.Player,
  219. range = entity.Attr.AtkRange,
  220. skillId = MonsterTableRepo.Get(entity.TableId).Skill,
  221. });
  222. }
  223. };
  224. entityView.State = EEntityState.Protected;
  225. entityView.MoveTo(args);
  226. }
  227. });
  228. asyncGroup.End();
  229. }
  230. private void OnRemoveEntity(int eventId, object args)
  231. {
  232. var entityId = (int)args;
  233. if (_monsterMap.TryGetValue(entityId, out var entity))
  234. {
  235. _monsterMap.Remove(entityId);
  236. _selector?.Unregister(entity);
  237. Context.Asset.Recycle(entity);
  238. return;
  239. }
  240. if (_partnerMap.TryGetValue(entityId, out var partner))
  241. {
  242. _partnerMap.Remove(entityId);
  243. _selector?.Unregister(partner);
  244. Context.Asset.Recycle(partner);
  245. return;
  246. }
  247. if (entityId == _player?.Entity.EntityId)
  248. {
  249. Context.Asset.Recycle(_player);
  250. _selector?.Unregister(_player);
  251. _player = null;
  252. }
  253. }
  254. #endregion
  255. #region 目标选择
  256. private void InitSelector()
  257. {
  258. if (_selector == null)
  259. {
  260. _selector = new TargetSelector();
  261. }
  262. _selectorTimer = Context.Time.AddLooperTimer(100, _selector.Selects);
  263. }
  264. private void ClearSelector()
  265. {
  266. _selector?.Clear();
  267. _selectorTimer?.Cancel();
  268. _selectorTimer = null;
  269. }
  270. private void OnFindTarget(int eventId, object args)
  271. {
  272. var targetArgs = (FindTargetArgs)args;
  273. _selector?.Start(targetArgs);
  274. }
  275. #endregion
  276. #region 黑屏
  277. private void OnStartMask(int eventId, object args)
  278. {
  279. var duration = 2;
  280. PlayerMoveToCenter(duration);
  281. Context.VM.ShowBlackMask(duration, () =>
  282. {
  283. EventSingle.Instance.Notify(EventDefine.GameMainMapEndMask);
  284. });
  285. }
  286. /// <summary>
  287. /// 玩家移动到屏幕中心
  288. /// </summary>
  289. /// <param name="duration">单位:秒</param>
  290. private void PlayerMoveToCenter(float duration)
  291. {
  292. var centerPosition = Context.VM.Camera.TopCenterToWorldPosition();
  293. var distance = centerPosition.y - _player.Position.y;
  294. var speed = distance / duration;
  295. var targetPosition = Context.VM.PlayerRoot.InverseTransformPoint(centerPosition);
  296. Log.Debug($"PlayerMoveToCenter Player World:{_player.Position} Local:{_player.LocalPosition} Center World:{centerPosition} Local:{targetPosition}");
  297. var args = new MoveArgs
  298. {
  299. target = targetPosition,
  300. speed = speed,
  301. };
  302. _player.State = EEntityState.Protected;
  303. _player.MoveTo(args);
  304. foreach (var item in _partnerMap)
  305. {
  306. var entityView = item.Value;
  307. var entity = entityView.Entity;
  308. var table = PartnerTableRepo.Get(entity.TableId);
  309. var tarPosition = targetPosition;
  310. tarPosition += PlayerData.Instance.GetSwordOffset((int)table.Type - 1);
  311. var moveArgs = new MoveArgs
  312. {
  313. target = tarPosition,
  314. speed = speed,
  315. };
  316. entityView.State = EEntityState.Protected;
  317. entityView.MoveTo(moveArgs);
  318. }
  319. }
  320. #endregion
  321. }
  322. }