GMap.ts 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. import { _decorator, MeshRenderer, Node, UITransform, Vec3 } from 'cc';
  2. import { BaseExp } from '../core/base/BaseExp';
  3. import { autoBind } from '../extend/AutoBind';
  4. import { Utils } from '../utils/Utils';
  5. const { ccclass, property } = _decorator;
  6. //埋伏点接口类
  7. export class AmbushPoint {
  8. //埋伏点位置节点数组
  9. public standPosArr: Vec3[] = [];
  10. //掩体点位置节点
  11. public ambushPosArr: Vec3[] = [];
  12. //逃跑点位置节点
  13. public escapePosArr: Vec3[] = [];
  14. //是否已经有人在此站位了
  15. public isVacancy: boolean = false;
  16. }
  17. @ccclass('GMap')
  18. export class GMap extends BaseExp {
  19. @autoBind({ type: Node, tooltip: "埋伏点配置节点" })
  20. public ambush_points: Node = null;
  21. @autoBind({type:Node,tooltip:"敌人出生区域"})
  22. public enemy_born_area: Node = null;
  23. @autoBind({type:Node,tooltip:"进门内线,用于敌人是否在门内"})
  24. public miidle_inline: Node = null;
  25. @autoBind({type:Node,tooltip:"进门外线,用于敌人是否在门外"})
  26. public miidle_outline: Node = null;
  27. @autoBind({type:Node,tooltip:"进去的大门"})
  28. public doors: Node = null;
  29. //埋伏点配置数组
  30. public ambushPoints: AmbushPoint[] = [];
  31. //游戏速度
  32. public game_speed: number = 1;
  33. start() {
  34. /*测试时使用 玩家坐标转换
  35. let n: Node = this.node.getChildByName('player_points');
  36. let pwww:Vec3 = Utils.convertPosition(this.node.getChildByName("player"),n);
  37. console.log("GGGGGGG = " + pwww);*/
  38. //区域隐藏
  39. const nodes:Node[] = this.ambush_points.children.flatMap(child => child.children);
  40. [this.enemy_born_area]
  41. .concat(nodes).forEach(e => {
  42. let m: MeshRenderer = e.getComponent(MeshRenderer);
  43. if(m){m.enabled = false}
  44. });
  45. }
  46. /**
  47. * 游戏速度
  48. */
  49. public multiplySpeed(): number{
  50. return this.game_speed;
  51. }
  52. /**
  53. * 解析埋伏点
  54. */
  55. private parseAmbushPoints() {
  56. this.ambushPoints = this.ambush_points.children.map(ambushNode => {
  57. const point = new AmbushPoint();
  58. point.isVacancy = false;
  59. //从节点结构获取坐标配置
  60. point.standPosArr = ambushNode.children
  61. .filter(e => e.name.startsWith('stand_'))
  62. .map(node => node.worldPosition.clone());
  63. point.ambushPosArr = ambushNode.children
  64. .filter(e => e.name.startsWith('bunker_'))
  65. .map(node => node.worldPosition.clone());
  66. point.escapePosArr = ambushNode.children
  67. .filter(e => e.name.startsWith('escape_'))
  68. .map(node => node.worldPosition.clone());
  69. return point;
  70. });
  71. }
  72. /**
  73. * 根据敌人信息得到敌人行走路径
  74. * @param eData 敌人数据
  75. * @param size 预制体大小
  76. * @returns
  77. */
  78. public getPaths(eData: any){
  79. let bornPos: Vec3 = this.getRandomBornPosition();
  80. //进入外门时的坐标
  81. const outerPos: Vec3 = this.getRandomPos(eData,this.miidle_outline);
  82. //进入内门时的坐标
  83. const innerPos: Vec3 = this.getRandomPos(eData,this.miidle_inline);
  84. //行走路径
  85. let paths: Array<Vec3> = [bornPos,outerPos,innerPos];
  86. //最后一个点特殊处理 包含(站位点、埋伏点、逃跑点) 随机一个埋伏点
  87. const ambush: AmbushPoint = this.getAmbushClas();
  88. ambush.isVacancy = true;
  89. eData.ambush = ambush;
  90. //随机一个站立点到最后坐标
  91. const endPos:Vec3 = Utils.randomArray(ambush.standPosArr)[0];
  92. endPos.x += Utils.getRandomFloat(1,0.2);
  93. paths.push(endPos);
  94. //测试时使用
  95. /*paths.forEach(e => {
  96. console.log("FFFFFF = " + this.node.getComponent(UITransform).convertToNodeSpaceAR(e));
  97. });*/
  98. return paths;
  99. }
  100. /**
  101. * 得到一个站位点
  102. */
  103. private getAmbushClas(){
  104. if(!this.ambushPoints
  105. || this.ambushPoints.length <= 0){
  106. //埋伏点类解析
  107. this.parseAmbushPoints();
  108. }
  109. //获取所有可用的埋伏点(未被占用的)
  110. const availablePoints = this.ambushPoints.filter(p => !p.isVacancy);
  111. if (availablePoints.length > 0) {
  112. //随机返回一个可用埋伏点
  113. return Utils.randomArray(availablePoints)[0];
  114. }
  115. // 当所有点位都被占用时,随机返回任意一个
  116. if(this.ambushPoints.length > 0) {
  117. return Utils.randomArray(this.ambushPoints)[0];
  118. }
  119. return null;
  120. }
  121. /**
  122. * 根据两个坐标点产生一个两个坐标点之前的随机点
  123. */
  124. public getRandomPos(eData:any,target: Node): Vec3 {
  125. //只有坦克走中间
  126. const isTan: boolean = eData.id == 20003;
  127. if(isTan){
  128. return target.worldPosition.clone();
  129. }
  130. let basePos: Vec3 = target.children[0].worldPosition.clone();
  131. if(target.children.length >= 2){
  132. let pos1: Vec3 = target.children[0].worldPosition.clone();
  133. let pos2: Vec3 = target.children[1].worldPosition.clone();
  134. //生成0-1的随机比例因子
  135. const ratio = Utils.getRandomFloat(0, 1);
  136. //分别在x和z轴进行线性插值 这儿为了看起来暂时保留x轴上的距离随机
  137. basePos.x = pos1.x + (pos2.x - pos1.x) * ratio;
  138. //y轴就是左边的间隔的距离
  139. basePos.z = pos1.z + (pos2.z - pos1.z) * ratio;
  140. }
  141. return basePos;
  142. }
  143. /**
  144. * 获取随机出生点位置
  145. */
  146. public getRandomBornPosition(): Vec3 {
  147. if (!this.enemy_born_area) return Vec3.ZERO;
  148. //获取3D节点的世界缩放
  149. const worldScale = this.enemy_born_area.getWorldScale();
  150. //使用X和Z轴缩放作为区域尺寸
  151. const areaWidth = worldScale.x;
  152. const areaDepth = worldScale.z;
  153. //在XZ平面生成随机坐标(Y轴保持地面高度)
  154. const randomX = (Math.random() - 0.5) * areaWidth;
  155. const randomZ = (Math.random() - 0.5) * areaDepth;
  156. //基于节点原点位置生成世界坐标 保持与出生区域相同高度
  157. const basePos = this.enemy_born_area.worldPosition;
  158. return new Vec3(
  159. basePos.x + randomX,
  160. basePos.y,
  161. basePos.z + randomZ
  162. );
  163. }
  164. /**
  165. * 还原数据
  166. */
  167. public resetData(){
  168. this.ambushPoints.forEach(e => {
  169. e.isVacancy = false;
  170. });
  171. }
  172. }