@cc-component/cc-pathfinding 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. package/.cc-ex-component.md +12 -0
  2. package/assets/pathfinding/Interface.ts +73 -0
  3. package/assets/pathfinding/Interface.ts.meta +9 -0
  4. package/assets/pathfinding/base/AStarPathfinder.ts +264 -0
  5. package/assets/pathfinding/base/AStarPathfinder.ts.meta +9 -0
  6. package/assets/pathfinding/base/Common.ts +342 -0
  7. package/assets/pathfinding/base/Common.ts.meta +9 -0
  8. package/assets/pathfinding/base/GridMap.ts +314 -0
  9. package/assets/pathfinding/base/GridMap.ts.meta +9 -0
  10. package/assets/pathfinding/base/GridMovementController.ts +257 -0
  11. package/assets/pathfinding/base/GridMovementController.ts.meta +9 -0
  12. package/assets/pathfinding/base/IMapData.ts +13 -0
  13. package/assets/pathfinding/base/IMapData.ts.meta +9 -0
  14. package/assets/pathfinding/base/IPlayerBuff.ts +1 -0
  15. package/assets/pathfinding/base/IPlayerBuff.ts.meta +9 -0
  16. package/assets/pathfinding/base/MapBoxView.ts +386 -0
  17. package/assets/pathfinding/base/MapBoxView.ts.meta +9 -0
  18. package/assets/pathfinding/base/MapViewModel.ts +17 -0
  19. package/assets/pathfinding/base/MapViewModel.ts.meta +9 -0
  20. package/assets/pathfinding/base/Mapitem.ts +38 -0
  21. package/assets/pathfinding/base/Mapitem.ts.meta +9 -0
  22. package/assets/pathfinding/base/PathGridStateManager.ts +94 -0
  23. package/assets/pathfinding/base/PathGridStateManager.ts.meta +9 -0
  24. package/assets/pathfinding/base/PathfindingModule.ts +161 -0
  25. package/assets/pathfinding/base/PathfindingModule.ts.meta +9 -0
  26. package/assets/pathfinding/base/prefab/map_root.prefab +16290 -0
  27. package/assets/pathfinding/base/prefab/map_root.prefab.meta +13 -0
  28. package/assets/pathfinding/base/prefab.meta +9 -0
  29. package/assets/pathfinding/base.meta +9 -0
  30. package/assets/pathfinding.meta +9 -0
  31. package/assets.meta +9 -0
  32. package/index.ts +9 -0
  33. package/index.ts.meta +9 -0
  34. package/package.json +19 -0
  35. package/package.json.meta +11 -0
