import { _decorator, director, find, Node, Tween, tween, v3, Vec3 } from 'cc'; import { NodePoolManager } from './NodePoolManager'; import { TipMessagePanel } from '../main/TipMessagePanel'; import { I18nManager } from './I18nManager'; const { ccclass, property } = _decorator; @ccclass('UIManager') export class UIManager { private static _instance: UIManager = null; static get instance() { if (this._instance) { return this._instance; } this._instance = new UIManager(); return this._instance; } private uiLayer: Node = null; setUILayer(uiLayer: Node) { this.uiLayer = uiLayer; } async showPopup( name: string, path: string, bundleName: string, callBack: (prefab: Node) => void ) { let prefab = await NodePoolManager.instance.getNodeFromPoolDynamic(name, path, bundleName); if (!prefab) { console.error(`UIManager 加载${name} prefab失败: ${path}`); return; } this.uiLayer.addChild(prefab); let main = prefab.getChildByName('main'); if (!main) { console.error(`UIManager ${name}prefab 没有main节点,命名不规范: ${path}`); return; } if (callBack) callBack(prefab); } async showPopupDynamic( name: string, path: string, bundleName: string, berforeOpenAnicallBack: (prefab: Node) => void, afterOpenAnicallBack: (prefab: Node) => void, onStartBtnCallback: () => void, onCloseBtnCallback: () => void ) { let prefab = await NodePoolManager.instance.getNodeFromPoolDynamic(name, path, bundleName); if (!prefab) { console.error(`UIManager 加载${name} prefab失败: ${path}`); return; } this.uiLayer.addChild(prefab); let main = prefab.getChildByName('main'); if (!main) { console.error(`UIManager ${name}prefab 没有main节点,命名不规范: ${path}`); return; } let okBtn = main.getChildByName('startBtn'); let closeBtn = main.getChildByName('cancelBtn'); let handleOkBtn = () => { if (onStartBtnCallback) onStartBtnCallback(); NodePoolManager.instance.putNodeToPool(name, prefab); } let handleCloseBtn = () => { if (onCloseBtnCallback) onCloseBtnCallback(); NodePoolManager.instance.putNodeToPool(name, prefab); } let registerEvent = () => { if (okBtn) okBtn.off(Node.EventType.TOUCH_START); if (closeBtn) closeBtn.off(Node.EventType.TOUCH_START); if (okBtn) okBtn.on(Node.EventType.TOUCH_START, handleOkBtn); if (closeBtn) closeBtn.on(Node.EventType.TOUCH_START, handleCloseBtn); } if (berforeOpenAnicallBack) berforeOpenAnicallBack(prefab); main.scale = new Vec3(0.1, 0.1, 0.1); tween(main) .to(0.1, { scale: new Vec3(1, 1, 1) }, { easing: 'quadOut' }) .call(() => { registerEvent(); if (afterOpenAnicallBack) afterOpenAnicallBack(prefab); }) .start(); } sceneAnimation() { let scene = director.getScene(); if (!scene?.isValid) return; let gameNode = find('Canvas/main/game'); if (!gameNode) return; let originalScale = gameNode.scale.clone(); tween(gameNode) // 第一次轻微弹跳 .to(0.08, { scale: v3(1.01, 1.01, 1) }, { easing: 'backOut' }) .to(0.05, { scale: v3(0.995, 0.995, 1) }, { easing: 'quadIn' }) // 第二次更轻微弹跳 .to(0.06, { scale: v3(1.005, 1.005, 1) }, { easing: 'sineOut' }) .to(0.04, { scale: originalScale }, { easing: 'sineIn' }) .start(); } tweenScorelinear(startScore: number, endScore: number, duration: number) { if (endScore == 0) { const controller = { onUpdate: (cb: (v: number) => void) => { _onUpdate = cb; return controller; }, onComplete: (cb: () => void) => { _onComplete = cb; return controller; }, start: () => { if (_onUpdate) _onUpdate(0); if (_onComplete) _onComplete(); return controller; }, holder: { value: 0 }, }; return controller; } let holder = { value: startScore }; let _onUpdate: (v: number) => void = null; let _onComplete: () => void = null; Tween.stopAllByTarget(holder); let tw = tween(holder) .to(duration, { value: endScore }, { easing: 'linear', onUpdate(target, ratio) { let val = target ? target.value : holder.value; if (_onUpdate) _onUpdate(val); }, onComplete(target) { if (_onUpdate) _onUpdate(endScore); if (_onComplete) _onComplete(); } }) let controller = { onUpdate: (cb: (v: number) => void) => { _onUpdate = cb; return controller; }, onComplete: (cb: () => void) => { _onComplete = cb; return controller; }, start: () => { tw.start(); return controller; }, holder: holder, } return controller; } showTipMessagePanel(title: string, msg: string, isCenter: boolean, confirmCb: () => void, closeCb: () => void, confirmStr: string= I18nManager.instance.t("AID_QUIT_LEFT_BUTTON"), cancelStr: string= I18nManager.instance.t("AID_MAIN_OPERATE_CLOSE"),) { let scene = director.getScene(); if (!scene?.isValid) return; let tipMessagePanel = find('Canvas/TipMessagePanel'); if (!tipMessagePanel) return; let tipMessagePanelComp = tipMessagePanel.getComponent(TipMessagePanel); tipMessagePanelComp.setTitle(title); tipMessagePanelComp.setMsg(msg); tipMessagePanelComp.setIsCenter(isCenter); tipMessagePanelComp.setConfirmCallBack(confirmCb); tipMessagePanelComp.setCloseCallBack(closeCb); tipMessagePanelComp.setBtnLabel(isCenter,confirmStr,cancelStr) tipMessagePanelComp.show(); } getHasTip() { let scene = director.getScene(); if (!scene?.isValid) return; let tipMessagePanel = find('Canvas/TipMessagePanel'); if (!tipMessagePanel) return false; let tipMessagePanelComp = tipMessagePanel.getComponent(TipMessagePanel); return tipMessagePanelComp.getHasTip(); } }