麒麟子Cocos Creator實用技巧九:棋牌UI全分辨率適配方案


麒麟子在五一勞動節這一天,爲大家準備了一個DEMO。 DEMO演示了,大廳,背景,以及像 3D麻將,鬥地主等桌面的適配方案。使大家可以用一套資源,適配從iPhoneX(目前最長的移動設備) 到 iPad(目前最短的移動設備 )的分辨率。

PS:黑莓那種1:1也可以的,只是我人爲的把它忽略了。

本DEMO在線演示: https://qilinzi.ukylin.net/?lesson=09

本DEMO源代碼:https://gitee.com/qilinzi/qlz_ccc_tips


不謀萬世者,不足謀一時。不謀全局者,不足謀一域。

麒麟子對這句話的理解就是,早睡早起,好好學習,天天向上。哈哈哈哈。正文開始之前,先瞎**幾句,是麒麟子的風格,大家久了就習慣了。如果不想看的,直接到正文即可。 這段的主要目的,是想緩解一下大家的壓力。畢竟大部分看這個文章的朋友,都在996,或者在去996的路上。

麒麟子不只一次說過,不要總是學人有跟熱點,不要總幻想自己是站在風口的豬。即便你飛起來了,那萬一風突然停了呢。選擇一個自己看好的領域進行深耕,不斷積累。

而選擇什麼領域,技術只是基礎。用戶需求是否可持續,纔是你能否持續深耕的關鍵。

麒麟子有云:棋牌之路漫漫其修遠兮,吾將上下而求索(翻譯:棋牌領域是棵常青樹,是一個可以深耕的領域)

後面的文章,大部分是基於棋牌來講解知識點,但對於其他遊戲也同樣適用


一、不同適配策略的表現效果

Cocos Creator的Canvas提供了fitWidth和fitHeight兩個開關,可以實現4種效果

1、fitWidth = false, fitHeight = false

    對應的是自動選擇定寬還是定高,當用戶手機比設計分辨率更寬時,使用定寬。 當用戶手機比設計分辨率更短時,使用定高。 帶來的就是裁剪效果

2、fitWidth = true, fitHeight = false

    對應的是定寬效果

3、fitHeight = false,fitHeight = true

對應的是定高效果

4、fitWidth = true,fitHeight = true

對應的是show_all效果

在設計分辨率不變的情況下,不同的適配策略,在不同的設備上的表現效果,如下圖

二、幼麟棋牌的適配模式

1、適配效果介紹

棋牌遊戲,卡牌遊戲等項目的適配,比RPG要難一點。特別是牌桌和全屏界面。對於RPG來說,只需要做靠主界面的停靠即可。而棋牌遊戲,桌子本來空間就不足,簡單的停靠是滿足不了需求的。幼麟棋牌團隊在經歷了十幾個項目之後總結出一條鐵律:不允許任意分辨率對內容裁剪。這條鐵律沿用至今,暫時沒有發現滿足不了的情況。

看到上面黑字的時候,我們肯定第一時間想到全顯的適配策略。 

心細的朋友應該能夠發現,全顯和幼麟棋牌,都是保證內容能夠全部顯示。但爲什麼麒麟子在畫圖的時候,要把全顯的背景弄成黑色呢。 你沒看錯,這不是麒麟子腦袋抽風,這是因爲,二者有區別。

有興趣的朋友可以拿ShowAll和幼麟棋牌的適配方案做一個測試,你會發現,核心差異就在Widget是否能夠正確停靠的問題。 使用ShowAll方案,Widget會按綠色邊緣作爲停靠。 而使用幼麟棋牌方案,Widget會使用屏幕寬高作爲停靠。

2、全分辨率適配代碼實現

