npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

@esengine/pathfinding

v1.0.8

Published

寻路算法库,支持A*、广度优先等算法,适用于Cocos Creator、Laya等游戏引擎

Readme

寻路算法库

CI npm版本 测试覆盖率 许可证

适用于Cocos Creator和Laya引擎的寻路算法库,支持A*和广度优先搜索算法。

✨ 特性

  • 多算法支持:A*、广度优先搜索
  • 引擎兼容:支持Cocos Creator和Laya引擎
  • TypeScript:完整的类型定义
  • 高性能:对象池优化,减少GC压力
  • 稳定可靠:87.39%测试覆盖率,14个测试用例验证
  • 类型安全:严格的TypeScript类型检查

安装

npm install @esengine/pathfinding

算法选择

A*算法

  • 适用场景:大部分游戏寻路需求
  • 特点:支持权重地形,路径质量好
  • 推荐用于:RPG、策略游戏、塔防游戏

广度优先搜索

  • 适用场景:简单网格寻路
  • 特点:保证最短路径(步数最少)
  • 推荐用于:迷宫游戏、推箱子游戏

快速开始

基本使用

import { AStarPathfinder, AstarGridGraph, Vector2Utils } from '@esengine/pathfinding';

// 创建20x20的网格
const graph = new AstarGridGraph(20, 20);

// 添加障碍物
graph.addWall(Vector2Utils.create(10, 10));
graph.addWall(Vector2Utils.create(10, 11));

// 添加难走地形(权重节点)
graph.addWeightedNode(Vector2Utils.create(5, 5));

// 搜索路径
const start = Vector2Utils.create(0, 0);
const goal = Vector2Utils.create(19, 19);

// 方法1:使用图对象的便捷方法
const path = graph.searchPath(start, goal);

// 方法2:使用静态方法(更灵活)
const path2 = AStarPathfinder.searchPath(graph, start, goal);

// 检查路径是否存在(不返回具体路径)
const hasPath = AStarPathfinder.hasPath(graph, start, goal);

console.log('路径:', path);
console.log('路径存在:', hasPath);

广度优先搜索

import { UnweightedGridGraph } from '@esengine/pathfinding';

// 创建网格,支持对角线移动
const graph = new UnweightedGridGraph(10, 10, true);

// 添加障碍物
graph.walls.push({ x: 5, y: 5 });

// 搜索路径
const path = graph.searchPath({ x: 0, y: 0 }, { x: 9, y: 9 });

按需加载

// 只使用A*算法
import { AstarGridGraph } from '@esengine/pathfinding/modules/astar';

// 只使用广度优先算法
import { UnweightedGridGraph } from '@esengine/pathfinding/modules/breadth-first';

在游戏引擎中使用

Cocos Creator

import { AstarGridGraph } from '@esengine/pathfinding';

export default class PathfindingComponent extends cc.Component {
    private graph: AstarGridGraph;
    
    onLoad() {
        this.graph = new AstarGridGraph(50, 50);
        this.setupObstacles();
    }
    
    findPath(start: cc.Vec2, goal: cc.Vec2): cc.Vec2[] {
        return this.graph.searchPath(start, goal) as cc.Vec2[];
    }
    
    private setupObstacles() {
        // 添加地图障碍物
        for (let x = 10; x < 15; x++) {
            this.graph.addWall(cc.v2(x, 10));
        }
    }
}

Laya引擎

import { AstarGridGraph } from '@esengine/pathfinding';

export class PathfindingManager {
    private graph: AstarGridGraph;
    
    constructor(mapWidth: number, mapHeight: number) {
        this.graph = new AstarGridGraph(mapWidth, mapHeight);
    }
    
    findPath(start: Laya.Vector2, goal: Laya.Vector2): Laya.Vector2[] {
        return this.graph.searchPath(start, goal) as Laya.Vector2[];
    }
    
    addObstacle(pos: Laya.Vector2) {
        this.graph.addWall(pos);
    }
}

API文档

AStarPathfinder

A*算法核心实现(静态方法)。

// 搜索完整路径
AStarPathfinder.searchPath<T>(graph: IAstarGraph<T>, start: T, goal: T): T[]

// 检查路径是否存在
AStarPathfinder.hasPath<T>(graph: IAstarGraph<T>, start: T, goal: T): boolean

// 底层搜索方法(返回节点对象)
AStarPathfinder.search<T>(graph: IAstarGraph<T>, start: T, goal: T): {
    found: boolean;
    goalNode?: AStarNode;
    openSetNodes?: AStarNode[];
}

// 对象池管理
AStarPathfinder.clearPool(): void                    // 清理对象池
AStarPathfinder.getPoolStats(): {                    // 获取池统计信息
    poolSize: number;
    maxPoolSize: number;
}

AstarGridGraph

A*算法网格图实现。

const graph = new AstarGridGraph(width: number, height: number);

