cocos creator从零开发简单框架(14)-Panel遮罩

遮罩相关属性

编辑framework/scripts/view/PanelMgr.ts,增加遮罩相关成员变量及初始化方法。

// 所有面板
private static _panels: Map<string, PanelBase> = new Map()

private static _maskName = '_mask'
private static _maskPrefab: cc.Node


public static init() {
    this._panels.clear()

    if (this._maskPrefab && this._maskPrefab.isValid) return

    this._maskPrefab = AppUtil.newSpriteNode(this._maskName)
    this._maskPrefab.color = cc.Color.BLACK
    this._maskPrefab.opacity = 0
}

编辑framework/scripts/App.ts,修改initFramework方法。

// 初始化框架
private static initFramework() {
    LayerMgr.init()

    UIMgr.init(this._uiMain)
    PanelMgr.init()
}

编辑framework/scripts/view/PanelMgr.ts,增加maskStyle方法。

private static maskStyle(go: PanelBase): void {

}

修改show方法,调用this.maskStyle(current)

LayerMgr.setLayer(current.skin, AppConstants.viewLayer.Panel)
this.maskStyle(current)

this._panels.set(viewName, current)

遮罩类型(不能穿透)

编辑framework/scripts/view/PanelMgr.ts,修改maskStyle方法。

const mask = cc.instantiate(this._maskPrefab)
go.skin.addChild(mask, -1) //渲染在 skin 最底层
AppUtil.setWidget(mask, go.skin.parent) //跟 Panel 层级一样大小

if ((go.panelMaskStyle & AppConstants.panelMaskStyle.NoThrough) > 0) {
    mask.addComponent(cc.BlockInputEvents)
}

编辑scripts/PanelYellow.ts,增加panelMaskStyle属性。

public skinPath: string = 'PanelYellow'
public panelMaskStyle: number = AppConstants.panelMaskStyle.NoThrough

运行程序,点击黄面板按钮,弹出来黄面板界面后,除了它自己的关闭按钮能够点击,其它按钮都是不能点击了的。其实这个原理很简单,就是在面板的最下层生成一个透明的跟程序窗口一样大小的节点,再添加cc.BlockInputEvents这个组件,这样就能阻止它下层所有的节点事件了。

遮罩类型(关闭组件)

编辑framework/scripts/view/PanelMgr.ts,修改maskStyle方法。

private static maskStyle(go: PanelBase): void {
    const mask = cc.instantiate(this._maskPrefab)
    go.skin.addChild(mask, -1) //渲染在 skin 最底层
    AppUtil.setWidget(mask, go.skin.parent) //跟 Panel 层级一样大小

    if ((go.panelMaskStyle & AppConstants.panelMaskStyle.NoThrough) > 0) {
        mask.addComponent(cc.BlockInputEvents)
    }
    if ((go.panelMaskStyle & AppConstants.panelMaskStyle.Close) > 0) {
        // 面板如果没设置 NoThrough 属性是不会有 cc.BlockInputEvents 组件的
        if (!mask.getComponent(cc.BlockInputEvents)) {
            mask.addComponent(cc.BlockInputEvents)
        }

        // 点击面板内的ui元素不会关闭面板
        mask.on(cc.Node.EventType.TOUCH_START, (et: cc.Event.EventTouch) => {
            const worldPos = et.getLocation()
            for (const child of go.skin.children) {
                if (child == mask) continue
                if (child.getBoundingBoxToWorld().contains(worldPos)) {
                    return
                }
            }

            this.hide(go.panelName)
        })
    }
}

编辑scripts/PanelYellow.ts,修改panelMaskStyle属性。

public skinPath: string = 'PanelYellow'
public panelMaskStyle: number = AppConstants.panelMaskStyle.Close

运行程序,点击黄面板按钮,弹出来黄面板界面后,如果点击黄色面板上关闭按钮以外的地方,面板没任何反应,但点击黄色面板外的地方,就会关闭黄色面板了。

遮罩类型(半透明)

半透明遮罩跟其它两个不一样,它会在面板显示完成后再出现,在面板关闭时先隐藏。

编辑framework/scripts/view/PanelMgr.ts,增加showPanelBeforeshowPanelAfter2和修改showPanelAfter方法。

private static showPanelBefore(go: PanelBase, isOpen: boolean) {
    // 如果有 半透明 组件,先隐藏组件
    if (!isOpen && (go.panelMaskStyle & AppConstants.panelMaskStyle.Black) > 0) {
        const mask = go.skin.getChildByName(this._maskName)
        mask.opacity = 0
    }
}

private static showPanelAfter(go: PanelBase, isOpen: boolean) {
    // 重置位置(有移动位置的显示方式遮罩位置会错乱)
    const mask = go.skin.getChildByName(this._maskName)
    mask.setPosition(0, 0)

    if (isOpen && (go.panelMaskStyle & AppConstants.panelMaskStyle.Black) > 0) {
        cc.tween(mask).to(0.1, { opacity: 125 }).call(() => this.showPanelAfter2(isOpen)).start()
    } else {
        this.showPanelAfter2(isOpen)
    }
}

private static showPanelAfter2(isOpen: boolean) {
    TopBlock.hide()
}

修改showNormal方法。

private static showNormal(go: PanelBase, isOpen: boolean) {
    this.showPanelBefore(go, isOpen)

    if (isOpen) {
        go.skin.active = true
        go.showed()
    } else {
        this.destroy(go.panelName)
    }

    this.showPanelAfter(go, isOpen)
}

编辑scripts/PanelYellow.ts,修改panelMaskStyle属性。

public skinPath: string = 'PanelYellow'
public panelMaskStyle: number = AppConstants.panelMaskStyle.Black

运行程序,点击黄面板按钮,可以发现黄面板出现后后面会有一层黑色半透明遮罩了。

遮罩组合

遮罩类型不仅可以单独设置,还可以以组合的方式设置。

编辑scripts/PanelYellow.ts,修改panelMaskStyle属性。

public skinPath: string = 'PanelYellow'
public panelMaskStyle: number = AppConstants.panelMaskStyle.Close | AppConstants.panelMaskStyle.Black //关闭组件(点击面板区域外会关闭面板)加半透明组件

运行程序,点击黄面板按钮,发现面板既有半透明又能点击面板区域外关闭面板了。

本作品采用《CC 协议》,转载必须注明作者和本文链接
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!