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.
 
 
 
 
AdLike2048/assets/script/battle/map/CocosBattleMapHost.ts

109 lines
3.7 KiB

import { _decorator, Component, Node } from 'cc';
import { GBundle } from '../../game/ConfigRes';
import { BattleMapSpec } from '../map/BattleMapSpec';
import { readMapGridSpec } from '../map/MapGridSpecReader';
import type { MapManager } from './legacy/MapManager';
const { ccclass, property } = _decorator;
/**
* 战斗地图宿主:负责加载 mapLayer 预制体并挂到场景
* 逻辑层格子规格见 BattleMapSpec(与 MapManager 字段一致)
*/
@ccclass('CocosBattleMapHost')
export class CocosBattleMapHost extends Component {
@property(Node)
mapRoot: Node | null = null;
private _mapNode: Node | null = null;
private _mapPrefabName = '';
/** 加载关卡 map 字段指定的地图预制体 */
loadMap(mapPrefabName: string): Node | null {
this.unloadMap();
const name = String(mapPrefabName ?? '').trim();
if (!name) {
console.error('[CocosBattleMapHost] 地图预制体名为空');
return null;
}
this._mapPrefabName = name;
const parent = this.mapRoot ?? this.node;
const path = BattleMapSpec.PREFAB_DIR;
if (typeof gg === 'undefined' || !gg.res?.getNode) {
console.log('[CocosBattleMapHost] gg.res not ready');
return null;
}
const mapNode = gg.res.getNode(path, name, GBundle.BattleMap);
if (!mapNode) {
console.error('[CocosBattleMapHost] map prefab not found', name);
return null;
}
mapNode.parent = parent;
this._mapNode = mapNode;
this.validateMapSize(mapNode);
const mapMgr = mapNode.getComponent('MapManager') as MapManager | null;
if (mapMgr) {
// 动态挂载后须等节点世界变换稳定,再采集出怪口/攻击点坐标
mapMgr.scheduleOnce(() => mapMgr.initMapGrids(), 0);
} else {
console.error('[CocosBattleMapHost] MapManager component missing on', name);
}
return mapNode;
}
unloadMap(): void {
if (this._mapNode?.isValid) {
const mapMgr = this._mapNode.getComponent('MapManager') as MapManager | null;
mapMgr?.areaUnlock.clear();
this._mapNode.destroy();
}
this._mapNode = null;
}
get mapNode(): Node | null {
return this._mapNode;
}
/** 当前地图预制体名(Level.map) */
get mapPrefabName(): string {
return this._mapPrefabName;
}
/** @deprecated 请用 mapPrefabName;从 mapLayerN 解析 N,否则为 0 */
get mapId(): number {
const matched = /^mapLayer(\d+)$/i.exec(this._mapPrefabName);
if (!matched) return 0;
const parsed = Number(matched[1]);
return Number.isFinite(parsed) && parsed > 0 ? parsed : 0;
}
/** 校验 MapManager 与战斗 session.grid 一致(session 未创建时跳过) */
private validateMapSize(mapNode: Node): void {
const mapMgr = mapNode.getComponent('MapManager') as MapManager | null;
if (!mapMgr) return;
const prefabSpec = readMapGridSpec(mapMgr);
const session = gg.game.CurentBattle?.session;
if (!session) return;
const g = session.grid;
if (g.rows === prefabSpec.rows && g.cols === prefabSpec.cols && g.cellSize === prefabSpec.cellSize) {
return;
}
console.error(
`[CocosBattleMapHost] ${this._mapPrefabName} 与 session.grid 不一致:`,
`预制体 ${prefabSpec.rows}×${prefabSpec.cols} @ ${prefabSpec.cellSize}px,`,
`session ${g.rows}×${g.cols} @ ${g.cellSize}px`,
'— 请确认进战斗前已从 mapLayer 预制体探测格子规格',
);
}
onDestroy(): void {
this.unloadMap();
}
}