You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
82 lines
2.9 KiB
82 lines
2.9 KiB
|
3 weeks ago
|
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<Vec3>, 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<Record<number, { rows: number; cols: number }>> = {
|
||
|
|
/** 循环圈章节地图(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) };
|
||
|
|
}
|