Files
Alien_Sniper/assets/scripts/framework/ui/PanelBase.ts
T
2026-07-14 11:44:07 +08:00

74 lines
2.1 KiB
TypeScript

import { _decorator, Component, Node, director, resources, instantiate, Prefab, js } from 'cc';
const { ccclass, property } = _decorator;
@ccclass('PanelBase')
export class PanelBase extends Component {
protected isOpen: boolean = false;
public async open(): Promise<void> {
if (this.isOpen) return;
this.node.active = true
this.isOpen = true;
this.onOpen();
}
static async LoadPanel(prefabPath: string, parentNode: Node) {
let panelNode: Node = null
resources.load(prefabPath, Prefab, (err, prefabAsset) => {
if (prefabAsset) {
const node = instantiate(prefabAsset);
node.parent = parentNode;
node.getComponent(PanelBase).open()
panelNode = node
} else {
console.error(`Failed to load UI prefab: ${prefabPath}`);
}
});
await this.waitUntil(() => panelNode != null);
return panelNode
}
static waitUntil(condition: () => boolean): Promise<void> {
return new Promise((resolve) => {
const checkCondition = () => {
if (condition()) {
resolve(); // 条件成立,结束等待
} else {
// 条件不成立,继续轮询
requestAnimationFrame(checkCondition);
}
};
checkCondition(); // 开始检查条件
});
}
public close(): void {
console.log("close panel", this.node.name)
if (!this.isOpen) return;
if (!this.isValid) return;
if (this.node && this.node.parent) {
this.node.removeFromParent();
this.node.destroy();
this.isOpen = false;
this.onClose();
}
}
protected getPrefabPath(): string {
let panelName = js.getClassName(this)
return `ui/${panelName}`; // 生成预制件路径
}
protected onOpen(): void {
// 子类可以重写此方法以执行打开后的操作
}
protected onClose(): void {
// 子类可以重写此方法以执行关闭后的操作
}
}