CocosCreator屏幕適配
CocosCreator通過以下幾個部分完成多分辨率適配解決方案:
Canvas(畫布)?組件隨時獲得設(shè)備屏幕的實際分辨率并對場景中所有渲染元素進行適當?shù)目s放。
Widget(對齊掛件)?放置在渲染元素上,能夠根據(jù)需要將元素對齊父節(jié)點的不同參考位置。
Label(文字)?組件內(nèi)置了提供各種動態(tài)文字排版模式的功能,當文字的約束框由于 Widget 對齊要求發(fā)生變化時,文字會根據(jù)需要呈現(xiàn)完美的排版效果。
Sliced Sprite(九宮格精靈圖)?則提供了可任意指定尺寸的圖像,同樣可以滿足各式各樣的對齊要求,在任何屏幕分辨率上都顯示高精度的圖像。
對于分辨率的概念我們經(jīng)常會了解到的是設(shè)計分辨率和屏幕分辨率
設(shè)計分辨率?是內(nèi)容生產(chǎn)者在制作場景時使用的分辨率藍本,也就是美術(shù)人員或開發(fā)人員設(shè)計ui時使用的分辨率模版。
屏幕分辨率?是游戲在設(shè)備上運行時的實際屏幕顯示分辨率,也就是游戲運行時我們所看到的實時分辨率。
而我們所說的屏幕適配,就是把設(shè)計分辨率適配到實時分辨率上,避免穿幫。
通常設(shè)計分辨率會采用市場目標群體中使用率最高的設(shè)備的屏幕分辨率,比如目前安卓設(shè)備中?800 x 480
和?1280 x 720
?兩種屏幕分辨率,或 iOS 設(shè)備中?1136 x 640
?和?960 x 640
?兩種屏幕分辨率。當然也可能是web端常用到1080 x 1920等。
這樣當美術(shù)或策劃使用設(shè)計分辨率設(shè)置好場景后,就可以自動適配最主要的目標人群設(shè)備。
不過如果需要做適配,設(shè)計分辨率的意義不是很大,但是不能太離譜。
當設(shè)計分辨率和屏幕分辨率出現(xiàn)差異時,也就是我們要解決的問題,適配屏幕分辨率。
假設(shè)我們的設(shè)計分辨率為?800 x 480
,美術(shù)制作了一個同樣分辨率大小的背景圖像

假如設(shè)計分辨率和屏幕分辨率寬高比相同,比如以上圖為例,設(shè)計分辨率800 x 480。屏幕分辨率是?1600 x 960,那么將背景圖像放大 1600/800 =?2 倍?就可以完美適配屏幕。
這種只針對于適配需求比較簡單的情況。
雖然cocosCreator官方提供了允許出現(xiàn)黑邊,和不出現(xiàn)黑邊但也不提供分別縮放 x 和 y 軸縮放率(圖像可能會拉伸)的適配情況,實際開發(fā)中基本不會考慮,誰不想做的更好呢。
于是把適配寬高的方案變通一下,讓它在不同分辨率下既不出現(xiàn)黑邊,也不會裁剪元素,不拉伸元素,保證ui元素的基本布局。
假設(shè)屏幕分辨率是?1920 x 960
,寬屏適配,同樣在下圖中以紅色方框表示設(shè)備屏幕可見區(qū)域。我們使用 Canvas 組件提供的?適配寬度(Fit Width
)模式,將設(shè)計分辨率的寬度自動撐滿屏幕寬度,也就是將場景放大 1920/800 =?2.4 倍。

但是在設(shè)計分辨率寬高比較小時,使用這種模式會裁剪掉屏幕上下一部分背景圖
如果我們在這種情況下考慮去判斷高度縮放比例:也就是1920/bgheigt(or設(shè)計分辨率的高度)?= gamescale,然后動態(tài)設(shè)置場景縮放。這樣沒有黑邊了,但相對的屏幕寬度的兩邊可能會有元素被裁減。這里就可以通過wedit組件來適配邊距。
原理就是,通過寬高比適配寬度有黑邊時就動態(tài)設(shè)置x軸方向的縮放,適配高度有黑邊時就動態(tài)設(shè)置Y軸方向的縮放,
cocosCreator提供了web端動態(tài)獲取橫豎屏切換的監(jiān)聽方法
cc.view.setResizeCallback(this.onResize.bind(this));
這樣就可以在onresize中動態(tài)設(shè)置分辨率適配
cc.view.setDesignResolutionSize(1350, 750, cc.ResolutionPolicy.FIXED_WIDTH);
或
cc.view.setDesignResolutionSize(1350, 750, cc.ResolutionPolicy.FIXED_HEIGHT);
貼個實例代碼:
當獲取到屏幕切換的回調(diào)onResize,該回調(diào)可以考慮在初始化的時候調(diào)用一次:
onResize() {
????????let vsize = cc.view.getFrameSize();
????
????????if (vsize.width > vsize.height) {
????????????????//橫屏動態(tài)適配
????????????????let th = 750;
????????????????let tw = 750 * vsize.width / vsize.height;
????????????????if (tw < 1350) {
????????????????cc.view.setDesignResolutionSize(1350, 750, cc.ResolutionPolicy.FIXED_WIDTH);
????????????????} else {
????????????????cc.view.setDesignResolutionSize(1350, 750, cc.ResolutionPolicy.FIXED_HEIGHT);
????????????????}
????????????????if (cc.winSize.width > 1334) {
????????????????????????GameConfig.gameScale = cc.winSize.width / 1334;
????????????????}
????????} else {
????????????????//豎屏動態(tài)適配
????????????????????let tw = 750;
????????????????????let th = 750 * vsize.height / vsize.width;
????????????????????if (th < 1440) {
????????????????????cc.view.setDesignResolutionSize(750, ?????????????????????????1440,cc.ResolutionPolicy.FIXED_HEIGHT);?
????????????????????} else {
????????????????????cc.view.setDesignResolutionSize(750, 1440, cc.ResolutionPolicy.FIXED_WIDTH);
????????????????????}
????????????????????if (cc.winSize.height > 1334) {
????????????????????????????????GameConfig.gameScale = cc.winSize.height / 1334;
????????????????????}
????????}
????????//這里就可以根據(jù)GameConfig.gameScale來適配屏幕的縮放了
????????//另外還可以自定義添加回調(diào)去設(shè)置橫豎屏適配
????????/*
????????let viewWay = cc.winSize.width > cc.winSize.height ? Direction.Horizontal : Direction.Vertical;
????????ObserverClass.publish(EventType.winResize, viewWay);
*/
}
對于手機端,可能需要各系統(tǒng)sdk提供的屏幕切換接口了。當前如果是只適配豎屏或只適配橫屏就可以直接套用。