Cocos Creator之彈窗管理
我們已經(jīng)知道怎樣制作、加載、顯示界面。但cocos沒有提供一個(gè)彈窗管理模塊,對(duì)于一個(gè)多人合作的項(xiàng)目,沒有統(tǒng)一的管理,界面層級(jí)容易混亂。作為主程,在項(xiàng)目開始就應(yīng)該處理好這些問題,將彈窗劃分為不同的層次,不同類型的信息顯示在不同的層中。下面將講解怎樣設(shè)計(jì)彈窗堆棧。
一般地,從下向上,我會(huì)將彈窗劃分為以下層:
1)內(nèi)容層,展示游戲相關(guān)的信息界面。
2)tips層,顯示提示性信息界面,例如獲得物品的浮窗、網(wǎng)絡(luò)異常的提示。
3)新手引導(dǎo)層,主要顯示新手引導(dǎo)的手指、新手提示文本框等。
4)alert層,主要顯示系統(tǒng)級(jí)的信息、錯(cuò)誤,例如斷網(wǎng)、被踢下線。
5)loading層,顯示加載動(dòng)畫。

具體怎樣實(shí)現(xiàn)?彈窗通常有統(tǒng)一的動(dòng)畫,所以定義一個(gè)界面邏輯的基類ViewCtrl,定義一些通用的屬性和方法。每個(gè)層中可能同時(shí)存在多個(gè)界面,我把每個(gè)層做成組ViewGroup。再寫一個(gè)類PopupCtrl,對(duì)界面分層,并對(duì)外提供編程接口。
先來說說ViewCtrl這個(gè)類,繼承自cc.Component,這樣我們寫的ViewCtrl子類就可以掛載到prefab的節(jié)點(diǎn)上。定義兩個(gè)boolean屬性:hasMask、touchOutClose,用于控制是否有灰色半透明遮罩,和是否點(diǎn)擊彈窗外關(guān)閉。后面在介紹ViewGroup時(shí)會(huì)介紹怎樣實(shí)現(xiàn)這兩個(gè)功能。
cc.Component本身有onEnable,onDisable兩個(gè)生命周期方法,但我們希望同屏不出現(xiàn)太多彈窗,彈出新彈窗時(shí)隱藏上一個(gè)彈窗,這會(huì)導(dǎo)致這兩個(gè)方法頻繁調(diào)用。對(duì)于打開界面時(shí)的刷新,在界面放到堆棧時(shí)回調(diào)更合適。同理對(duì)重用的界面的重置,在界面移出堆棧時(shí)回調(diào)重置??梢栽赩iewCtrl定義onAddToStack和onRemoveFromStack兩個(gè)生命周期方法,在ViewGroup里在合適的時(shí)機(jī)觸發(fā),后面會(huì)介紹。再添加兩個(gè)方法,onPlayShowAni,onPlayHideAni,在這里可以實(shí)現(xiàn)統(tǒng)一的彈窗動(dòng)畫。子類的特殊顯示和關(guān)閉動(dòng)畫由子類重寫這兩個(gè)方法實(shí)現(xiàn)。這兩個(gè)方法也由ViewGroup在合適的時(shí)機(jī)觸發(fā)。
/** * auth: 關(guān)健昌 * date: 2018-11-17 * desc: 界面基類 * modify: */ const {ccclass, property} = cc._decorator; @ccclass export default class ViewCtrl extends cc.Component { @property hasMask: boolean = true; @property touchOutClose: boolean = false; public onAddToStack(): void { } public onRemoveFromStack(): void { } public onPlayShowAni(): void { } public onPlayHideAni(): void { } }
接下來是ViewGroup這個(gè)類,它代表一個(gè)彈窗層,也繼承自cc.Component,它的node可以添加到PopupCtrl的node上從而展示這個(gè)彈窗層。它應(yīng)該有自己的maskLayer、blockLayer,用于顯示灰色半透明遮罩,和屏蔽下層界面的觸屏事件。當(dāng)然,像tips層,我們不希望屏蔽下層界面的觸屏事件,可以提供接口來控制這兩個(gè)layer是否生效。
ViewGroup最重要的作用是管理一層的彈窗。所以它應(yīng)該有一個(gè)Array<ViewCtrl>類型的viewArr屬性?;镜牟僮靼?
/** * auth: 關(guān)健昌 * date: 2018-11-17 * desc: 界面組 * modify: */ export default class ViewGroup extends cc.Component { private maskLayer: cc.Node = null; private blockLayer: cc.Node = null; private viewArr: Array<ViewCtrl> = []; public pushView(ctrl: ViewCtrl, hideOld: boolean): void { } public popView(cleanup: boolean): void { } public insertView(ctrl: ViewCtrl): void { } public removeView(ctrl: ViewCtrl): void { } public pushViews(ctrls: Array<ViewCtrl>, hideOld: boolean): void { } public removeAllViews(cleanup: boolean): void { } public lastView(): ViewCtrl { } public getViewByName(name: string): ViewCtrl { } public getViewCount(): number { } public isEmpty(): boolean { } }
其中pushView、insertView、pushViews會(huì)將對(duì)應(yīng)ViewCtrl放入viewArr,并觸發(fā)ViewCtrl.onAddToStack。通過ViewGroup.node.addChild將ViewCtrl.node添加為子節(jié)點(diǎn)將對(duì)應(yīng)界面顯示出來。具體是否要添加到界面要看是否在hideOld的界面下面。pushViews主要是為自動(dòng)彈窗設(shè)計(jì)的,例如登錄后自動(dòng)顯示公告、簽到等,關(guān)閉一個(gè)自動(dòng)打開下一個(gè)。
popView、removeView、removeAllViews通過ViewCtrl.node.removeFromParent將ViewCtrl.node移出界面,同時(shí)將ViewCtrl移出viewArr,并觸發(fā)ViewCtrl.onRemoveFromStack。pushView、popView還會(huì)觸發(fā)onPlayShowAni,onPlayHideAni這兩個(gè)生命周期方法。
現(xiàn)在來說說PopupCtrl這個(gè)類,它也繼承自cc.Component,可以直接掛載到prefab的節(jié)點(diǎn)上,在介紹游戲入口時(shí)我們給Canvas添加了popupLayer子節(jié)點(diǎn),通過添加組件將PopupCtrl掛上去。PopupCtrl要實(shí)現(xiàn)分層,它有Array<ViewGroup>類型的groupArr屬性。在onLoaded生命周期方法里按彈窗層順序,通過PopupCtrl.addChild添加對(duì)應(yīng)的彈窗層。PopupCtrl提供跟ViewGroup類似的接口,不同的是PopupCtrl的pushView、insertView、pushViews提供layer參數(shù),用于指定彈窗添加的層。
enum PopupLayer { CONTENT = 0, TIPS, GUIDE, ALERT, LOADING }
彈窗管理先說到這里。
更多資源請(qǐng)點(diǎn)擊:https://bycwedu.vipwan.cn/promotion_channels/630597732