import { _decorator, Color, Component, isValid, Layers, Node, NodeEventType, Sprite, SpriteFrame, Texture2D, tween, Tween, UIOpacity, UITransform, view } from 'cc'; const { ccclass, property } = _decorator; export enum FuncBgType { None, Single,//打开一个 会关闭前一个 Series,//可同时打开多个,会同时关闭 } @ccclass('FuncBg') export class FuncBg extends Component { singleTar: Node = null SeriesTarList: Array = [] /** 添加功能背景,如全屏关闭的遮罩背景 * @param node 目标节点(背景在它之下) * @param func 具体功能 * @param mode 模式,参考 FuncBgType * @param opacity 0 为透明背景 * @param useCapture 有其他上层的点击遮挡时 是否穿透 */ public add(node: Node, func: Function, mode: FuncBgType = 0, opacity = 100, useCapture = false) { let event = () => { if (mode == FuncBgType.Single) this.singleTar = null if (mode == FuncBgType.Series) this.clsoeSeries(node) if (!isValid(bg)) { console.warn("FuncBG is not find"); return; } Tween.stopAllByTarget(bg) func && func() tween(bg.getComponent(UIOpacity)).to(time, { opacity: 0 }).call(_ => { bg.destroy() }).start() console.log("关闭功能背景"); node.off("CLOSEBG") } const time = 0.05 let bg = this.newBg(node) bg.once(NodeEventType.TOUCH_END, event, null, useCapture) tween(bg.getComponent(UIOpacity)).to(time, { opacity: opacity / 255 }).start() node.once("CLOSEBG", () => { event(); }) node.once(NodeEventType.NODE_DESTROYED, () => { // console.warn("BG 销毁"); isValid(bg) && bg.destroy() }) node.once(NodeEventType.ACTIVE_IN_HIERARCHY_CHANGED, () => { // console.warn("BG 隐藏"); isValid(bg) && bg.destroy() }) if (mode == FuncBgType.Single) { this.clsoeLastSingle(node) } else if (mode == FuncBgType.Series) { this.SeriesTarList.push(node) } } newBg(tar: Node): Node { let bg = new Node("FuncBG"); bg.layer = Layers.Enum.DEFAULT; let ui = bg.addComponent(UITransform); let sp = bg.addComponent(Sprite); let op = bg.addComponent(UIOpacity); sp.sizeMode = Sprite.SizeMode.CUSTOM; // 1. 创建纯黑纹理 const texture = new Texture2D(); texture.create(1, 1, Texture2D.PixelFormat.RGBA8888); texture.uploadData(new Uint8Array([0, 0, 0, 255])); // R,G,B,A 全0是纯黑 // 2. 创建SpriteFrame并绑定纹理 const spriteFrame = new SpriteFrame(); spriteFrame.texture = texture; sp.spriteFrame = spriteFrame; sp.color = new Color(0, 0, 0, 255); ui.width = view.getVisibleSize().width; ui.height = 1600//view.getVisibleSize().height; bg.setPosition(ui.width / 2, ui.height / 2) bg.setParent(tar.parent, true) bg.setSiblingIndex(tar.getSiblingIndex()) bg.toOpacity(0) op.opacity = 0 return bg } /**关闭上一个 */ clsoeLastSingle(node) { if (isValid(this.singleTar)) { this.singleTar.emit("CLOSEBG") } this.singleTar = node } /**全部关闭 */ clsoeSeries(node) { let index = this.SeriesTarList.indexOf(node) if (index < 0) return this.SeriesTarList.splice(index, 1) this.SeriesTarList.forEach((tar) => { tar.emit("CLOSEBG") }) } /** 手动关闭功能背景 * @param node 目标节点 */ public close(node: Node) { node.emit("CLOSEBG") } } export const funcBg = new FuncBg()