研究了兩天屏幕適配,瞭解了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的定位的
特別注意:
上面兩點都會致使想要在程序裏動態設置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下得效果圖:
大功告成!!!