麒麟子在五一勞動節這一天,爲大家準備了一個DEMO。 DEMO演示了,大廳,背景,以及像 3D麻將,鬥地主等桌面的適配方案。使大家可以用一套資源,適配從iPhoneX(目前最長的移動設備) 到 iPad(目前最短的移動設備 )的分辨率。
PS:黑莓那種1:1也可以的,只是我人爲的把它忽略了。
本DEMO在線演示: https://qilinzi.ukylin.net/?lesson=09
本DEMO源代碼:https://gitee.com/qilinzi/qlz_ccc_tips
不謀萬世者,不足謀一時。不謀全局者,不足謀一域。
麒麟子對這句話的理解就是,早睡早起,好好學習,天天向上。哈哈哈哈。正文開始之前,先瞎**幾句,是麒麟子的風格,大家久了就習慣了。如果不想看的,直接到正文即可。 這段的主要目的,是想緩解一下大家的壓力。畢竟大部分看這個文章的朋友,都在996,或者在去996的路上。
麒麟子不只一次說過,不要總是學人有跟熱點,不要總幻想自己是站在風口的豬。即便你飛起來了,那萬一風突然停了呢。選擇一個自己看好的領域進行深耕,不斷積累。
而選擇什麼領域,技術只是基礎。用戶需求是否可持續,纔是你能否持續深耕的關鍵。
麒麟子有云:棋牌之路漫漫其修遠兮,吾將上下而求索(翻譯:棋牌領域是棵常青樹,是一個可以深耕的領域)
後面的文章,大部分是基於棋牌來講解知識點,但對於其他遊戲也同樣適用
一、不同適配策略的表現效果
Cocos Creator的Canvas提供了fitWidth和fitHeight兩個開關,可以實現4種效果
1、fitWidth = false, fitHeight = false
對應的是自動選擇定寬還是定高,當用戶手機比設計分辨率更寬時,使用定寬。 當用戶手機比設計分辨率更短時,使用定高。 帶來的就是裁剪效果
2、fitWidth = true, fitHeight = false
對應的是定寬效果
3、fitHeight = false,fitHeight = true
對應的是定高效果
4、fitWidth = true,fitHeight = true
對應的是show_all效果
在設計分辨率不變的情況下,不同的適配策略,在不同的設備上的表現效果,如下圖
二、幼麟棋牌的適配模式
1、適配效果介紹
棋牌遊戲,卡牌遊戲等項目的適配,比RPG要難一點。特別是牌桌和全屏界面。對於RPG來說,只需要做靠主界面的停靠即可。而棋牌遊戲,桌子本來空間就不足,簡單的停靠是滿足不了需求的。幼麟棋牌團隊在經歷了十幾個項目之後總結出一條鐵律:不允許任意分辨率對內容裁剪。這條鐵律沿用至今,暫時沒有發現滿足不了的情況。
看到上面黑字的時候,我們肯定第一時間想到全顯的適配策略。
心細的朋友應該能夠發現,全顯和幼麟棋牌,都是保證內容能夠全部顯示。但爲什麼麒麟子在畫圖的時候,要把全顯的背景弄成黑色呢。 你沒看錯,這不是麒麟子腦袋抽風,這是因爲,二者有區別。
有興趣的朋友可以拿ShowAll和幼麟棋牌的適配方案做一個測試,你會發現,核心差異就在Widget是否能夠正確停靠的問題。 使用ShowAll方案,Widget會按綠色邊緣作爲停靠。 而使用幼麟棋牌方案,Widget會使用屏幕寬高作爲停靠。
2、全分辨率適配代碼實現
這裏要注意,CocosCreator場景中,一定要去掉 fitWidth和fitHeight。 一個都不能留,否則是有問題的。下面的代碼是從Demo代碼中的Utils.ts文件中截取的。
public static resize() {
var cvs = cc.find('Canvas').getComponent(cc.Canvas);
//保存原始設計分辨率,供屏幕大小變化時使用
if(!this.curDR){
this.curDR = cvs.designResolution;
}
var dr = this.curDR;
var s = cc.view.getFrameSize();
var rw = s.width;
var rh = s.height;
var finalW = rw;
var finalH = rh;
if((rw/rh) > (dr.width / dr.height)){
//!#zh: 是否優先將設計分辨率高度撐滿視圖高度。 */
//cvs.fitHeight = true;
//如果更長,則用定高
finalH = dr.height;
finalW = finalH * rw/rh;
}
else{
/*!#zh: 是否優先將設計分辨率寬度撐滿視圖寬度。 */
//cvs.fitWidth = true;
//如果更短,則用定寬
finalW = dr.width;
finalH = rh/rw * finalW;
}
cvs.designResolution = cc.size(finalW, finalH);
cvs.node.width = finalW;
cvs.node.height = finalH;
cvs.node.emit('resize');
}
麒麟子保證,用上面的代碼,配上fitWidth = false, fitHeight = false. 你將再也不用因爲分辨率適配而掉頭髮 (因爲劉海屏適配掉的頭髮不算在這個裏面)
不要太浪哦!!!!
三、背景適配
按理說,我們弄一張足夠大的背景,總是能撐滿所有分辨率的。但這樣一來,美術的設計成本就高了。 特別是不能複用一些現成(別人)的資源。
麒麟子弄了一個bg_scaler.ts來滿足大家,大家可以通過點擊大廳的 居中,自由縮放,裁剪 來觀察不同的效果。
關鍵代碼如下:
resize () {
this.node.width = this.originWidth;
this.node.height = this.originHeight;
//0、居中(居中其實不需要掛這個腳本,浪費效率)
//1、寬高都根據高度拉伸
//2、長邊充滿
var cvs = cc.find('Canvas').getComponent(cc.Canvas);
var size = cc.view.getFrameSize();
var dr = Utils.curDR;
var scaleMethod = this.mode;
//
var fitWidth = true;
//如果更寬,則使用定高
if((size.width/size.height) > (dr.width / dr.height)){
fitWidth = false;
}
//自由縮放撐滿
if(scaleMethod == 1){
if(fitWidth){
this.node.height = this.node.width/size.width * size.height;
}
else{
this.node.width = this.node.height/size.height * size.width;
}
}
//保持等比縮放撐滿
else if(scaleMethod == 2){
if(fitWidth){
//定寬表示設備更高了,則以高的縮放爲準
var oldHeight = this.node.height;
this.node.height = this.node.width/size.width * size.height;
var scale = this.node.height/oldHeight;
this.node.width = scale * this.node.width;
}
else{
//定高表示設備更寬的,以寬的縮放爲準
var oldWidth = this.node.width;
this.node.width = this.node.height/size.height * size.width;
var scale = this.node.width / oldWidth;
this.node.height = scale * this.node.height;
}
}
else{
//默認處理,有黑邊
}
}
四、麻將桌子適配
麒麟子的DEMO裏面,處理了一個假3D的麻將桌子。因爲這個比較特殊,所以放在這裏作爲了案例。此代碼在DEMO代碼的 09_3dmjtable.ts文件中。它實現的效果是,如果屏幕比設計分辨率高,比如 iPad這樣的設備,那麼將會多顯示出一些牆壁上的內容。如果比設計分辨率更長,比如iPhoneX,那麼將會做一定的拉伸,確保背景充滿。
start () {
cc.find('Canvas').on('resize',this.resize.bind(this));
this.resize();
}
resize(){
var canvas = cc.find('Canvas');
if(canvas.width > Utils.curDR.width){
this.node.width = canvas.width;
}
}
五、鬥地主桌子適配
半弧的桌子適配是最容易的,只需要一個Widget無腦充滿即可
六、總結
本文章和DEMO只是演示了一些基本的適配技巧。 每一個項目,面對的需求都大相徑庭,沒有哪一個方案是可以一勞永逸的,需要大家根據自身項目的情況,酌情調整。
本DEMO在線演示: https://qilinzi.ukylin.net/?lesson=09