85 lines
3.0 KiB
TypeScript
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)}`;
|
|
}
|
|
}
|
|
}
|