import { _decorator, Component, Node, Label, Sprite, Button } from 'cc'; import EventBus, { GameEvents } from '../Core/EventBus'; import { JsonConfigLoader } from '../Core/JsonConfigLoader'; import { BundleLoader } from '../Core/BundleLoader'; import { PopUPAni } from '../Animations/PopUPAni'; const { ccclass, property } = _decorator; @ccclass('GainUI') export class GainUI extends Component { @property(Node) panel: Node = null; // 弹窗根节点 @property(Label) titleLabel: Label = null; // 标题,如“新武器” @property(Sprite) iconSprite: Sprite = null; // 武器图标 @property(Label) nameLabel: Label = null; // 武器名称 @property(Node) bt1: Node = null; // Canvas/GainUI/bt1 @property(Node) weaponNode: Node = null; // Canvas/GainUI/Weapon @property(Button) confirmBtn: Button = null; // 确认按钮 private weaponsConfig: any = null; private bundleLoader: BundleLoader = null; // 等待展示的武器名称队列(来自 UpgradeController 派发的 NEW_WEAPONS_UNLOCKED) private pendingWeapons: string[] = []; // 是否已经完成奖励动画(由 MoneyAni 派发 REWARD_ANIMATION_COMPLETED) private rewardAnimationCompleted = false; // 当前是否正在显示弹窗 private showing = false; // 当前正在展示的武器名称(用于避免重复渲染队列首项) private currentWeaponName: string | null = null; // 辅助:获取或添加 PopUPAni 组件 private getOrAddPopAni(node: Node): PopUPAni | null { if (!node) return null; let comp = node.getComponent(PopUPAni); if (!comp) { comp = node.addComponent(PopUPAni); } return comp; } async onLoad() { this.bundleLoader = BundleLoader.getInstance(); // 默认隐藏弹窗 if (this.panel) this.panel.active = false; console.log('[GainUI] 已隐藏弹窗(默认状态)'); // 改为仅监听GameManager派发的显示事件 EventBus.getInstance().on(GameEvents.SHOW_GAIN_UI, this.onShowGainUI, this); // 监听新武器解锁事件,接收武器名称队列 EventBus.getInstance().on(GameEvents.NEW_WEAPONS_UNLOCKED, this.onNewWeaponsUnlocked, this); // 绑定确认按钮 this.confirmBtn?.node.on(Button.EventType.CLICK, this.onConfirm, this); } async start() { console.log('[GainUI] 已初始化,等待新武器解锁事件...'); // 预加载武器配置,便于查找图标与名称 try { this.weaponsConfig = await JsonConfigLoader.getInstance().loadConfig('weapons'); } catch (err) { console.warn('[GainUI] 加载武器配置失败:', err); } } onDestroy() { EventBus.getInstance().off(GameEvents.SHOW_GAIN_UI, this.onShowGainUI, this); EventBus.getInstance().off(GameEvents.NEW_WEAPONS_UNLOCKED, this.onNewWeaponsUnlocked, this); this.confirmBtn?.node.off(Button.EventType.CLICK, this.onConfirm, this); } // 确认按钮逻辑:继续展示队列中的下一个或关闭弹窗 private async onConfirm() { if (this.pendingWeapons.length > 0) { const nextName = this.pendingWeapons.shift(); await this.renderWeapon(nextName); } else { if (this.panel) this.panel.active = false; this.showing = false; this.currentWeaponName = null; EventBus.getInstance().emit(GameEvents.GAIN_UI_CONFIRMED); } } // 接收解锁事件并更新待展示队列 private async onNewWeaponsUnlocked(weaponNames: string[]) { if (!weaponNames || weaponNames.length === 0) return; this.pendingWeapons.push(...weaponNames); console.log('[GainUI] 收到新武器解锁:', weaponNames); // 如果弹窗已显示且当前未渲染任何武器,则渲染第一个 if (this.showing && !this.currentWeaponName && this.pendingWeapons.length > 0) { const first = this.pendingWeapons.shift(); await this.renderWeapon(first); } } // 根据武器名称渲染弹窗内容(标题、图标、名称) private async renderWeapon(weaponName: string) { this.currentWeaponName = weaponName || null; if (this.titleLabel) this.titleLabel.string = '新武器'; if (this.nameLabel) this.nameLabel.string = weaponName || ''; // 查找武器配置,加载图标 const config = this.findWeaponConfigByName(weaponName); if (config && config.visualConfig && config.visualConfig.weaponSprites) { let spritePath: string; const sprites = config.visualConfig.weaponSprites; if (typeof sprites === 'string') { spritePath = sprites; } else { spritePath = sprites['I'] || sprites['H-I'] || sprites['L'] || sprites['S'] || sprites['D-T']; } if (spritePath && this.iconSprite) { await this.loadWeaponSprite(this.iconSprite, spritePath); } } } private findWeaponConfigByName(name: string) { if (!this.weaponsConfig || !this.weaponsConfig.weapons) return null; return this.weaponsConfig.weapons.find((w: any) => w.name === name); } private async loadWeaponSprite(sprite: Sprite, spritePath: string) { const bundlePath = spritePath.replace(/^images\//, ''); try { const spriteFrame = await this.bundleLoader.loadSpriteFrame(bundlePath + '/spriteFrame'); if (spriteFrame && sprite && sprite.isValid) { sprite.spriteFrame = spriteFrame; } } catch (err) { console.warn(`[GainUI] 加载武器图标失败: ${spritePath}`, err); } } // 新增:接收GameManager派发的显示事件,直接显示弹窗 private onShowGainUI = async () => { if (this.panel) { this.panel.active = true; const parent = this.panel.parent; if (parent) { this.panel.setSiblingIndex(parent.children.length - 1); } } this.showing = true; // 新增:显示时让 bt1 与 Weapon 节点弹出显示 try { const promises: Promise[] = []; const bt1Ani = this.getOrAddPopAni(this.bt1); const weaponAni = this.getOrAddPopAni(this.weaponNode); if (bt1Ani) promises.push(bt1Ani.showPanel()); if (weaponAni) promises.push(weaponAni.showPanel()); if (promises.length > 0) { await Promise.all(promises); } } catch (e) { console.warn('[GainUI] 弹出动画执行失败:', e); } // 如果已有待展示武器,立即渲染第一个(并弹出队列) if (this.pendingWeapons.length > 0) { const first = this.pendingWeapons.shift(); await this.renderWeapon(first); } } }