閱讀643 返回首頁    go 阿裏雲 go 技術社區[雲棲]


cocos2d-x多分辨率適配方案:setDesignResolutionSize(完美)

cocos2d-x是一個優秀的跨平台遊戲引擎,當然跨平台超容易遇到的分辨率適配問題,cocos2d-x也提供了超好用的解決方案。

官方的多分辨率適配wiki頁麵在這裏:https://www.cocos2d-x.org/projects/cocos2d-x/wiki/Multi_resolution_support

當然這是E文的教程,而且有些細節官方也沒有說清楚,下麵就開始我自己的一些見解了。

====本教程基於cocos2d-x-2.1.4撰寫====

1. setDesignResolutionSize使用方法及主要的三種適配模式

在cocos2d-x 2.0裏,提供了一個叫做setDesignResolutionSize的方法,直接一次設置就可以自動適配各種分辨率。這個方法的注釋如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
enum ResolutionPolicy
{
    kResolutionExactFit,
    kResolutionNoBorder,
    kResolutionShowAll,
    kResolutionFixedHeight,
    kResolutionFixedWidth,
    kResolutionUnKnown,
};
 
/**
* Set the design resolution size.
* @param width Design resolution width.
* @param height Design resolution height.
* @param resolutionPolicy The resolution policy desired, you may choose:
*                         [1] kResolutionExactFit Fill screen by stretch-to-fit: if the design resolution ratio of width to height is different from the screen resolution ratio, your game view will be stretched.
*                         [2] kResolutionNoBorder Full screen without black border: if the design resolution ratio of width to height is different from the screen resolution ratio, two areas of your game view will be cut.
*                         [3] kResolutionShowAll  Full screen with black border: if the design resolution ratio of width to height is different from the screen resolution ratio, two black borders will be shown.
*/
virtual void setDesignResolutionSize(float width, float height, ResolutionPolicy resolutionPolicy);

這個方法的使用很簡單,在遊戲啟動過程的 pDirector->setOpenGLView(pEGLView); 行之後,直接調用一次就好。調用完了之後,CCDirector->WinSize就會變更為你設定的分辨率,之後就按照這個WinSize進行開發就好了,當然有些時候還是需要一些注意一些額外的地方後麵會提到。

這個方法的作用簡單來說,就是我們可以隻按照一套指定的分辨率設計遊戲,稱之為design resolution。然後選擇合適的適配方案,引擎就會在你的design resolution的基礎上進行縮放操作,使得按照指定分辨率設計的遊戲可以適配各種分辨率。

具體的主要適配方案主要有以下三種,為了方便理解還會配圖說明,先舉一個例子:

這是我們的實際屏幕尺寸,有寬屏568×320和正屏480×360兩種:
QQ20130807-1

而這是我們設定的design resolution 480×320:
QQ20130807-4

1) kResolutionExactFit:強製拉伸遊戲方案,這個方案實用性很低,用暴力的拉伸直接將遊戲拉伸到全屏,會導致圖片比例失真
QQ20130807-5

2) kResolutionNoBorder:無黑邊保持高寬比拉伸方案,這個方案最美觀,但是等比拉伸會導致左右或上下總會有一部分顯示到屏幕外,需要自己去保證UI元素不會顯示在屏幕外
QQ20130807-6
(可以看到如果我們按照design resolution直接設計UI,貼在上下兩側的按鈕等就可能顯示到屏幕外了。但是實際上cocos2d-x有提供方案來幫助幫助我們保證UI元素繪製在屏幕內,後麵的內容會提到具體方法。

3) kResolutionShowAll:有黑邊保持寬高比全顯示拉伸方案,這個方案在在上兩種方案之間,保持了寬高比也顯示了全部內容,但是會在屏幕兩側留下黑邊
QQ20130807-7
(可以看到design resolution和實際屏幕寬高比相差太大的話黑邊會比較多,但是這個方案是設計時最省心的)

三種適配模式都講解完了,大家對選用哪種模式應該自己心裏也都有數了。實際上最省心的方案就是找一個寬高比居中的design resolution,然後如果選用方案2的話就額外注意把元素都不要擺的太靠邊就OK了。

