cocos creator主程入門教程(二)—— 彈窗管理


五邑隱俠,本名關健昌,10年游戲生涯,現隱居五邑。本系列文章以TypeScript為介紹語言。

 

我們已經知道怎樣制作、加載、顯示界面。但cocos沒有提供一個彈窗管理模塊,對於一個多人合作的項目,沒有統一的管理,界面層級容易混亂。作為主程,在項目開始就應該處理好這些問題,將彈窗划分為不同的層次,不同類型的信息顯示在不同的層中。下面將講解怎樣設計彈窗堆棧。

一般地,從下向上,我會將彈窗划分為以下層:

1)內容層,展示游戲相關的信息界面。

2tips層,顯示提示性信息界面,例如獲得物品的浮窗、網絡異常的提示。

3)新手引導層,主要顯示新手引導的手指、新手提示文本框等。

4alert層,主要顯示系統級的信息、錯誤,例如斷網、被踢下線。

5loading層,顯示加載動畫。

具體怎樣實現?彈窗通常有統一的動畫,所以定義一個界面邏輯的基類ViewCtrl,定義一些通用的屬性和方法。每個層中可能同時存在多個界面,我把每個層做成組ViewGroup。再寫一個類PopupCtrl,對界面分層,並對外提供編程接口。

先來說說ViewCtrl這個類,繼承自cc.Component,這樣我們寫的ViewCtrl子類就可以掛載到prefab的節點上。定義兩個boolean屬性:hasMasktouchOutClose,用於控制是否有灰色半透明遮罩,和是否點擊彈窗外關閉。后面在介紹ViewGroup時會介紹怎樣實現這兩個功能。

cc.Component本身有onEnableonDisable兩個生命周期方法,但我們希望同屏不出現太多彈窗,彈出新彈窗時隱藏上一個彈窗,這會導致這兩個方法頻繁調用。對於打開界面時的刷新,在界面放到堆棧時回調更合適。同理對重用的界面的重置,在界面移出堆棧時回調重置。可以在ViewCtrl定義onAddToStackonRemoveFromStack兩個生命周期方法,在ViewGroup里在合適的時機觸發,后面會介紹。再添加兩個方法,onPlayShowAnionPlayHideAni,在這里可以實現統一的彈窗動畫。子類的特殊顯示和關閉動畫由子類重寫這兩個方法實現。這兩個方法也由ViewGroup在合適的時機觸發。

 

/**
 * auth: 關健昌
 * 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這個類,它代表一個彈窗層,也繼承自cc.Component,它的node可以添加到PopupCtrlnode上從而展示這個彈窗層。它應該有自己的maskLayerblockLayer,用於顯示灰色半透明遮罩,和屏蔽下層界面的觸屏事件。當然,像tips層,我們不希望屏蔽下層界面的觸屏事件,可以提供接口來控制這兩個layer是否生效。

ViewGroup最重要的作用是管理一層的彈窗。所以它應該有一個Array<ViewCtrl>類型的viewArr屬性。基本的操作包括:

/**
 * auth: 關健昌
 * 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 {
     }
}

 

其中pushViewinsertView、pushViews會將對應ViewCtrl放入viewArr,並觸發ViewCtrl.onAddToStack。通過ViewGroup.node.addChildViewCtrl.node添加為子節點將對應界面顯示出來。具體是否要添加到界面要看是否在hideOld的界面下面。pushViews主要是為自動彈窗設計的,例如登錄后自動顯示公告、簽到等,關閉一個自動打開下一個。

popViewremoveView、removeAllViews通過ViewCtrl.node.removeFromParentViewCtrl.node移出界面,同時將ViewCtrl移出viewArr,並觸發ViewCtrl.onRemoveFromStackpushViewpopView還會觸發onPlayShowAnionPlayHideAni這兩個生命周期方法。

現在來說說PopupCtrl這個類,它也繼承自cc.Component,可以直接掛載到prefab的節點上,在介紹游戲入口時我們給Canvas添加了popupLayer子節點,通過添加組件將PopupCtrl掛上去。PopupCtrl要實現分層,它有Array<ViewGroup>類型的groupArr屬性。在onLoaded生命周期方法里按彈窗層順序,通過PopupCtrl.addChild添加對應的彈窗層。PopupCtrl提供跟ViewGroup類似的接口,不同的是PopupCtrlpushViewinsertView、pushViews提供layer參數,用於指定彈窗添加的層。

 

enum PopupLayer {
    CONTENT = 0,
    TIPS,
    GUIDE,
    ALERT,
    LOADING
}

 

彈窗管理先說到這里,下一篇我們將介紹下怎樣做資源加載管理。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM