Cocos2d-JS螢幕適配(NO-BORDER模式)
距離上一篇部落格已經有將近一年時間,沒有寫什麼一個是因為一直太忙,另外一個也是不知道要寫什麼,還是做遊戲專案,不過從手遊轉到了Html5遊戲,繼續使用Cocos2d,語言換成了JS。
不多敘舊,這次簡單說下Cocos2d-JS的適配問題,上一個專案(手機QQ空間玩吧的《點點萌萌消》,歡迎試玩^_^)沒有考慮解析度適配問題,直接採用的是640*960的方式進行開發,基本上不用考慮適配問題。
當前這個專案需要考慮螢幕白邊問題,今天有點閒工夫,就慢慢研究了一上午,還有點意思。說有點意思是因為NO_BORDER模式需要計算螢幕尺寸,而這也將解決螢幕適配問題。
接著在程式碼中對這個適配層進行位置和大小的計算,如果依然按照這篇部落格的程式碼寫,可能不能得到想要的效果,因為Cocos2d-JS是有點不同的。
現在我們重新考慮NO_BORDER模式的原理。
程式碼中對NO_BORDER的解釋是:Theentire application fills the specified area, without distortion but possiblywith some cropping,while maintaining the original aspect ratio of theapplication.(翻譯即是:程式將是充滿整個區域,做裁剪而不是變形處理,裁剪不會改變原有寬高比)
如上圖所示:在iPhone4s(我目前用的)的手機上,如果說設計高寬為1280*720(設計高寬通過cc.view.setDesignResolutionSize函式設定),那麼螢幕上顯示的高寬到底是多少呢?而這個高寬也是我們適配層需要設定的大小。
不是960*640,也不是1280*720,是不是有點意思了。
對於NO_BORDER模式,手機螢幕大小作為攝像頭的尺寸,設計高寬作為物件(舞臺),那麼,在這個例子中,攝像頭需要做放大操作,使得螢幕高度能容納720的畫素展示。
感性的做一下放大操作,可以感知適配層大小必須為寬960.0*(720.0/640.0)和高720.0。
理性分析下,很快適配層的大小就計算出來了程式碼見後面的dockUI函式。
NO_BORDER適配合適解析度差異大且UI相對獨立的情況,效果算是比較理想的吧。var _LayoutUtil = cc.Class.extend({
//UI層
dockUI: function(panelUI) {
panelUI.setAnchorPoint(0.5, 0.5);
var size = cc.view.getFrameSize();
var wsize = cc.director.getWinSize();
var rw = wsize.width/size.width;
var rh = wsize.height/size.height;
panelUI.setPosition(wsize.width/2, wsize.height/2);
if(rw > rh){
panelUI.setContentSize(cc.size(size.width*rh, size.height*rh));
}else{
panelUI.setContentSize(cc.size(size.width*rw, size.height*rw));
}
},
//錨點預設為0.5
/**
* 停靠在左邊,距離左邊距intervalX個畫素
* @param {CCNode} node 節點
* @param {int} intervalX 邊距
* @return {null} 無
*/
dockLeft: function(node, intervalX, isCenter) {
intervalX = intervalX | 0;
var parent = node.getParent();
var pos = node.getPosition();
var size = node.getContentSize();
if(isCenter){
node.setPosition(size.width / 2 + intervalX, node.getParent().getContentSize().height/2);
}else{
node.setPosition(size.width / 2 + intervalX, pos.y);
}
},
/**
* 停靠在右邊,距離右邊距intervalX個畫素
* @param {CCNode} node 節點
* @param {int} intervalX 邊距
* @return {null} 無
*/
dockRight: function(node, intervalX, isCenter) {
intervalX = intervalX | 0;
var parent = node.getParent();
var psize = parent.getContentSize();
var pos = node.getPosition();
var size = node.getContentSize();
if(isCenter){
node.setPosition(psize.width - size.width / 2 - intervalX, node.getParent().getContentSize().height/2);
}else{
node.setPosition(psize.width - size.width / 2 - intervalX, pos.y);
}
},
/**
* 停靠在上邊,距離上邊距intervalY個畫素
* @param {CCNode} node 節點
* @param {int} intervalX 邊距
* @return {null} 無
*/
dockTop: function(node, intervalY, isCenter) {
intervalY = intervalY | 0;
var parent = node.getParent();
var psize = parent.getContentSize();
var pos = node.getPosition();
var size = node.getContentSize();
if(isCenter){
node.setPosition(node.getParent().getContentSize().width/2, psize.height - size.height / 2 - intervalY);
}else{
node.setPosition(pos.x, psize.height - size.height / 2 - intervalY);
}
},
/**
* 停靠在下邊,距離下邊距intervalY個畫素
* @param {CCNode} node 節點
* @param {int} intervalX 邊距
* @return {null} 無
*/
dockBottom: function(node, intervalY, isCenter) {
intervalY = intervalY | 0;
var parent = node.getParent();
var pos = node.getPosition();
var size = node.getContentSize();
if(isCenter){
node.setPosition(node.getParent().getContentSize().width/2, size.height / 2 + intervalY);
}else{
node.setPosition(pos.x, size.height / 2 + intervalY);
}
},
/**
* 停靠在中心
* @param {CCNode} node 節點
* @return {null} 無
*/
dockCenter: function(node) {
var parent = node.getParent();
var size = parent.getContentSize();
node.setPosition(size.width / 2, size.height / 2);
},
});
var LayoutUtil = new _LayoutUtil();