如何使用cocos2dx-jsbinding 來處理分辨率適配


    首先說點題外話,對於任何大型項目來說,coding的規范重要,在cocos2dx-jsbinding這個框架中,javascript是一個絕對核心的腳本語言,99%的游戲邏輯都由js完成。腳本的編寫量絕對大於大多數的web項目,掌握javascript的扎實的基礎至關重要,這里推薦一篇好的博客,由淺入深的講解從js的一些編寫習慣,到設計模式,值得細細品讀。湯姆大叔的博客:http://www.cnblogs.com/TomXu/archive/2011/12/15/2288411.html

   進入正題,今天討論的是如何使用jsb來處理移動平台的多分辨率適配問題。就目前的移動平台來講,分辨率可謂是百花齊放,且不談安卓平台各種稀奇古怪的分辨率,就ios平台有ip4(960*640),ip5(1136*640),ipad2,mini(1024*768),ipad3,ipad4(2048*1536),這四種當然今后還有更多,如何保證一套代碼,一套資源通吃android和ios平台,同時游戲的布局又不會發生偏差,能夠恰當好處,這是我們追求的目標。cocos2d-x本身提供有幾種屏幕適配API,但是並不是非常完美,並且每種方案都有自己的缺陷,我介紹一下如何用js來處理這個棘手的問題。首先我們要定義實際使用資源的分辨率,也就是美術設計是用的分辨率大小,這里我們將資源定義為960*640,這個分辨率有什么好處?第一是這個分辨率是一個中等類型的分辨率,它比1年前的主流android分辨率800*480)要大,比新出的高端機型分辨率要小一點,同時也是主流的ios分辨率。選資源大小有一個要點,不能選的過高,這樣對低端機型就是浪費,你需要花很大的下載來存這些資源,不值得,但是選太小的也不行,高端機型上又模糊無比,所以選擇一個中等的分辨率。

   分辨率適配的核心思想是縮放,也就是layer.scale函數,但是一定要是等比縮放,如果用layer.scaleX或者layer.scaleY函數,雖然可以把游戲畫面非常簡單的搞成分辨率適配成沒有黑邊,但是整個游戲畫面已經被拉伸或者壓擠,不能達到我們需要的效果。

   游戲中一般有3大類層。

   1.大於屏幕的層,可實現拖動、縮放或者可以隨着角色移動移動場景畫面的,一般這種場景為主城、副本等等。

   2.居中的層,一般是同時基於水平方向和豎直方向居中的,也有基於一個方向居中的。這種一般為ui彈層。

   3.靠邊的層,一般是ui,這些ui分別是緊貼屏幕邊緣。

   以上幾種類型是基本的類型,當然某一個場景可能是上面幾種層類型的組合。比如一個傳統九宮格的戰報場景,人物的排列是基於居中的,ui分布是靠邊的,實現的時候我們將人物和ui分別繪制再2個layer中,每個layer基於相應的類型進行縮放,就可以達到想要的效果。

   下面分別來說明下,三種類型的layer如何做縮放。

   第一種:這種其實最簡單,因為這種層的底圖超過屏幕(一般都超出很多,因為要做移動和多點縮放,或者要隨着角色移動至少一屏),所以只要做一個通用縮放就可以,何謂通用縮放,還是看代碼

       // 獲取屏幕尺寸
        var size = cc.Director.getInstance().getWinSize();
       this.designResolution = cc.size(960,640); 
        // 獲取高寬系數
        var widthRatio = size.width/this.designResolution.width,heightRatio = size.height/this.designResolution.height;
        if (widthRatio !=1 || heightRatio!=1){
            // 按照比例小的系數去進行縮放
            if (widthRatio<heightRatio){
                this._scaleRatio = widthRatio;
            }else{
                this._scaleRatio = heightRatio;
            }
        }else{
            this._scaleRatio = 1;
        }

        this.setScale(this._scaleRatio);

     第二種:在上面通用縮放的基礎上設定層的坐標,使之可以上下左右居中   

        var size = cc.Director.getInstance().getWinSize();
        this.setPosition(cc.p((size.width-this.designResolution.width*this._scaleRatio)/2,(size.height-this.designResolution.height*this._scaleRatio)/2));

    第三種:這種layer是緊靠屏幕邊緣的,所以我們要分別設定他的錨點,我們將整個layer分為9個點,剛好呈現一個“米”字型,其中每個點都需要new一個單獨layer來設定它的錨點。   

this._uiLayerMap = this._uiLayerMap || {};
        if (this._uiLayerMap[directionType]){
            return this._uiLayerMap[directionType];
        }
        var layer = cc.Layer.create();
        layer.setPosition(cc.p(0,0));
        this._uiLayerMap[directionType] = layer;
        // 根據directionType設定錨點位置
        switch (directionType){
            case 1:
                layer.setAnchorPoint(cc.p(0,1));
                break;
            case 2:
                layer.setAnchorPoint(cc.p(0.5,1));
                break;
            case 3:
                layer.setAnchorPoint(cc.p(1,1));
                break;
            case 4:
                layer.setAnchorPoint(cc.p(1,0.5));
                break;
            case 5:
                layer.setAnchorPoint(cc.p(1,0));
                break;
            case 6:
                layer.setAnchorPoint(cc.p(0.5,0));
                break;
            case 7:
                layer.setAnchorPoint(cc.p(0,0));
                break;
            case 8:
                layer.setAnchorPoint(cc.p(0,0.5));
                break;
        }
        this.addChild(layer);

當然,這些層生成完以后還需要做一個通用縮放。使用的時候要注意2點。

1.設定坐標的時候要按照size.width和size.height來計算大小,例如我設定屏幕右下角ui的坐標為

sprite1.setPositon(size.width,50);
sprite2.setPositon(size.width-80,50);
sprite3.setPositon(size.width-160,50);

2.針對每個角的layer需要選擇上面設定相應錨點layer。


免責聲明!

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



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