@@ -0,0 +1,9 @@
1
+ {
2
+ "ver": "4.0.24",
3
+ "importer": "typescript",
4
+ "imported": true,
5
+ "uuid": "5599834a-6bc7-46b6-98fe-cd266a07ebea",
6
+ "files": [],
7
+ "subMetas": {},
8
+ "userData": {}
9
+ }
@@ -0,0 +1,17 @@
1
+ import { Sprite } from 'cc';
2
+ import { Vec3 } from 'cc';
3
+ import { _decorator, Component, Node } from 'cc';
4
+ import { IMapData } from './IMapData';
5
+ const { ccclass, property } = _decorator;
6
+
7
+ @ccclass('MapViewModel')
8
+ export class MapViewModel implements IMapData {
9
+ col: number
10
+ row: number
11
+ position: Vec3
12
+ node: Node;
13
+ node_sp: Sprite;
14
+ node_chose_sp: Sprite;
15
+ bottom_positon: Vec3;
16
+ }
17
+
@@ -0,0 +1,9 @@
1
+ {
2
+ "ver": "4.0.24",
3
+ "importer": "typescript",
4
+ "imported": true,
5
+ "uuid": "a60bab4f-11c4-44e8-8036-0c7ceececdd7",
6
+ "files": [],
7
+ "subMetas": {},
8
+ "userData": {}
9
+ }
@@ -0,0 +1,38 @@
1
+ import { Sprite } from 'cc';
2
+ import { _decorator, Component, Node } from 'cc';
3
+ const { ccclass, property } = _decorator;
4
+
5
+ @ccclass('Mapitem')
6
+ export class Mapitem extends Component {
7
+ @property({ type: Sprite, displayName: '背景' })
8
+ bg: Sprite;
9
+ @property({ type: Sprite, displayName: '背景高亮' })
10
+ bgHighlight: Sprite;
11
+
12
+ row: number;
13
+ col: number;
14
+ /**点击回调 */
15
+ call: (row: number, col: number) => void;
16
+
17
+ onLoad() {
18
+ this.node.on(Node.EventType.TOUCH_END, this.click, this)
19
+
20
+ }
21
+ start() {
22
+
23
+ }
24
+
25
+ update(deltaTime: number) {
26
+
27
+ }
28
+
29
+ onDestroy() {
30
+ this.node.off(Node.EventType.TOUCH_END, this.click, this)
31
+ }
32
+
33
+ click() {
34
+ this.call?.(this.row, this.col)
35
+ }
36
+ }
37
+
38
+
@@ -0,0 +1,9 @@
1
+ {
2
+ "ver": "4.0.24",
3
+ "importer": "typescript",
4
+ "imported": true,
5
+ "uuid": "760944a7-bf43-418a-ba1b-fc7ba7bf6958",
6
+ "files": [],
7
+ "subMetas": {},
8
+ "userData": {}
9
+ }
@@ -0,0 +1,94 @@
1
+ import { Cell, cellKey } from './GridMap';
2
+
3
+ export interface PathGridOccupancy {
4
+ isOccupied(row: number, col: number): boolean;
5
+ occupy(row: number, col: number): void;
6
+ free(row: number, col: number): void;
7
+ }
8
+
9
+ export class PathGridStateManager {
10
+ private readonly temporaryCells = new Set<string>();
11
+ private readonly reservedCells = new Map<string, Set<symbol>>();
12
+
13
+ constructor(private readonly occupancy: PathGridOccupancy) {
14
+ }
15
+
16
+ reserveCurrent(cell: Cell, owner: symbol): void {
17
+ this.occupancy.occupy(cell.row, cell.col);
18
+ this.temporaryCells.add(cellKey(cell.row, cell.col));
19
+ this.addReservation(cellKey(cell.row, cell.col), owner);
20
+ }
21
+
22
+ tryReserve(previous: Cell, next: Cell, owner: symbol): boolean {
23
+ const nextKey = cellKey(next.row, next.col);
24
+ const nextOwners = this.reservedCells.get(nextKey);
25
+ if (nextOwners && [...nextOwners].some((reservedOwner) => reservedOwner !== owner)) {
26
+ return false;
27
+ }
28
+ if (this.occupancy.isOccupied(next.row, next.col) && !nextOwners?.has(owner)) {
29
+ return false;
30
+ }
31
+
32
+ this.occupancy.occupy(previous.row, previous.col);
33
+ this.occupancy.occupy(next.row, next.col);
34
+ this.temporaryCells.add(cellKey(previous.row, previous.col));
35
+ this.temporaryCells.add(nextKey);
36
+ this.addReservation(cellKey(previous.row, previous.col), owner);
37
+ this.addReservation(nextKey, owner);
38
+ return true;
39
+ }
40
+
41
+ completeMove(previous: Cell, next: Cell, owner: symbol): void {
42
+ const previousKey = cellKey(previous.row, previous.col);
43
+ if (this.removeReservation(previousKey, owner)) {
44
+ this.temporaryCells.delete(previousKey);
45
+ if (!this.reservedCells.has(previousKey)) {
46
+ this.occupancy.free(previous.row, previous.col);
47
+ }
48
+ }
49
+
50
+ this.occupancy.occupy(next.row, next.col);
51
+ this.temporaryCells.add(cellKey(next.row, next.col));
52
+ this.addReservation(cellKey(next.row, next.col), owner);
53
+ }
54
+
55
+ release(owner?: symbol): void {
56
+ for (const [key, owners] of this.reservedCells) {
57
+ if (owner && !owners.has(owner)) {
58
+ continue;
59
+ }
60
+ if (owner) {
61
+ owners.delete(owner);
62
+ } else {
63
+ owners.clear();
64
+ }
65
+ if (owners.size > 0) {
66
+ continue;
67
+ }
68
+ const [row, col] = key.split(',').map(Number);
69
+ this.occupancy.free(row, col);
70
+ this.reservedCells.delete(key);
71
+ this.temporaryCells.delete(key);
72
+ }
73
+ }
74
+
75
+ private addReservation(key: string, owner: symbol): void {
76
+ let owners = this.reservedCells.get(key);
77
+ if (!owners) {
78
+ owners = new Set<symbol>();
79
+ this.reservedCells.set(key, owners);
80
+ }
81
+ owners.add(owner);
82
+ }
83
+
84
+ private removeReservation(key: string, owner: symbol): boolean {
85
+ const owners = this.reservedCells.get(key);
86
+ if (!owners || !owners.delete(owner)) {
87
+ return false;
88
+ }
89
+ if (owners.size === 0) {
90
+ this.reservedCells.delete(key);
91
+ }
92
+ return true;
93
+ }
94
+ }
@@ -0,0 +1,9 @@
1
+ {
2
+ "ver": "4.0.24",
3
+ "importer": "typescript",
4
+ "imported": true,
5
+ "uuid": "219dad89-34cd-4c9f-8afe-b9d1d8fade3b",
6
+ "files": [],
7
+ "subMetas": {},
8
+ "userData": {}
9
+ }
@@ -0,0 +1,161 @@
1
+ import { _decorator, Component, Node, v3 } from 'cc';
2
+ import { MapBoxView } from './MapBoxView';
3
+ import { Vec3 } from 'cc';
4
+ import { MapViewModel } from './MapViewModel';
5
+ import { Color } from 'cc';
6
+ import { AttackDistance } from './Common';
7
+ import { GridMovementController } from './GridMovementController';
8
+ const { ccclass, property } = _decorator;
9
+
10
+ @ccclass('PathfindingModule')
11
+ export class PathfindingModule {
12
+ private static instance: PathfindingModule;
13
+ private constructor() {
14
+
15
+ }
16
+ static get Ins() {
17
+ if (!this.instance) {
18
+ this.instance = new PathfindingModule();
19
+ }
20
+ return this.instance;
21
+ }
22
+
23
+ map_view: MapBoxView;
24
+ private static movementController: GridMovementController = null;
25
+
26
+ static SetMovementController(controller: GridMovementController): void {
27
+ this.movementController = controller;
28
+ }
29
+
30
+ static InitMovementController(scheduler: Component, options?: { retryDelay?: number; moveDuration?: number }): void {
31
+ if (!this.movementController) {
32
+ this.movementController = new GridMovementController(scheduler, options);
33
+ }
34
+ }
35
+
36
+ static SetPosition(playerNode: Node, position: { row: number, col: number }): void {
37
+ this.movementController?.setPosition(playerNode, position);
38
+ }
39
+
40
+ static GetPosition(playerNode: Node): { row: number, col: number } {
41
+ return this.movementController?.getPosition(playerNode) ?? { row: 0, col: 0 };
42
+ }
43
+
44
+ static MoveTo(playerNode: Node, target: { row: number, col: number }, attackDistance: AttackDistance, openColor: boolean, callBack?: () => void): void {
45
+ this.movementController?.moveTo(playerNode, target, attackDistance, openColor, callBack);
46
+ }
47
+
48
+ static CancelMove(playerNode: Node, preserveCurrent = false): void {
49
+ this.movementController?.cancel(playerNode, preserveCurrent);
50
+ }
51
+
52
+ static DestroyMovement(): void {
53
+ this.movementController?.destroy();
54
+ this.movementController = null;
55
+ }
56
+
57
+ static Init(map_view: MapBoxView) {
58
+ this.Ins.map_view = map_view;
59
+ map_view.InitView();
60
+ }
61
+ static Destroy() {
62
+ this.Ins.map_view = null;
63
+
64
+ }
65
+ // 调用 A* 路径寻找,从 (1,1) 到 (5,5)
66
+ static TracePath(start: { row: number, col: number }, end: { row: number, col: number }, attackDis: AttackDistance, openColor?: boolean): { row: number, col: number }[] {
67
+ return this.Ins.map_view.TracePath(start, end, attackDis, openColor)
68
+ }
69
+
70
+ // 占用某个节点
71
+ static OccupyNode(row: number, col: number, openColor?: boolean) {
72
+ this.Ins.map_view.occupyNode(row, col, openColor)
73
+ }
74
+
75
+ static IsOccupied(row: number, col: number): boolean {
76
+ return this.Ins.map_view.isOccupied(row, col);
77
+ }
78
+
79
+ // 节点可以用
80
+ static FreeNode(row: number, col: number) {
81
+ this.Ins.map_view.freeNode(row, col)
82
+
83
+ }
84
+
85
+ // 获取指定行列位置的坐标
86
+ static GetMapPosition(row: number, col: number): Vec3 {
87
+ return this.Ins.map_view.GetMapPosition(row, col)
88
+ }
89
+
90
+ // 获取指定位置的MapViewModel
91
+ static CreateMapModel(row: number, col: number): MapViewModel {
92
+ const map = new MapViewModel();
93
+ map.row = row;
94
+ map.col = col;
95
+ map.position = v3(0, 0, 0)
96
+ map.bottom_positon = v3(0, 0, 0)
97
+ return map;
98
+ }
99
+ // 获取指定位置的MapViewModel
100
+ static GetMapModel(row: number, col: number): MapViewModel {
101
+ return this.Ins.map_view.GetMapModel(row, col)
102
+ }
103
+ //获取所有的map
104
+ static GetSeatModelList(): MapViewModel[][] {
105
+ return this.Ins.map_view.GetSeatModelList();
106
+ }
107
+
108
+ /*获取目标点周围最近的位置*/
109
+ static CheckAvailableSurrounding(
110
+ target: { row: number, col: number, dis: number },
111
+ ): { row: number, col: number }[] {
112
+ return this.Ins.map_view.checkAvailableSurrounding(target.row, target.col, target.dis)
113
+ }
114
+
115
+ //在攻击距离内,
116
+ static IsAttackDistance(model1: MapViewModel, model2: MapViewModel, maxDistance: number): boolean {
117
+ return this.Ins.map_view.IsAttackDistance(model1, model2, maxDistance)
118
+ }
119
+
120
+ static TargetColor(row, col, dis: number) {
121
+ const map_row = PathfindingModule.Ins.map_view.row;
122
+ const map_col = PathfindingModule.Ins.map_view.col;
123
+ if (row >= 0 && row < map_row && col >= 0 && col < map_col) {
124
+ PathfindingModule.ClearColor()
125
+ const list = PathfindingModule.CheckAvailableSurrounding({ row, col, dis })
126
+ list.forEach(model => {
127
+ const map = PathfindingModule.GetMapModel(model.row, model.col)
128
+ map.node_chose_sp.color = Color.GREEN
129
+ map.node_chose_sp.node.active = true
130
+ })
131
+ const map = PathfindingModule.GetMapModel(row, col)
132
+ map.node_chose_sp.color = Color.YELLOW
133
+ map.node_chose_sp.node.active = true
134
+
135
+ }
136
+ }
137
+ static SetColorVisible(visible: boolean) {
138
+ this.Ins.map_view.SetColorVisible(visible)
139
+ }
140
+ static ClearColor() {
141
+ const all = PathfindingModule.GetSeatModelList()
142
+ all.forEach(list => {
143
+ list.forEach(map => {
144
+ map.node_chose_sp.node.active = false
145
+ })
146
+ })
147
+ }
148
+ static ClearColorPath() {
149
+ this.Ins.map_view.ClearColor()
150
+ }
151
+ // 判断目标点是否被包围
152
+ static IsClosedLoop(
153
+ targetRow: number,
154
+ targetCol: number, maxDistance: number
155
+ ): boolean {
156
+ return this.Ins.map_view.isClosedLoop(targetRow, targetCol, maxDistance)
157
+
158
+ }
159
+ }
160
+
161
+ window.PathfindingModule = PathfindingModule;
@@ -0,0 +1,9 @@
1
+ {
2
+ "ver": "4.0.24",
3
+ "importer": "typescript",
4
+ "imported": true,
5
+ "uuid": "62642350-f8d4-4516-8def-6fb058e4f52c",
6
+ "files": [],
7
+ "subMetas": {},
8
+ "userData": {}
9
+ }