PathFind.ts 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. import { Vec3 } from "cc";
  2. import { ecs } from "../../../../../../extensions/oops-plugin-framework/assets/libs/ecs/ECS";
  3. import { smc } from "../../SingletonModuleComp";
  4. import { MapInfo } from "../../../checkpoint/model/CheckpointModel";
  5. import { ECSEntity } from "../../../../../../extensions/oops-plugin-framework/assets/libs/ecs/ECSEntity";
  6. import { ArrayUtil } from "../../../../../../extensions/oops-plugin-framework/assets/core/utils/ArrayUtil";
  7. @ecs.register('PathFind')
  8. export class PathFindComp extends ecs.Comp {
  9. private _path: Vec3[]
  10. private _canReach: boolean = false
  11. private _x: number
  12. private _y: number
  13. // private _mute: boolean = false
  14. // get mute(): boolean {
  15. // return this._mute
  16. // }
  17. // set mute(value: boolean) {
  18. // this._mute = value
  19. // }
  20. get y(): number {
  21. return this._y
  22. }
  23. set y(value: number) {
  24. this._y = value
  25. }
  26. get path(): Vec3[] {
  27. return this._path
  28. }
  29. set path(value: Vec3[]) {
  30. this._path = value
  31. }
  32. get canReach(): boolean {
  33. return this._canReach
  34. }
  35. set canReach(value: boolean) {
  36. this._canReach = value
  37. }
  38. get x(): number {
  39. return this._x
  40. }
  41. set x(value: number) {
  42. this._x = value
  43. }
  44. reset() {
  45. this.canReach = false
  46. this.path = null
  47. // this.mute = false
  48. }
  49. }
  50. @ecs.register('PathFindTrigger')
  51. export class PathFindTriggerComponent extends ecs.Comp {
  52. reset() {
  53. }
  54. }
  55. /** 路径查找 */
  56. export class PathFindSystem extends ecs.ComblockSystem<ecs.Entity> implements ecs.IEntityEnterSystem {
  57. filter(): ecs.IMatcher {
  58. return ecs.allOf(PathFindComp,PathFindTriggerComponent);
  59. }
  60. entityEnter(e: ecs.Entity): void {
  61. // const pathComp = e.get(PathFindComp)
  62. this.update(e)
  63. e.remove(PathFindTriggerComponent)
  64. }
  65. // entityRemove(e: ecs.Entity): void {
  66. // e.remove(PathFindComp)
  67. // }
  68. update(e: ECSEntity): void {
  69. const pathComp = e.get(PathFindComp)
  70. if (smc.initialize.account.checkpoint && smc.initialize.account.checkpoint.CheckpointModel) {
  71. const pathGrid = smc.initialize.account.checkpoint.CheckpointModel.path_grid
  72. const pathRes = this.findPath(ArrayUtil.copy2DArray(pathGrid), pathComp.x, pathComp.y)
  73. pathComp.path = pathRes
  74. if (pathRes && pathRes.length > 0) {
  75. pathComp.canReach = true
  76. } else {
  77. pathComp.canReach = false
  78. }
  79. }
  80. }
  81. findPath(grid: MapInfo[][], startX: number, startY: number): Vec3[] {
  82. // const cell = grid[startX][startY]
  83. // if (cell.fill == null) {
  84. // return null; // 起始格子是空的,无法移动
  85. // }
  86. let rows = grid.length;
  87. let cols = grid[0].length;
  88. let visited = Array.from({ length: rows }, () => Array(cols).fill(false));
  89. type pathQue = [number, number, Vec3[]]
  90. let queue: pathQue[] = [[startX, startY, null]]; // 初始位置和路径
  91. // 四个可能的移动方向(上、下、左、右)
  92. let directions = [[-1, 0], [1, 0], [0, -1], [0, 1]];
  93. while (queue.length > 0) {
  94. let [x, y, path] = queue.shift();
  95. visited[x][y] = true;
  96. // 检查是否到达顶部行
  97. if (x === 0) {
  98. return path ? path : [grid[x][y].pos];
  99. }
  100. for (let [dx, dy] of directions) {
  101. let newX = x + dx;
  102. let newY = y + dy;
  103. // 检查新位置是否有效
  104. if (newX >= 0 && newX < rows && newY >= 0 && newY < cols && !visited[newX][newY] && grid[newX][newY]?.fill == null) {
  105. queue.push([newX, newY, (path ? path.concat([grid[newX][newY]?.pos]) : [grid[x][y]?.pos, grid[newX][newY]?.pos])]);
  106. }
  107. }
  108. }
  109. return null; // 没有找到路径
  110. }
  111. }