import { Vec3 } from 'cc'; import { CELL_PIXEL } from './GridConstants'; /** * 与 Unity Grid 一致:CellLayout Isometric Z-as-Y,CellSize (1, 0.5, 1)。 * 缩放后 halfW=CELL/2, halfH=CELL/4。 */ const HALF_W = CELL_PIXEL * 0.5; const HALF_H = CELL_PIXEL * 0.25; if (!Number.isFinite(HALF_W) || HALF_W <= 0) { console.error('[GridCoords] CELL_PIXEL 无效,请检查 GridConstants 模块加载'); } export function cellToWorld(cell: Vec3): Vec3 { const x = cell.x; const y = cell.y; return new Vec3((x - y) * HALF_W, (x + y) * HALF_H, 0); } /** Unity Tilemap tileAnchor (0.5,0.5):精灵 pivot 对齐格子中心 */ export function cellToWorldCenter(cell: Vec3): Vec3 { const w = cellToWorld(cell); return new Vec3(w.x, w.y + HALF_H, 0); } export function worldToCell(world: Vec3): Vec3 { const cx = (world.y / HALF_H + world.x / HALF_W) * 0.5; const cy = (world.y / HALF_H - world.x / HALF_W) * 0.5; return new Vec3(Math.round(cx), Math.round(cy), 0); } /** 输入为世界坐标下的格子中心(与 Tilemap tileAnchor 一致) */ export function worldCenterToCell(world: Vec3): Vec3 { return worldToCell(new Vec3(world.x, world.y - HALF_H, world.z)); } /** 世界坐标吸附到最近格子中心 */ export function snapWorldToCellCenter(world: Vec3, out?: Vec3): Vec3 { const cell = worldToCell(world); const snapped = cellToWorld(cell); if (out) { out.set(snapped); return out; } return snapped; } export function formatCellKey(x: number, y: number): string { return `${x},${y}`; } export function parseCellKey(key: string): { x: number; y: number } | null { const parts = key.split(','); if (parts.length !== 2) return null; const x = parseInt(parts[0], 10); const y = parseInt(parts[1], 10); if (Number.isNaN(x) || Number.isNaN(y)) return null; return { x, y }; } /** 烘焙瓦片节点名 g_1_0 / b_-2_1 → 格子坐标 */ export function parseTileNodeName(name: string | undefined | null): { layer: 'ground' | 'border'; x: number; y: number } | null { if (!name) return null; const m = name.match(/^([gb])_(-?\d+)_(-?\d+)$/); if (!m) return null; return { layer: m[1] === 'g' ? 'ground' : 'border', x: parseInt(m[2], 10), y: parseInt(m[3], 10), }; } export function tileNodeName(layer: 'ground' | 'border', x: number, y: number): string { const p = layer === 'ground' ? 'g' : 'b'; return `${p}_${x}_${y}`; } export function getHalfCellSize(): { halfW: number; halfH: number } { return { halfW: HALF_W, halfH: HALF_H }; } /** 等距绘制深度(连续值,移动插值用;与 compareIsoDrawOrder 配套) */ export function isoDrawDepthFromWorld(world: Vec3): { x: number; y: number } { const cx = (world.y / HALF_H + world.x / HALF_W) * 0.5; const cy = (world.y / HALF_H - world.x / HALF_W) * 0.5; return { x: cx, y: cy }; }