@esengine/pathfinding 1.0.3 → 1.0.7
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.
- package/README.md +115 -7
- package/dist/pathfinding.cjs +1 -1
- package/dist/pathfinding.d.ts +1 -1
- package/dist/pathfinding.js +1 -1
- package/dist/pathfinding.mjs +1 -1
- package/package.json +7 -1
package/README.md
CHANGED
|
@@ -13,6 +13,8 @@
|
|
|
13
13
|
- **引擎兼容**:支持Cocos Creator和Laya引擎
|
|
14
14
|
- **TypeScript**:完整的类型定义
|
|
15
15
|
- **高性能**:对象池优化,减少GC压力
|
|
16
|
+
- **稳定可靠**:87.39%测试覆盖率,14个测试用例验证
|
|
17
|
+
- **类型安全**:严格的TypeScript类型检查
|
|
16
18
|
|
|
17
19
|
## 安装
|
|
18
20
|
|
|
@@ -37,7 +39,7 @@ npm install @esengine/pathfinding
|
|
|
37
39
|
### 基本使用
|
|
38
40
|
|
|
39
41
|
```typescript
|
|
40
|
-
import { AstarGridGraph, Vector2Utils } from '@esengine/pathfinding';
|
|
42
|
+
import { AStarPathfinder, AstarGridGraph, Vector2Utils } from '@esengine/pathfinding';
|
|
41
43
|
|
|
42
44
|
// 创建20x20的网格
|
|
43
45
|
const graph = new AstarGridGraph(20, 20);
|
|
@@ -52,9 +54,18 @@ graph.addWeightedNode(Vector2Utils.create(5, 5));
|
|
|
52
54
|
// 搜索路径
|
|
53
55
|
const start = Vector2Utils.create(0, 0);
|
|
54
56
|
const goal = Vector2Utils.create(19, 19);
|
|
57
|
+
|
|
58
|
+
// 方法1:使用图对象的便捷方法
|
|
55
59
|
const path = graph.searchPath(start, goal);
|
|
56
60
|
|
|
61
|
+
// 方法2:使用静态方法(更灵活)
|
|
62
|
+
const path2 = AStarPathfinder.searchPath(graph, start, goal);
|
|
63
|
+
|
|
64
|
+
// 检查路径是否存在(不返回具体路径)
|
|
65
|
+
const hasPath = AStarPathfinder.hasPath(graph, start, goal);
|
|
66
|
+
|
|
57
67
|
console.log('路径:', path);
|
|
68
|
+
console.log('路径存在:', hasPath);
|
|
58
69
|
```
|
|
59
70
|
|
|
60
71
|
### 广度优先搜索
|
|
@@ -134,6 +145,32 @@ export class PathfindingManager {
|
|
|
134
145
|
|
|
135
146
|
## API文档
|
|
136
147
|
|
|
148
|
+
### AStarPathfinder
|
|
149
|
+
|
|
150
|
+
A*算法核心实现(静态方法)。
|
|
151
|
+
|
|
152
|
+
```typescript
|
|
153
|
+
// 搜索完整路径
|
|
154
|
+
AStarPathfinder.searchPath<T>(graph: IAstarGraph<T>, start: T, goal: T): T[]
|
|
155
|
+
|
|
156
|
+
// 检查路径是否存在
|
|
157
|
+
AStarPathfinder.hasPath<T>(graph: IAstarGraph<T>, start: T, goal: T): boolean
|
|
158
|
+
|
|
159
|
+
// 底层搜索方法(返回节点对象)
|
|
160
|
+
AStarPathfinder.search<T>(graph: IAstarGraph<T>, start: T, goal: T): {
|
|
161
|
+
found: boolean;
|
|
162
|
+
goalNode?: AStarNode;
|
|
163
|
+
openSetNodes?: AStarNode[];
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
// 对象池管理
|
|
167
|
+
AStarPathfinder.clearPool(): void // 清理对象池
|
|
168
|
+
AStarPathfinder.getPoolStats(): { // 获取池统计信息
|
|
169
|
+
poolSize: number;
|
|
170
|
+
maxPoolSize: number;
|
|
171
|
+
}
|
|
172
|
+
```
|
|
173
|
+
|
|
137
174
|
### AstarGridGraph
|
|
138
175
|
|
|
139
176
|
A*算法网格图实现。
|
|
@@ -148,13 +185,19 @@ graph.defaultWeight: number // 默认移动成本(默认1)
|
|
|
148
185
|
graph.weightedNodeWeight: number // 加权节点成本(默认5)
|
|
149
186
|
|
|
150
187
|
// 方法
|
|
151
|
-
graph.searchPath(start, goal): IVector2[] //
|
|
152
|
-
graph.
|
|
188
|
+
graph.searchPath(start, goal): IVector2[] // 搜索完整路径(便捷方法)
|
|
189
|
+
graph.isNodePassable(node): boolean // 检查节点是否可通行
|
|
190
|
+
graph.isNodeInBounds(node): boolean // 检查节点是否在边界内
|
|
153
191
|
graph.addWall(wall): void // 添加单个障碍物
|
|
154
192
|
graph.addWalls(walls): void // 批量添加障碍物
|
|
155
193
|
graph.clearWalls(): void // 清空障碍物
|
|
156
194
|
graph.addWeightedNode(node): void // 添加加权节点
|
|
157
195
|
graph.clearWeightedNodes(): void // 清空加权节点
|
|
196
|
+
|
|
197
|
+
// IAstarGraph接口方法
|
|
198
|
+
graph.getNeighbors(node): IVector2[] // 获取邻居节点
|
|
199
|
+
graph.cost(from, to): number // 计算移动成本
|
|
200
|
+
graph.heuristic(node, goal): number // 计算启发式距离
|
|
158
201
|
```
|
|
159
202
|
|
|
160
203
|
### UnweightedGridGraph
|
|
@@ -193,31 +236,67 @@ Vector2Utils.distance(a, b) // 欧几里得距离
|
|
|
193
236
|
### 塔防游戏
|
|
194
237
|
|
|
195
238
|
```typescript
|
|
239
|
+
import { AStarPathfinder, AstarGridGraph } from '@esengine/pathfinding';
|
|
240
|
+
|
|
196
241
|
// 敌人寻路到基地
|
|
197
242
|
const graph = new AstarGridGraph(mapWidth, mapHeight);
|
|
198
243
|
towers.forEach(tower => graph.addWall(tower.position));
|
|
199
|
-
|
|
244
|
+
|
|
245
|
+
// 检查是否有路径(性能更好)
|
|
246
|
+
if (AStarPathfinder.hasPath(graph, spawnPoint, basePosition)) {
|
|
247
|
+
const path = AStarPathfinder.searchPath(graph, spawnPoint, basePosition);
|
|
248
|
+
enemy.followPath(path);
|
|
249
|
+
}
|
|
200
250
|
```
|
|
201
251
|
|
|
202
252
|
### RPG游戏
|
|
203
253
|
|
|
204
254
|
```typescript
|
|
255
|
+
import { AStarPathfinder, AstarGridGraph } from '@esengine/pathfinding';
|
|
256
|
+
|
|
205
257
|
// 角色移动寻路,设置不同地形权重
|
|
206
258
|
const graph = new AstarGridGraph(mapWidth, mapHeight);
|
|
207
259
|
swampTiles.forEach(tile => graph.addWeightedNode(tile));
|
|
208
260
|
graph.weightedNodeWeight = 3; // 沼泽地移动慢
|
|
209
|
-
|
|
261
|
+
|
|
262
|
+
const path = AStarPathfinder.searchPath(graph, playerPos, targetPos);
|
|
263
|
+
if (path.length > 0) {
|
|
264
|
+
player.moveTo(path);
|
|
265
|
+
}
|
|
210
266
|
```
|
|
211
267
|
|
|
212
268
|
### 迷宫游戏
|
|
213
269
|
|
|
214
270
|
```typescript
|
|
271
|
+
import { UnweightedGridGraph } from '@esengine/pathfinding';
|
|
272
|
+
|
|
215
273
|
// 简单迷宫寻路
|
|
216
274
|
const graph = new UnweightedGridGraph(mazeWidth, mazeHeight);
|
|
217
275
|
walls.forEach(wall => graph.walls.push(wall));
|
|
218
276
|
const path = graph.searchPath(startPos, exitPos);
|
|
219
277
|
```
|
|
220
278
|
|
|
279
|
+
### 性能优化示例
|
|
280
|
+
|
|
281
|
+
```typescript
|
|
282
|
+
import { AStarPathfinder } from '@esengine/pathfinding';
|
|
283
|
+
|
|
284
|
+
// 在游戏结束时清理对象池
|
|
285
|
+
function onGameEnd() {
|
|
286
|
+
AStarPathfinder.clearPool();
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
// 监控内存使用
|
|
290
|
+
function checkMemoryUsage() {
|
|
291
|
+
const stats = AStarPathfinder.getPoolStats();
|
|
292
|
+
console.log(`对象池使用: ${stats.poolSize}/${stats.maxPoolSize}`);
|
|
293
|
+
|
|
294
|
+
if (stats.poolSize > stats.maxPoolSize * 0.8) {
|
|
295
|
+
console.warn('对象池使用率较高,考虑优化');
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
```
|
|
299
|
+
|
|
221
300
|
## 文件结构
|
|
222
301
|
|
|
223
302
|
```
|
|
@@ -238,13 +317,42 @@ bin/
|
|
|
238
317
|
# 安装依赖
|
|
239
318
|
npm install
|
|
240
319
|
|
|
320
|
+
# 运行测试
|
|
321
|
+
npm test
|
|
322
|
+
|
|
323
|
+
# 测试覆盖率
|
|
324
|
+
npm run test:coverage
|
|
325
|
+
|
|
326
|
+
# 类型检查
|
|
327
|
+
npm run type-check
|
|
328
|
+
|
|
329
|
+
# 代码检查
|
|
330
|
+
npm run lint
|
|
331
|
+
|
|
241
332
|
# 构建
|
|
242
333
|
npm run build
|
|
243
334
|
|
|
244
|
-
#
|
|
245
|
-
|
|
335
|
+
# 完整CI检查
|
|
336
|
+
npm run ci
|
|
246
337
|
```
|
|
247
338
|
|
|
339
|
+
## 质量保证
|
|
340
|
+
|
|
341
|
+
- ✅ **14个测试用例**覆盖主要功能
|
|
342
|
+
- ✅ **87.39%代码覆盖率**
|
|
343
|
+
- ✅ **TypeScript严格模式**
|
|
344
|
+
- ✅ **ESLint代码规范**
|
|
345
|
+
- ✅ **CI自动化测试**
|
|
346
|
+
|
|
347
|
+
### 测试覆盖范围
|
|
348
|
+
|
|
349
|
+
- 基础路径查找功能
|
|
350
|
+
- 边界情况处理(起点=终点、超出边界、障碍物上)
|
|
351
|
+
- 错误情况处理(无路径、不可达)
|
|
352
|
+
- 性能和稳定性(大网格、多次搜索)
|
|
353
|
+
- 对象池内存管理
|
|
354
|
+
- 路径质量验证
|
|
355
|
+
|
|
248
356
|
## 许可证
|
|
249
357
|
|
|
250
358
|
MIT License
|
package/dist/pathfinding.cjs
CHANGED
package/dist/pathfinding.d.ts
CHANGED
package/dist/pathfinding.js
CHANGED
package/dist/pathfinding.mjs
CHANGED
package/package.json
CHANGED
|
@@ -1,10 +1,16 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@esengine/pathfinding",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.7",
|
|
4
4
|
"description": "寻路算法库,支持A*、广度优先等算法,适用于Cocos Creator、Laya等游戏引擎",
|
|
5
5
|
"main": "dist/pathfinding.cjs",
|
|
6
6
|
"module": "dist/pathfinding.mjs",
|
|
7
7
|
"types": "dist/pathfinding.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"import": "./dist/pathfinding.mjs",
|
|
11
|
+
"default": "./dist/pathfinding.cjs"
|
|
12
|
+
}
|
|
13
|
+
},
|
|
8
14
|
"files": [
|
|
9
15
|
"dist/**/*",
|
|
10
16
|
"README.md",
|