Files
KateLegend2_proj/assets/scripts/scene_entries/LevelEntry.ts
T
2026-05-06 08:17:32 +08:00

85 lines
3.0 KiB
TypeScript

import { _decorator, Component, director, Color, Label, Node } from 'cc';
import { ConfigMgr } from '../data/ConfigMgr';
import { CCJsonLoader } from './CCJsonLoader';
import { LevelMgr } from '../logic/LevelMgr';
import { ensureCanvasSize, createLabel } from './MainMenuEntry';
import { DESIGN_HEIGHT } from '../common/Constants';
const { ccclass, property } = _decorator;
/**
* Generic Level scene entry (task 7.1-7.2 hookup).
*
* Attach to the root node of `Level_1_1` … `Level_1_5`. Configure the
* `levelId` property in the Inspector ("1-1", "1-2", ...).
*
* For MVP the scene has no real gameplay rendering yet; `autoBuildUI`
* simply draws a top-centered label with the current level id so you can
* verify scene transitions by eye.
*/
@ccclass('LevelEntry')
export class LevelEntry extends Component {
@property({ tooltip: '本关的 levelId (与 configs/levels.json 对应),如 1-1 / 1-2 / 1-3 / 1-4 / 1-5' })
public levelId: string = '1-1';
@property({ tooltip: '胜利后跳转的场景,留空则按 1-1 → 1-2 → ... → 1-5 → Boss 自动推导' })
public nextSceneName: string = '';
@property({ tooltip: '是否自动创建关卡 HUD (顶部显示 Level / 倒计时)' })
public autoBuildUI: boolean = true;
private mgr: LevelMgr | undefined;
private hudNode: Node | null = null;
protected async onLoad(): Promise<void> {
if (this.autoBuildUI) this.buildDefaultUI();
const cfg = new ConfigMgr(new CCJsonLoader());
await cfg.load();
this.mgr = new LevelMgr(cfg.level(this.levelId));
}
protected update(dt: number): void {
if (!this.mgr) return;
const status = this.mgr.tick(dt);
this.refreshHud();
if (status === 'victory') {
director.loadScene(this.nextSceneName || this.deriveNextScene());
} else if (status === 'timeout' || status === 'player_dead') {
director.loadScene('Settlement');
}
}
private deriveNextScene(): string {
const map: Record<string, string> = {
'1-1': 'Level_1_2',
'1-2': 'Level_1_3',
'1-3': 'Level_1_4',
'1-4': 'Level_1_5',
'1-5': 'Boss_ShuangHuanFang',
};
return map[this.levelId] ?? 'Settlement';
}
private buildDefaultUI(): void {
ensureCanvasSize(this.node);
createLabel(this.node, `Level ${this.levelId}`, 0, DESIGN_HEIGHT / 2 - 50, 28, Color.WHITE);
this.hudNode = createLabel(
this.node,
'Time: --',
0,
DESIGN_HEIGHT / 2 - 90,
22,
new Color(255, 220, 120, 255),
);
}
private refreshHud(): void {
if (!this.hudNode || !this.mgr) return;
const lb = this.hudNode.getComponent(Label);
if (lb) {
const r = this.mgr.result();
lb.string = `Time: ${Math.max(0, Math.ceil(r.remainingSec))}s Kills: ${Object.values(r.kills).reduce((a, b) => a + b, 0)}`;
}
}
}