BasicTreeControlNode.ts 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235
  1. import { _ECommonState, _IBehaviorTreeConfig } from "../Data/CommonDataType";
  2. import { EventName } from "../Event/EventName";
  3. import EventManager from "../Event/EventManager";
  4. import Tool from "../Tool/Tool";
  5. import BasicTreeBehaviorNode from "./BasicTreeBehaviorNode";
  6. import BasicTreePreconditionNode from "./BasicTreePreconditionNode";
  7. /**
  8. * 基础行为树控制节点 - 逻辑层
  9. */
  10. export default abstract class BasicTreeControlNode extends BasicTreeBehaviorNode {
  11. /**子节点列表 */
  12. protected childs: Map<any, BasicTreeBehaviorNode>;
  13. /**当前运行的子节点列表 */
  14. protected _currentChilds: Array<any>;
  15. /**行为树配置 */
  16. public readonly behaviorTreeConfig: _IBehaviorTreeConfig;
  17. /**前提 */
  18. protected _precondition: BasicTreePreconditionNode;
  19. constructor (node: cc.Node, behaviorType: string, unitID: string, behaviorTreeConfig: _IBehaviorTreeConfig, childs?: Map<any, BasicTreeBehaviorNode>, precondition?: BasicTreePreconditionNode) {
  20. super(node, behaviorType, precondition);
  21. this._id = unitID;
  22. this.childs = childs || new Map<any, BasicTreeBehaviorNode>();
  23. this._currentChilds = new Array<any>();
  24. this.behaviorTreeConfig = behaviorTreeConfig;
  25. this.childs.forEach((value: BasicTreeBehaviorNode, key: any) => {
  26. value.id = this.id;
  27. value.precondition && (value.precondition.priority = this.behaviorTreeConfig.priority[key]);
  28. });
  29. this.childs.forEach((value: BasicTreeBehaviorNode, key: any) => {
  30. this.addComponentIntance(value);
  31. });
  32. EventManager.onEvent(EventName.Behavior.Behavior_SetBehaviorData, this, this.onSetBehaviorData);
  33. EventManager.onEvent(EventName.Behavior.Behavior_SetPreconditionData, this, this.onPreconditionData);
  34. EventManager.onEvent(EventName.Behavior.Behavior_GetBehaviorData, this, this.onGetBehaviorData);
  35. EventManager.onEvent(EventName.Behavior.Behavior_EnterBehavior, this, this.enter);
  36. EventManager.onEvent(EventName.Behavior.Behavior_ForceEnterBehavior, this, this.forceEnter);
  37. EventManager.onEvent(EventName.Behavior.Behavior_LeaveBehavior, this, this.leave);
  38. EventManager.onEvent(EventName.Behavior.Behavior_ForceLeaveBehavior, this, this.forceLeave);
  39. }
  40. public _update (dt: number): void {
  41. for (let index in this._currentChilds) {
  42. if (this.childs.get(this.currentChilds[index]).isEnabled == true ||
  43. this.childs.get(this.currentChilds[index]).enabled == true) {
  44. this.childs.get(this.currentChilds[index])._update(dt);
  45. }
  46. }
  47. }
  48. /**获得当前运行的子节点列表 */
  49. public get currentChilds (): Array<any> {
  50. return [].concat(this._currentChilds);
  51. }
  52. /**子节点是否正在运行 */
  53. public isCurrentChild (behavior: any): boolean {
  54. return this._currentChilds.includes(behavior);
  55. }
  56. /**设置子节点 */
  57. public setChild (behavior: any, behaviorNode: BasicTreeBehaviorNode): void {
  58. let _child: BasicTreeBehaviorNode = this.childs.get(behavior);
  59. if (_child != null) {
  60. _child._destroy();
  61. }
  62. this.childs.set(behavior, behaviorNode);
  63. }
  64. /**获得子节点 */
  65. public getChild (behavior: any): BasicTreeBehaviorNode {
  66. return this.childs.get(behavior);
  67. }
  68. /**设置行为数据响应方法 */
  69. public onSetBehaviorData (behavior: any, data: any): void {
  70. // 是否有该行为
  71. if (this.getChild(behavior) == null) {
  72. return;
  73. }
  74. this.getChild(behavior).customData = Tool.dataAllCover(this.getChild(behavior).customData, data);
  75. }
  76. /**设置前提数据响应方法 */
  77. public onPreconditionData (behavior: any, data: any): void {
  78. // 是否有该行为
  79. if (this.getChild(behavior) == null) {
  80. return;
  81. }
  82. this.getChild(behavior).precondition.customData = Tool.dataAllCover(this.getChild(behavior).precondition.customData, data);
  83. }
  84. /**获得行为数据响应方法 */
  85. private onGetBehaviorData (id: string, callback: Function): void {
  86. if (this.id == id) {
  87. callback(this._currentChilds);
  88. }
  89. }
  90. /**是否可以进入 */
  91. public isEnter (behavior: any, ...args: any): _ECommonState {
  92. // 是否有该行为
  93. if (this.childs.has(behavior) == false) {
  94. return _ECommonState.Fail;
  95. }
  96. // 遍历当前所有子节点,判断能否进入
  97. let commonState: _ECommonState = _ECommonState.None;
  98. if (this._currentChilds.length == 0 || this._currentChilds.includes(behavior) == true) {
  99. if (this.childs.get(behavior).getPreconditionResule(behavior, ...args) == _ECommonState.Success) {
  100. commonState = _ECommonState.Success;
  101. }
  102. else {
  103. commonState = _ECommonState.Fail;
  104. }
  105. }
  106. else {
  107. let child: BasicTreeBehaviorNode;
  108. for (let index in this._currentChilds) {
  109. child = this.childs.get(this._currentChilds[index]);
  110. if (child != null && child.getPreconditionResule(behavior, ...args) == _ECommonState.Success) {
  111. commonState = _ECommonState.Success;
  112. }
  113. else {
  114. commonState = _ECommonState.Fail;
  115. break;
  116. }
  117. }
  118. }
  119. return commonState;
  120. }
  121. /**强制进入行为 */
  122. public forceEnter (behavior: any, ...args: any): void {
  123. this._enter(behavior, ...args);
  124. }
  125. /**强制离开行为 */
  126. public forceLeave (behavior: any, ...args: any): void {
  127. this._leave(behavior, ...args);
  128. }
  129. public enter (behavior: any, ...args: any): void {
  130. // 是否有该行为
  131. if (this.childs.has(behavior) == false) {
  132. return;
  133. }
  134. if (this.isEnter(behavior, ...args) == _ECommonState.Success) {
  135. this._enter(behavior, ...args);
  136. }
  137. else {
  138. let child: BasicTreeBehaviorNode = this.childs.get(behavior);
  139. child.enterFail(...args);
  140. }
  141. }
  142. protected _enter (behavior: any, ...args: any): void {
  143. // 是否有该行为
  144. if (this.childs.has(behavior) == false) {
  145. return;
  146. }
  147. let child: BasicTreeBehaviorNode = this.childs.get(behavior);
  148. if (this._currentChilds.includes(behavior) == true) {
  149. child.enterAgain(...args);
  150. }
  151. else {
  152. this._currentChilds.push(behavior);
  153. this.leaveMutexChild(behavior);
  154. child.enter(...args);
  155. }
  156. }
  157. protected _leave (behavior: any, ...args: any): void {
  158. // 是否有该行为
  159. if (this.childs.has(behavior) == false) {
  160. return;
  161. }
  162. let child: BasicTreeBehaviorNode = this.childs.get(behavior);
  163. child.leave(...args);
  164. let index: number = this._currentChilds.indexOf(behavior);
  165. if (index != -1) {
  166. this._currentChilds.splice(index, 1);
  167. }
  168. }
  169. /**离开互斥子节点 */
  170. protected leaveMutexChild (behavior: any): void {
  171. if (this.behaviorTreeConfig != null) {
  172. let mutexChild: Array<string> = this.behaviorTreeConfig.mutexChild[behavior];
  173. let compatibilityChild: Array<string> = this.behaviorTreeConfig.compatibilityChild[behavior];
  174. // 若两者为空,排斥其他所有子节点
  175. if (mutexChild == null && compatibilityChild == null) {
  176. this.currentChilds.forEach((value: any, index: number) => {
  177. if (value != behavior) {
  178. this._leave(value);
  179. }
  180. });
  181. }
  182. else if (mutexChild != null) {
  183. for (let index: number = 0; index < this.currentChilds.length; index++) {
  184. // 若是互斥行为
  185. if (this.currentChilds[index] != behavior && mutexChild.includes(this.currentChilds[index]) == true) {
  186. if (this.isCurrentChild(this.currentChilds[index]) == true) {
  187. this._leave(this.currentChilds[index]);
  188. index--;
  189. }
  190. }
  191. }
  192. }
  193. else if (compatibilityChild != null) {
  194. for (let index: number = 0; index < this.currentChilds.length; index++) {
  195. // 若不是兼容行为
  196. if (this.currentChilds[index] != behavior && compatibilityChild.includes(this.currentChilds[index]) == false) {
  197. if (this.isCurrentChild(this.currentChilds[index]) == true) {
  198. this._leave(this.currentChilds[index]);
  199. index--;
  200. }
  201. }
  202. }
  203. }
  204. }
  205. }
  206. }