Cocos2d-x lua 屏幕適配

研究了兩天屏幕適配,瞭解了Cocos提供的屏幕適配的方案有下面幾種:
1, EXACT_FIT
使用這個選項,能夠保證設計區域徹底鋪滿屏幕,可是可能會出現界面被拉伸。segmentfault

2, SHOW_ALL
按原始比例進行縮放,圖片不變形,爲了保證縮放後較長的邊也能徹底顯示,較短的邊剩下的位置會用黑邊填充,居中顯示。iphone

3, NO_BORDER
這個和上面的SHOW_ALL相反,按原始比例進行縮放,圖片不變形,爲了保證縮小後較短的邊全屏顯示,較長的邊超出屏幕的部分會被裁剪,不會出現黑邊,並且鋪滿屏幕佈局

下面兩種在Cocos2d-x 3.x版本里新添加的(沒仔細瞭解):
4, FIXED_HEIGHT
保持傳入的設計分辨率高度不變,根據屏幕分辨率修正設計分辨率的寬度。
適合高方向須要撐滿,寬方向可裁減的遊戲,結合setContentScaleFactor(RH/DH)使用ui

五、FIXED_WIDTH
保持傳入的設計分辨率寬度不變,根據屏幕分辨率修正設計分辨率的高度。
適合寬方向須要撐滿,高方向可裁減的遊戲,結合setContentScaleFactor(RW/DW)使用。spa

使用的時候設置也很簡單,按照我如今的理解,這個屏幕適配設置一次之後就無需再管理了,在function main 裏添加:設計

cc.Director:getInstance():getOpenGLView():setDesignResolutionSize(設計分辨率的寬度, 設計分辨率的高度, cc.ResolutionPolicy.NO_BORDER) -- NO_BORDER能夠修改爲上面任意一種模式

瞭解這些以後,以爲NO_BORDER是最合適的,而後繼續研究如何作出遊戲主菜單,我是使用Cocos Studio來作UI的,畫好的UI如何導入到項目和使用這裏就不詳細說了,不瞭解的參考以前寫的博客 查看,使用Cocos Studio作UI的時候,個人理解是畫布的大小就是設計分辨率的大小,因此畫布大小應該和程序裏setDesignResolutionSize的寬高一致,好比設計的是一個以iphone4爲準的橫屏遊戲,那畫布的寬高就設置成960 * 640,對應的程序設置應該是setDesignResolutionSize(960, 640, cc.ResolutionPolicy.NO_BORDER)code

把作好的UI導入到程序裏以後,在各個分辨率下運行,是本身指望的結果,到此屏幕適配研究完成了,可是使用NO_BORDER的方式適配屏幕會帶來一個問題,就是根據運行設備屏幕的大小不一樣,有可能上下左右的某兩條靠近邊線一部份內容會被裁掉看不到,附上2張個效果圖
個人Demo是基於960 * 640分辨率設計的
1,在960 * 640分辨率模擬器下運行效果:
請輸入圖片描述對象

2,在1280 * 720分辨率模擬器下運行效果:
請輸入圖片描述blog

能夠明顯的看到第2張圖上下各有一部分由於分辨率的關係被裁剪了,可是這不是我指望的結果,我但願某些控件是始終能徹底顯示在界面上的,好比個人遊戲名稱logo遊戲

最終想到的一個解決方案是Cocos Studio弄兩個Panel,一個負責加載絕對定位的控件,一個負責加載相對定位的控件,在程序載入UI以後,根據屏幕大小把負責加載相對定位的Panel大小修改爲屏幕大小,這樣這個Panel裏面的控件就會根據先對定位顯示到合適的位置,具體步驟以下:

在Cocos Studio裏拖界面的時候,使用結構:
請輸入圖片描述

這裏rootPanel是960 * 640大小的(全屏),activePanel是rootPanel的子視圖,而且鋪滿rootPanel。

把不須要根據屏幕的變化而改變位置的控件放入到rootPanel裏,好比開始遊戲按鈕,和界面的背景底圖,設置rootPanel的子空間佈局爲絕對佈局,而後activePanel的子空間佈局設置成相對佈局,這個時候放入activePanel裏的控件位置是相對於activePanel的定位的

特別注意:

  1. rootPanel的子空間佈局必定要設置成絕對佈局
  2. 在設計activePanel的屬性時,千萬不要使用百分比,包括設置"尺寸和模式"和"控件佈局"的時候

上面兩點都會致使想要在程序裏動態設置activePanel大小和位置的時候無效,血的教訓呀!!!

把UI按照上面的思路畫完以後,導入到項目裏,這個時候須要作的是拿到activePanel對象、當前屏幕讀取的分辨率大小、和從畫布(UI界面)的什麼位置開始讀activePanel設置合適的位置和大小,而後把具體看下面代碼:

local ui      = rootNode:getChildByName("activePanel") -- 獲得activePanel節點
local size    = cc.Director:getInstance():getVisibleSize() -- 屏幕分辨率大小
local origin  = cc.Director:getInstance():getVisibleOrigin() -- 從畫布的某個點顯示

-- 若是origin.x不等於0,表示是左右是被裁過的,把activePanel的x位置設置到屏幕裏的0的位置
if origin.x ~= 0 then
  ui:setPositionX(ui:getPositionX() + origin.x)
end

-- y的設置理解同上,上下被裁過的
if origin.y ~= 0 then
  ui:setPositionY(ui:getPositionY() + origin.y)
end

-- 經過上面兩個判斷設置,ui在顯示起始位置被固定好了,接下來設置ui的大小等於屏幕的大小,就大功告成了
ui:setContentSize(size)

作上面的處理,獲得的結果就是指望的結果了,在960*640不會產生任何邊變化,這裏不貼圖了
在1280 * 720下得效果圖:
請輸入圖片描述

大功告成!!!

相關文章
相關標籤/搜索