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 🙏

© 2026 – Pkg Stats / Ryan Hefner

@ccgf/tilemap

v0.1.0

Published

网格 / 等距 / 六边形地图拓扑:坐标、邻居、距离、直线、圆环、投影(纯计算,不依赖引擎与框架)

Readme

@ccgf/tilemap

状态(2026-10-23):基础算法已完成;地图数据格式、关卡包、渲染、编辑器整体暂缓。 恢复前先读 docs/map-todo.md,不要在这里继续加产品级功能。

地图网格的纯算法库:方格 / 真等距(菱形)/ 六边形。

  • 零 cc、零 framework 依赖 —— Node 里能直接单测,也能给工具/服务端复用
  • 只算拓扑、坐标、邻居、距离、直线、圆环、投影;不碰渲染、节点、资源、可走性
  • 坐标用普通数字 / {x,y} / {q,r},不持有全局状态
import { SquareGrid, IsoProjection, HexGrid } from '@ccgf/tilemap';

方格

const grid = new SquareGrid(20, 20);
const i = grid.index(5, 5);           // y * width + x
const nb4 = grid.neighbors(i);        // 4 邻居
const nb8 = grid.neighbors(i, [], true); // 8 邻居
const area = grid.range(i, 2);        // 曼哈顿范围
const line = grid.line(i, grid.index(10, 10));

约定:(0,0) 在左下角,x 向右、y 向上(第一象限);索引仍是 index = y*width + x,只是第 0 行在最下面。本类不判断可走性。

真等距(菱形)

菱形地图的逻辑拓扑就是方格,只是投影不同 —— 所以寻路/范围直接复用 SquareGrid。

const iso = new IsoProjection({ tileWidth: 64, tileHeight: 32 });
const p = iso.toWorld(3, 5);          // 格子中心(Cocos Y 向上)
const cell = iso.pick(p.x, p.y);      // 点选,返回整数格
const idx = iso.pickIndex(grid, p.x, p.y); // 图内返回索引,图外 null
const depth = iso.sortKey(3, 5);      // -(x+y),升序 = 先画后排、再画前排

公式(origin 是 (0,0) 格心的世界坐标):

worldX = originX + (x - y) * tileWidth  / 2
worldY = originY + (x + y) * tileHeight / 2

(0,0) 在左下角;x 向右上、y 向左上;Y 向上为正。pick 不是对连续坐标 floor:每格是菱形,边界附近必须用菱形判定,库已经处理。

六边形

const hex = new HexGrid({
    cols: 20,
    rows: 20,
    size: 32,              // 外接圆半径(中心到顶点)
    orientation: 'flat',   // 平顶
    offset: 'odd-q',       // 平顶标准:按列错半格
});

const i = hex.index(5, 5);
const nb = hex.neighbors(i);              // 6 个
const ring = hex.ring(i, 2);
const range = hex.range(i, 2);
const line = hex.line(i, hex.index(10, 8));
const world = hex.toWorld(i);
const picked = hex.fromWorld(world.x, world.y); // 图外 null
const corners = hex.corners(i);                // 6 个顶点,画高亮用

坐标同样是左下原点:index = row * cols + col,row 向上增大(第 0 行在最下面)。

平顶 vs 尖顶,以及“行错行”

  • flat(平顶):左右是尖角,上下是平边;标准错位是按列(odd-q / even-q)。
  • pointy(尖顶):上下是尖角;标准错位是按行(odd-r / even-r)。

四种 offset 都已实现、可以互转,但要注意:

  • “每行水平排列、奇数行错半格”的视觉,标准做法是 pointy + odd-r;
  • 平顶六边形的邻居方向是 N / S + 四个斜向,没有正 E / W 邻居,所以它天然是“按列错位”。 如果你把平顶地图按 row 索引(odd-r),数学上仍然正确(row 只是存储坐标), 但那一行并不对应屏幕上的水平行。

内部一律用 axial (q, r) 做邻居/距离/直线/圆环;col/row 只用于矩形存储。 三种坐标都支持:

const a = hex.toAxial(col, row);      // offset -> axial
const o = hex.toOffset(q, r);         // axial  -> offset
const cube = hex.cubeOf(index);       // (x, y, z), x + y + z = 0

边界

  • 不做可走性/权重:可走性数据由使用方存(Uint8Array 就行)。

  • 寻路用 @ccgf/pathfinding 的 findPathOnGraph;HexGrid 自带 neighbors + heuristic, 结构上就是一张图:

    import { findPathOnGraph } from '@ccgf/pathfinding';
    findPathOnGraph(hex, start, goal);   // 无阻挡
    // 有阻挡:包一层 isBlocked
    findPathOnGraph({
        neighbors: (i, out) => hex.neighbors(i, out),
        contains: (i) => hex.contains(i),
        heuristic: (a, b) => hex.distance(a, b),
        isBlocked: (i) => blocked[i] === 1,
    }, start, goal);
  • 不做地图数据格式、渲染、相机、节点坐标转换。

  • 不持有任何全局状态。