PathFind.ts 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  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. get x(): number {
  14. return this._x
  15. }
  16. set x(value: number) {
  17. this._x = value
  18. }
  19. get y(): number {
  20. return this._y
  21. }
  22. set y(value: number) {
  23. this._y = value
  24. }
  25. get path(): Vec3[] {
  26. return this._path
  27. }
  28. set path(value: Vec3[]) {
  29. this._path = value
  30. }
  31. get canReach(): boolean {
  32. return this._canReach
  33. }
  34. set canReach(value: boolean) {
  35. this._canReach = value
  36. }
  37. reset() {
  38. this.canReach = false
  39. this.path = null
  40. }
  41. }
  42. /** 路径查找 */
  43. export class PathFindSystem extends ecs.ComblockSystem<ecs.Entity> implements ecs.ISystemUpdate {
  44. filter(): ecs.IMatcher {
  45. return ecs.allOf(PathFindComp);
  46. }
  47. // entityEnter(e: ecs.Entity): void {
  48. // }
  49. // entityRemove(e: ecs.Entity): void {
  50. // }
  51. update(e: ECSEntity): void {
  52. if (smc.initialize.account.checkpoint && smc.initialize.account.checkpoint.CheckpointModel) {
  53. const pathGrid = smc.initialize.account.checkpoint.CheckpointModel.path_grid
  54. const pathComp = e.get(PathFindComp)
  55. const pathRes = this.findPath(ArrayUtil.copy2DArray(pathGrid), pathComp.x, pathComp.y)
  56. pathComp.path = pathRes
  57. if (pathRes && pathRes.length > 0) {
  58. pathComp.canReach = true
  59. } else {
  60. pathComp.canReach = false
  61. }
  62. }
  63. }
  64. findPath(grid: MapInfo[][], startX: number, startY: number): Vec3[] {
  65. // const cell = grid[startX][startY]
  66. // if (cell.fill == null) {
  67. // return null; // 起始格子是空的,无法移动
  68. // }
  69. let rows = grid.length;
  70. let cols = grid[0].length;
  71. let visited = Array.from({ length: rows }, () => Array(cols).fill(false));
  72. type pathQue = [number, number, Vec3[]]
  73. let queue: pathQue[] = [[startX, startY, null]]; // 初始位置和路径
  74. // 四个可能的移动方向(上、下、左、右)
  75. let directions = [[-1, 0], [1, 0], [0, -1], [0, 1]];
  76. while (queue.length > 0) {
  77. let [x, y, path] = queue.shift();
  78. visited[x][y] = true;
  79. // 检查是否到达顶部行
  80. if (x === 0) {
  81. return path ? path : [grid[x][y].pos];
  82. }
  83. for (let [dx, dy] of directions) {
  84. let newX = x + dx;
  85. let newY = y + dy;
  86. // 检查新位置是否有效
  87. if (newX >= 0 && newX < rows && newY >= 0 && newY < cols && !visited[newX][newY] && grid[newX][newY].fill === null) {
  88. queue.push([newX, newY, (path ? path.concat([grid[newX][newY].pos]) : [grid[x][y].pos, grid[newX][newY].pos])]);
  89. }
  90. }
  91. }
  92. return null; // 没有找到路径
  93. }
  94. }