// 属性
graph.walls: IVector2[]              // 障碍物数组
graph.weightedNodes: IVector2[]      // 加权节点数组
graph.defaultWeight: number          // 默认移动成本(默认1)
graph.weightedNodeWeight: number     // 加权节点成本(默认5)

// 方法
graph.searchPath(start, goal): IVector2[]  // 搜索完整路径(便捷方法)
graph.isNodePassable(node): boolean        // 检查节点是否可通行
graph.isNodeInBounds(node): boolean        // 检查节点是否在边界内
graph.addWall(wall): void                  // 添加单个障碍物
graph.addWalls(walls): void                // 批量添加障碍物
graph.clearWalls(): void                   // 清空障碍物
graph.addWeightedNode(node): void          // 添加加权节点
graph.clearWeightedNodes(): void           // 清空加权节点

// IAstarGraph接口方法
graph.getNeighbors(node): IVector2[]       // 获取邻居节点
graph.cost(from, to): number               // 计算移动成本
graph.heuristic(node, goal): number        // 计算启发式距离

UnweightedGridGraph

广度优先搜索网格图实现。

const graph = new UnweightedGridGraph(
    width: number, 
    height: number, 
    allowDiagonal?: boolean  // 是否允许对角线移动
);

// 属性
graph.walls: IVector2[]  // 障碍物数组

// 方法
graph.searchPath(start, goal): IVector2[]  // 搜索完整路径
graph.hasPath(start, goal): boolean        // 检查是否存在路径

Vector2Utils

向量操作工具类。

Vector2Utils.create(x, y)                    // 创建向量
Vector2Utils.equals(a, b)                    // 判断相等
Vector2Utils.add(a, b)                       // 向量加法
Vector2Utils.manhattanDistance(a, b)         // 曼哈顿距离
Vector2Utils.distance(a, b)                  // 欧几里得距离

游戏场景示例

塔防游戏

import { AStarPathfinder, AstarGridGraph } from '@esengine/pathfinding';

// 敌人寻路到基地
const graph = new AstarGridGraph(mapWidth, mapHeight);
towers.forEach(tower => graph.addWall(tower.position));

// 检查是否有路径(性能更好)
if (AStarPathfinder.hasPath(graph, spawnPoint, basePosition)) {
    const path = AStarPathfinder.searchPath(graph, spawnPoint, basePosition);
    enemy.followPath(path);
}

RPG游戏

import { AStarPathfinder, AstarGridGraph } from '@esengine/pathfinding';

// 角色移动寻路,设置不同地形权重
const graph = new AstarGridGraph(mapWidth, mapHeight);
swampTiles.forEach(tile => graph.addWeightedNode(tile));
graph.weightedNodeWeight = 3; // 沼泽地移动慢

const path = AStarPathfinder.searchPath(graph, playerPos, targetPos);
if (path.length > 0) {
    player.moveTo(path);
}

迷宫游戏

import { UnweightedGridGraph } from '@esengine/pathfinding';

// 简单迷宫寻路
const graph = new UnweightedGridGraph(mazeWidth, mazeHeight);
walls.forEach(wall => graph.walls.push(wall));
const path = graph.searchPath(startPos, exitPos);

性能优化示例

import { AStarPathfinder } from '@esengine/pathfinding';

// 在游戏结束时清理对象池
function onGameEnd() {
    AStarPathfinder.clearPool();
}

// 监控内存使用
function checkMemoryUsage() {
    const stats = AStarPathfinder.getPoolStats();
    console.log(`对象池使用: ${stats.poolSize}/${stats.maxPoolSize}`);

    if (stats.poolSize > stats.maxPoolSize * 0.8) {
        console.warn('对象池使用率较高,考虑优化');
    }
}

文件结构

bin/
├── pathfinding.js          # 完整版本
├── pathfinding.min.js      # 完整版本(压缩)
├── pathfinding.d.ts        # TypeScript类型定义
└── modules/                # 分模块版本
    ├── astar.js           # A*算法模块
    ├── astar.min.js       # A*算法模块(压缩)
    ├── breadth-first.js   # 广度优先模块
    └── breadth-first.min.js # 广度优先模块(压缩)

开发

# 安装依赖
npm install

# 运行测试
npm test

# 测试覆盖率
npm run test:coverage

# 类型检查
npm run type-check

# 代码检查
npm run lint

# 构建
npm run build

# 完整CI检查
npm run ci

质量保证

  • 14个测试用例覆盖主要功能
  • 87.39%代码覆盖率
  • TypeScript严格模式
  • ESLint代码规范
  • CI自动化测试

测试覆盖范围

  • 基础路径查找功能
  • 边界情况处理(起点=终点、超出边界、障碍物上)
  • 错误情况处理(无路径、不可达)
  • 性能和稳定性(大网格、多次搜索)
  • 对象池内存管理
  • 路径质量验证

许可证

MIT License