cocos2d-x 之 適配解析度全屏的方法
cocos2d-x 2.0 提供一個極有價值的新特徵: setDesignResolutionSize() 。
這個函式用於指定一個 OpenGL 檢視,然後將這個檢視對映到裝置螢幕上。根據不同的設定,檢視會自動縮放顯示內容,為 cocos2d-x 自適應多種解析度提供了基本支援。
不過要真正實現自適應解析度,從場景設計、美術製作到程式編寫,都需要遵循一套規範,才能極大減少工作量。
注意:本文假定遊戲是橫向顯示的。
~
明確自適應多種解析度的需求
要讓遊戲在不同解析度下都獲得良好的使用者體驗,應該滿足這幾個要求:
- 背景圖填滿整個畫面,不出現黑邊;
- 背景圖的主要內容都顯示在螢幕上,儘可能少的裁剪圖片(減少超出螢幕可視區域的部分);
- 如果背景圖需要放大,儘可能減小放大的比例,避免放大後出現明顯的模糊;
- 使用者介面的文字標籤、按鈕在任何解析度下都應該完整顯示,並且容易互動。
上述需求實際上可以分解為兩部分:
- 如何製作滿足多種解析度的背景圖;
- 如何定位使用者介面元素(標籤、按鈕等)。
~
製作適合多種解析度的背景圖
在開始製作背景圖前,我們看看市面上各種裝置(480 畫素解析度的老裝置 2012 的遊戲應該可以無視了)常見的畫素解析度(resolution in pixels):
Device | Width | Height |
---|---|---|
iPad | 1024px | 768px |
New iPad | 2048px | 1536px |
iPhone | 960px | 640px |
Android Phone 1 | 800px | 480px |
Android Phone 2 | 854px | 480px |
Android Phone 3 | 1280px | 720px |
Android Pad 1 | 1024px | 600px |
Android Pad 2 | 1280px | 800px |
經過幾個遊戲的實踐,我們確定了幾個背景圖的解析度:
-
2048px * 1536px
專門針對 New iPad,設計師的原稿也是這個尺寸。
-
960px * 720px
這個解析度針對 iPhone 和 iPad 裝置。在 iPhone 上 1:1 顯示,上下各剪裁掉 40px。而在 iPad 上按 1.067 放大顯示,正好填滿整個螢幕,並且使用者看不到模糊。從 2048px 的原稿匯出 PNG 時,按照 0.469 比例縮小正好就是 960px * 720px。
-
854px * 480px
市面上的 Android 手機,854px * 480px 和 800px * 480px 是最常見的兩種解析度。2048px 的原稿按照 0.417 比例縮小,然後裁減掉上下多餘部分就可以得到需要的 PNG 圖片。
-
1280px * 800px
應付高解析度的 Android 手機和平板裝置,在各種解析度下都可以獲得很好的顯示效果。2048px 的原稿按照 0.625 比例縮小,然後裁減掉上下多餘部分就可以得到需要的 PNG 圖片。
對於美術來說,背景圖都按照 2048px * 1536px 的尺寸繪製。然後用指令碼配合 ImageMagick 就可以自動匯出四種解析度的背景圖片。
如果需要最大程度減小遊戲的下載體積,那麼可以只使用 960px * 720px 的素材。並且參考本文後面示例程式的做法,用一套素材應付各種不同的解析度。
唯一需要注意的問題就是:確保畫面中的主要內容在各種裝置上都位於螢幕的可視區域中。
下面幾個圖展示 2048px 原稿在不同裝置上的可視區域:
~
製作適合各種解析度的使用者介面元素
相比背景圖,介面元素的製作只需要考慮一點:必須能夠放置在最小的可視區域中。如下圖介面底部有一排按鈕,這些按鈕在各種解析度下都能完整顯示:
在匯出介面元素的 PNG 圖片時,仍然使用指令碼檔案和 ImageMagick 按照特定比例自動縮放。
~
在各種解析度的螢幕上定位介面元素
準備好了美術素材,接下來的挑戰就是如何在不同解析度的裝置中定位介面元素。
為了解決這個問題,我們做了大量的嘗試,最終找到一種可行的解決方案,而且使用起來非常簡單。
虛擬解析度
為了簡化程式的開發,我們使用一個統一的虛擬座標系來對映裝置的螢幕。經過幾個產品的實踐,證明將螢幕寬度設定為 960pt 是很合理的。
特別注意:在討論虛擬座標系時,一律使用 pt(Point)作為單位,而不是 px(Pixel)。
下面的表格整理了各種裝置解析度與 960pt 寬度虛擬解析度的對應關係:
Device | Width | Height | Virtual Width | Virutal Height | Scale |
---|---|---|---|---|---|
iPad | 1024px | 768px | 960pt | 720pt | 1.066666667 |
New iPad | 2048px | 1536px | 960pt | 720pt | 2.133333333 |
iPhone | 960px | 640px | 960pt | 640pt | 1.0 |
Android Phone 1 | 800px | 480px | 960pt | 576pt | 0.833333333 |
Android Phone 2 | 854px | 480px | 960pt | 540pt | 0.889583333 |
Android Phone 3 | 1280px | 720px | 960pt | 540pt | 1.333333333 |
Android Pad 1 | 1024px | 600px | 960pt | 562pt | 1.066666667 |
Android Pad 2 | 1280px | 800px | 960pt | 600pt | 1.333333333 |
根據參考點定位介面元素
在遊戲初始化時,引擎就會根據裝置的實際解析度,自動設定好對應的虛擬解析度,並且確定螢幕上的幾個參考點:
Position | Value |
---|---|
left | 0pt |
right | 959pt |
top | 虛擬解析度的高度 - 1 |
bottom | 0pt |
center x | 480pt |
center y | 虛擬解析度的高度 / 2 |
有了參考點,定位介面元素就很簡單了。例如一個按鈕的原點(按鈕圖片中心點)相對於螢幕左側 40pt,相對於螢幕底部 30pt。那麼在不同解析度的裝置上,這個按鈕和螢幕左下角的距離都是差不多的。
只要確保所有介面元素都使用參考點來定位,那麼就絕不會出現在裝置螢幕上看不到介面元素的情況。
~
示例程式
為了方便大家進行測試,本文的示例工程已經編譯成 Windows 可執行檔案。執行時可以用下列命令列啟動以便測試不同解析度:
命令列引數1 2 |
|
或者雙擊 test_multires.cmd 直接檢視不同解析度的執行效果。
其他:
- 示例程式只包含按照 960px * 720px 製作的素材。
~
補充說明
本文前面描述瞭如何建立適合不同解析度的圖片,但最後的示例程式並沒有考慮這一點,而是用一套素材就搞定了多種解析度。實際上,我個人推薦使用一套素材適應多種解析度,最多再為 New iPad 單獨準備一套素材,這樣可以顯著減少工作量。
如果一定要按照不同解析度使用不同的素材,那麼在顯示圖片時需要呼叫 setScale() 調整圖片的縮放比例。這樣做的原因是 setDesignResolutionSize() 設定虛擬解析度後,會指定一個全域性的縮放比例,所有的圖片即便是 scale = 100%,也會自動縮放。所以當圖片尺寸和虛擬解析度不一致時,我們就需要手動調整圖片縮放比例了。
假設裝置解析度是 1280px * 720px,虛擬解析度是 960pt * 540pt,背景圖是 1280px * 800px。要確保背景圖 1:1 顯示在螢幕上,參考如下程式碼:
讓圖片按 1:1 顯示在螢幕上1 2 3 4 5 6 |
|
~
-EOF-