import { Vec3 } from 'cc'; /** * 地图规格常量(默认 10×8;个别地图可按 mapId 覆盖,须与预制体 MapManager 一致) */ export const BattleMapSpec = { /** 默认总行数(竖向) */ ROWS: 11, /** 默认总列数(横向) */ COLS: 9, /** 单格逻辑像素尺寸 */ CELL_SIZE: 83, /** 地图预制体路径(相对 BattleMap bundle) */ PREFAB_DIR: 'prefab/地图/', /** 预制体命名:mapLayer{mapId} */ prefabName(mapId: number): string { return `mapLayer${mapId}`; }, } as const; /** 怪物节点锚点在脚下:相对格心向下偏移(格),视觉上占满格 */ export const MONSTER_VISUAL_OFFSET_Y_CELLS = 0.45; /** 格心世界坐标 → 脚底偏移后的表现坐标(可选写入 out,避免热路径分配) */ export function applyMonsterFootOffset(cellCenter: Readonly, out?: Vec3, cellSize: number = BattleMapSpec.CELL_SIZE): Vec3 { const y = cellCenter.y - cellSize * MONSTER_VISUAL_OFFSET_Y_CELLS; if (out) { out.set(cellCenter.x, y, cellCenter.z); return out; } return new Vec3(cellCenter.x, y, cellCenter.z); } /** 非默认规格地图:mapId → 行列(cellSize 仍用 BattleMapSpec.CELL_SIZE) */ const MAP_SIZE_BY_ID: Readonly> = { /** 循环圈章节地图(Chapter 10061) */ 10061: { rows: 8, cols: 8 }, /** 环走验证图 */ 999: { rows: 8, cols: 8 }, }; /** 按地图 id 解析行列(仅作预制体未预载时的兜底;正常须 probeMapGridSpecFromPrefab) */ export function resolveMapSizeFallback(mapId: number): { rows: number; cols: number; cellSize: number } { const override = MAP_SIZE_BY_ID[mapId]; return { rows: override?.rows ?? BattleMapSpec.ROWS, cols: override?.cols ?? BattleMapSpec.COLS, cellSize: BattleMapSpec.CELL_SIZE, }; } /** @deprecated 请用 probeMapGridSpecFromPrefab;保留兼容旧调用 */ export function resolveMapSize(mapId: number): { rows: number; cols: number; cellSize: number } { return resolveMapSizeFallback(mapId); } /** * MapGrid 的 Row/Col 与 MX 逻辑格一一对应(同规格,无偏移换算) * @returns 越界返回 null */ export function mapGridToLogicCell( row: number, col: number, logicRows: number, logicCols: number, ): { row: number; col: number } | null { if (row < 0 || row >= logicRows || col < 0 || col >= logicCols) return null; return { row, col }; } /** 逻辑格 → 世界坐标(格子中心,Y 向下) */ export function cellToWorld(row: number, col: number): { x: number; y: number } { const s = BattleMapSpec.CELL_SIZE; return { x: (col + 0.5) * s, y: (row + 0.5) * s }; } /** 世界坐标 → 逻辑格 */ export function worldToCell(x: number, y: number): { row: number; col: number } { const s = BattleMapSpec.CELL_SIZE; return { row: Math.floor(y / s), col: Math.floor(x / s) }; }