不過這樣做出來的遊戲顯得對用戶體驗太不上心了,個人覺得至少要檢測一下屏幕的實際寬高比,對寬屏和正屏係列采用兩套以上分辨率才可以。確定最合適的分辨率需要事先考察一下主流的屏幕分辨率,這裏為了方便把分辨率統一轉換成寬高比方便比較:
(安卓設備分辨率來自https://developer.android.com/guide/practices/screens_support.html
iPad: 1.333 : 1
iPhone5: 1.775 : 1
iPhone4(s): 1.5 : 1
WVGA800(800×480): 1.667 : 1
WVGA854(854×480): 1.779 : 1
1024×600: 1.707 : 1
WXGA(1280×800): 1.6 : 1
1024×768: 1.333 : 1
1280×768: 1.667 : 1
綜上觀察手持設備的分辨率再多,大部分也都遵循了顯示器界4:3、16:9、16:10三大主流寬高比,iPhone4(s)算是略特殊的一個寬高比。基於這個統計,再根據遊戲主推的平台,就可以確定兩到三個主支持分辨率來進行設計了。當然,根據高清設備采用一個高清的分辨率方案,有時也是很必要的。

2. 關於getVisibleSize和getVisibleOrigin

針對上文中kResolutionNoBorder模式下,遊戲UI有可能繪製到屏幕外的問題,有沒有什麼好的處理辦法?答案是有,cocos2d-x為我們準備了方法來獲取真正的可視範圍,詳情見這兩個方法:

1
2
3
4
5
6
7
8
9
/**
* Get the visible area size of opengl viewport.
*/
virtualCCSizegetVisibleSize()const;
 
/**
* Get the visible origin point of opengl viewport.
*/
virtualCCPointgetVisibleOrigin()const;

拿設計分辨率480×360但實際屏幕為480×320舉例(取這個值是因為沒拉伸好計算 -__-!),這個時候畫麵上下會有一部分顯示不出來,經過引擎的計算會得到如下的值:
visibleSize: 480 x 320
visibleOrigin: 0, 20

通過這兩個值,我們就可以正確的取得視圖上真正顯示在屏幕內的矩形範圍了。在這個值的配合下,將所有的UI元素指定為左上、左中、左下、中上、中下、右上、右中、右下8種對齊方式的一種,就可以動態的計算坐標,放在屏幕的合適位置了。

====水平有限,如有錯誤歡迎指正====

3. 動態變化的設計分辨率

上述的三種主要適配方案都是使用固定的設計分辨率的,比較方便設計師直接出固定坐標的UI設計圖。

仔細看了看適配方案的枚舉,可以看到還有兩個方案在setDesignResolutionSize的注釋裏沒有出現,他們就是kResolutionFixedHeight和kResolutionFixedWidth。(老實說沒有研究代碼前我也不知道這倆方案cocos2d-x已經出官方支持了,我和我的小夥伴們之前都是自己手動實現的啊 QAQ)

1) kResolutionFixedHeight:固定高度,動態寬度的適配模式,可以自由的自己根據動態的寬度處理遊戲

2) kResolutionFixedWidth:固定寬度,動態高度的適配模式,可以自由的自己根據動態的高度處理遊戲

這裏拿固定高度方案來舉個例子說明,比如我設定了固定高度600,如果屏幕實際高寬比為1.5 : 1,那麼CCDirector->WinSize就會變成900×600;如果屏幕實際高寬比為1.667 : 1,那麼CCDirector->WinSize就會變成1000×600。

看明白了沒有?對!就是說固定高度的話,設計遊戲全景的時候就要按最長的寬度可能(以600來算應該是600×1.78=1068)來設計,來保證最長寬高比的情況下右側不會出現黑邊。右側的UI元素必須設定為“右對齊”,這樣在寬度變窄的情況下UI元素會自動左移,寬度變寬的情況下UI元素會自動右移。另外要注意左右UI的擺放要保證在寬度最窄的情況下(600×1.333=800)不會重疊。

固定寬度的情況類似不多說了。

這是目前來說最好的動態適配方案,不用擔心黑邊也不用擔心UI出屏幕。而且不用考慮複雜的8種對齊方式,因為寬度和高度有一個是固定的,所以隻需要考慮兩種對齊。對於橫版或者豎版的卷軸遊戲來說,這個適配方案需要的額外設計成本幾乎為零。

4. 下期預告

基本上對於cocos2d-x多分辨率適配方案,我的使用見解主要就是這些了,有更多細節想要探討的歡迎留言。

關於分辨率適配的具體實現方式解析,將會在不久後寫一篇教程專門說明,敬請期待。

最後更新:2017-04-03 12:56:08

  上一篇:go Netty4詳解一:理解Netty的設計理念NIO
  下一篇:go Netty4詳解一:理解Netty的設計理念NIO