這裏要注意,CocosCreator場景中,一定要去掉 fitWidth和fitHeight。 一個都不能留,否則是有問題的。下面的代碼是從Demo代碼中的Utils.ts文件中截取的。

    public static resize() {
        
        var cvs = cc.find('Canvas').getComponent(cc.Canvas);
        //保存原始設計分辨率,供屏幕大小變化時使用
        if(!this.curDR){
            this.curDR = cvs.designResolution;
        }
        var dr = this.curDR;
        var s = cc.view.getFrameSize();
        var rw = s.width;
        var rh = s.height;
        var finalW = rw;
        var finalH = rh;

        if((rw/rh) > (dr.width / dr.height)){
            //!#zh: 是否優先將設計分辨率高度撐滿視圖高度。 */
            //cvs.fitHeight = true;
            
            //如果更長,則用定高
            finalH = dr.height;
            finalW = finalH * rw/rh;
        }
        else{
            /*!#zh: 是否優先將設計分辨率寬度撐滿視圖寬度。 */
            //cvs.fitWidth = true;
            //如果更短,則用定寬
            finalW = dr.width;
            finalH = rh/rw * finalW;
        }
        cvs.designResolution = cc.size(finalW, finalH);
        cvs.node.width = finalW;
        cvs.node.height = finalH;
        cvs.node.emit('resize');
    }

麒麟子保證,用上面的代碼,配上fitWidth = false, fitHeight = false. 你將再也不用因爲分辨率適配而掉頭髮 (因爲劉海屏適配掉的頭髮不算在這個裏面)

不要太浪哦!!!!

三、背景適配

按理說,我們弄一張足夠大的背景,總是能撐滿所有分辨率的。但這樣一來,美術的設計成本就高了。 特別是不能複用一些現成(別人)的資源。

麒麟子弄了一個bg_scaler.ts來滿足大家,大家可以通過點擊大廳的 居中,自由縮放,裁剪 來觀察不同的效果。

關鍵代碼如下:

resize () {

        this.node.width = this.originWidth;
        this.node.height = this.originHeight;

        //0、居中(居中其實不需要掛這個腳本,浪費效率)
        //1、寬高都根據高度拉伸
        //2、長邊充滿
        var cvs = cc.find('Canvas').getComponent(cc.Canvas);
        var size = cc.view.getFrameSize();
        
        var dr = Utils.curDR;
        var scaleMethod = this.mode;

        //
        var fitWidth = true;
        //如果更寬,則使用定高
        if((size.width/size.height) > (dr.width / dr.height)){
            fitWidth = false;
        }

        //自由縮放撐滿
        if(scaleMethod == 1){
            if(fitWidth){
                this.node.height = this.node.width/size.width * size.height;
            }
            else{
                this.node.width = this.node.height/size.height * size.width;
            }
        }
        //保持等比縮放撐滿
        else if(scaleMethod == 2){
            if(fitWidth){
                //定寬表示設備更高了,則以高的縮放爲準
                var oldHeight = this.node.height;
                this.node.height = this.node.width/size.width * size.height;
                var scale = this.node.height/oldHeight;
                this.node.width = scale * this.node.width;
            }
            else{
                //定高表示設備更寬的,以寬的縮放爲準
                var oldWidth = this.node.width;
                this.node.width = this.node.height/size.height * size.width;
                var scale = this.node.width / oldWidth;
                this.node.height = scale * this.node.height;
            }
        }
        else{
            //默認處理,有黑邊
        }
    }

四、麻將桌子適配

麒麟子的DEMO裏面,處理了一個假3D的麻將桌子。因爲這個比較特殊,所以放在這裏作爲了案例。此代碼在DEMO代碼的 09_3dmjtable.ts文件中。它實現的效果是,如果屏幕比設計分辨率高,比如 iPad這樣的設備,那麼將會多顯示出一些牆壁上的內容。如果比設計分辨率更長,比如iPhoneX,那麼將會做一定的拉伸,確保背景充滿。

    start () {
        cc.find('Canvas').on('resize',this.resize.bind(this));
        this.resize();
    }

    resize(){
        var canvas = cc.find('Canvas');
        if(canvas.width > Utils.curDR.width){
            this.node.width = canvas.width;
        }
    }

五、鬥地主桌子適配

半弧的桌子適配是最容易的,只需要一個Widget無腦充滿即可

六、總結

本文章和DEMO只是演示了一些基本的適配技巧。 每一個項目,面對的需求都大相徑庭,沒有哪一個方案是可以一勞永逸的,需要大家根據自身項目的情況,酌情調整。

本DEMO在線演示: https://qilinzi.ukylin.net/?lesson=09

本DEMO源代碼:https://gitee.com/qilinzi/qlz_ccc_tips

發佈了233 篇原創文章 · 獲贊 546 · 訪問量 119萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章