| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165 |
- 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<void>[] = [];
- 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);
- }
- }
- }
|