溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

Cocos2D-X屏幕適配新解

發(fā)布時(shí)間:2020-07-22 01:00:46 來源:網(wǎng)絡(luò) 閱讀:247 作者:yerik_yao 欄目:游戲開發(fā)

Cocos2D-X屏幕適配新解

發(fā)布于:2013-05-13 09:31閱讀數(shù):8182

為了適應(yīng)移動(dòng)終端的各種分辨率大小,各種屏幕寬高比,在 Cocos2D-X(當(dāng)前穩(wěn)定版:2.0.4) 中,提供了相應(yīng)的解決方案,以方便我們在設(shè)計(jì)游戲時(shí),能夠更好的適應(yīng)不同的環(huán)境。 而在設(shè)計(jì)游戲之

閱讀器


為了適應(yīng)移動(dòng)終端的各種分辨率大小,各種屏幕寬高比,在 Cocos2D-X(當(dāng)前穩(wěn)定版:2.0.4) 中,提供了相應(yīng)的解決方案,以方便我們在設(shè)計(jì)游戲時(shí),能夠更好的適應(yīng)不同的環(huán)境。

而在設(shè)計(jì)游戲之初,決定著我們屏幕適配的因素有哪些?簡而言之只有兩點(diǎn):屏幕大小和寬高比。這兩個(gè)因素是如何影響游戲的呢?
屏幕大小: 從小分辨率 480×320 1280×800 分辨率,再到全高清 1080p,從手機(jī)到平板,還有蘋果設(shè)備的 Retina屏,這么多不同的分辨率,而且大小差距甚大,不可能做到一套資源走天下,資源往小了設(shè)計(jì),在大屏幕會顯示模糊,圖片往大了設(shè)計(jì),在小屏幕設(shè)備又太浪費(fèi),而且小屏幕的手機(jī)硬件資源也會相對的緊缺,所以 根據(jù)屏幕大小使用不同的資源 是有必要的,而 Cocos2D-X 也幫我們解決了這一點(diǎn)。
寬高比: 什么是寬高比,就是你的屏幕是方的還是長的,靠近方形的分辨率如 480×320,比例為 3:2,還有 960×540 的16:9 標(biāo)準(zhǔn)寬屏,這也算是兩種總極端情況了,如果能在這兩種比例情況做好適配基本就可以了,如果比 3:2 “更方”如 4:3,比 16:9 “更長”,那么不論如何布局,顯示效果差距甚大,最好對固定比例優(yōu)化吧。當(dāng)在寬高比在一定范圍內(nèi),可以通過靈活編寫程序去適應(yīng),而在顯示效果上,Cocos2D-X為我們提供了三種模式,這些 模式更多的是幫我們解決比例不一的情況而存在 的,如果只是屏幕大?。ū壤粯樱?,那通過簡單的放大縮小即可完成。
三種模式
說是三種模式,其實(shí)還有一種“無模式”,也就是 Cocos2D-X默認(rèn)的適配方案,現(xiàn)在我們就來認(rèn)識一下這些模式,并且通過這些模式去認(rèn)識其中一些概念 FrameSize、WinSize、VisibleSize、VisibleOrigin,以及它們存在的意義,并且最后靈活運(yùn)行這些概念 創(chuàng)建出一個(gè)不屬于這些模式而超越這些模式的新適配解決方案,這是最終目的。
kResolutionUnKnown 認(rèn)識 FrameSize
這是 Cocos2D-X 編寫的默認(rèn)模式,沒有做任何處理,在這種情況下,游戲畫面的大小與比例都是不可控的,在程序運(yùn)行之初,由各個(gè)平臺入口函數(shù)定義畫面大?。?/div>
1.// proj.linux/main.cpp linux 平臺手動(dòng)指定畫面大小
2.CCEGLView* eglView = CCEGLView::sharedOpenGLView();
3.eglView->setFrameSize(720, 480);
4.
5.// proj.android/jni/hellocpp/main.cpp android 平臺由 jni 調(diào)用傳入設(shè)備分辨率參數(shù)
6.void Java_org_cocos2dx_lib_Cocos2dxRenderer_nativeInit(JNIEnv* env, jobject thiz, jint w, jint h)
7.{
8. if (!CCDirector::sharedDirector()->getOpenGLView())
9. {
10. CCEGLView *view = CCEGLView::sharedOpenGLView();
11. view->setFrameSize(w, h);
12.
13. AppDelegate *pAppDelegate = new AppDelegate();
14. CCApplication::sharedApplication()->run();
15. }
16. else
17. {
18. // other
19. ...
20. }
21.}
1.
在此我們首先認(rèn)識了 FrameSize 參數(shù),在游戲運(yùn)行時(shí),我們可以通過 CCEGLView::sharedOpenGLView()->getFrameSize();獲得此值。如果在手機(jī)上運(yùn)行,那么不同分辨率將會得到不同的值,既然這個(gè)值不可控,那么在寫游戲中也就沒有參考價(jià)值了,比如我們寫一個(gè)精靈的位置距離底部 320 高度,在 480×320 分辨率,能看到其在屏幕上方,如果換一臺手機(jī)分辨率 960×540 那么只能顯示在中間靠上的位置,如果設(shè)置精靈位置為距離屏幕上方(高度)320,反之依然,顯示效果不一。
此時(shí)可行的方案是使用百分比,如精靈位置在屏幕橫向距離左邊 1/3 寬度,在 1/2 正中間處,而類似這樣的設(shè)置也不用依賴 FrameSize 的具體數(shù)值。而這樣的做法,使得內(nèi)部元素像彈簧一樣,隨著 FrameSize 的大小改變而改變,伸縮或者擠壓,對于圖片資源大小也是完全不可控,如果根據(jù)屏幕大小放大縮小,那我們可以考慮用下面要說的模式,在此不推薦使用 Cocos2D-X 的無模式方案。
kResolutionExactFit and kResolutionShowAll 認(rèn)識 WinSize
在 AppDelegate.cpp 處可以通過設(shè)置:
1.CCEGLView::sharedOpenGLView()->setDesignResolutionSize(720, 480, kResolutionShowAll);
2.// 或者
3.CCEGLView::sharedOpenGLView()->setDesignResolutionSize(720, 480, kResolutionExactFit);
1.
DesignResolutionSize!顧名思義,也就是邏輯上的游戲屏幕大小,在這里我們設(shè)置了其分辨率為 720×480 為例,那么在游戲中,我么設(shè)置精靈的位置便可以參照此值,如 左下角 ccp(0,0),右上角 ccp(720, 480),而不論 FrameSize 的大小為多少,是 720×480 也是,是 480×320 也罷,總能正確顯示其位置,左下角和右上角。能夠?qū)崿F(xiàn)這一點(diǎn)的原因是,固定了設(shè)計(jì)分辨率大小,從而確定了其固定的寬高比,它的 優(yōu)勢 是可以使用具體的數(shù)值擺放精靈位置,不會因?yàn)閷?shí)際屏幕大小寬高比而是內(nèi)部元素相對位置關(guān)系出現(xiàn)混亂。
而為了保持畫面的寬高比,Cocos2D-X 做了些犧牲,犧牲了什么呢?kResolutionExactFit 犧牲了畫質(zhì)而保持了全屏顯示,對畫面進(jìn)行了拉伸,這意味著什么?意味著相對極端情況下,本來精靈是方形的,顯示出來變成長方形,本來圓形的變成了橢圓,固此模式不推薦使用。kResolutionShowAll 為了保持設(shè)計(jì)畫面比例對四周進(jìn)行留黑邊處理,使得不同比例下畫面不能全屏。魚和熊掌不能兼得也。
我們可以通過如下方法獲取到 setDesignResolutionSize 所設(shè)置的值:
1.CCSize winSize = CCDirector::sharedDirector()->getWinSize();
我們可以用 Cocos2D-X 程序是如何開始運(yùn)行與結(jié)束的 一文的方法,跟蹤 WinSize 的初始化,獲取過程,在這里簡單提一下,如下步驟:
1.// 獲得 winSize
2.CCSize winSize = CCDirector::sharedDirector()->getWinSize();
3.
4.// 查看其 getWinSize(); 方法實(shí)現(xiàn)
5.[cocos2dx-path]/cocos2dx/CCDirector.cpp
6.
7.CCSize CCDirector::getWinSize(void)
8.{
9. return m_obWinSizeInPoints;
10.}
11.
12.// 而 m_obWinSizeInPoints 是何時(shí)被賦值的
13.[cocos2dx-path]/cocos2dx/platform/CCEGLViewProtocol.cpp
14.
15.void CCEGLViewProtocol::setDesignResolutionSize(float width, float height, ResolutionPolicy resolutionPolicy)
16.{
17. ...
18. ...
19. m_obDesignResolutionSize.setSize(width, height);
20.
21. ...
22. ...
23. CCDirector::sharedDirector()->m_obWinSizeInPoints = getDesignResolutionSize();
24.}
25.
26.const CCSize& CCEGLViewProtocol::getDesignResolutionSize() const
27.{
28. return m_obDesignResolutionSize;
29.}
1.
具體的優(yōu)勢:通過設(shè)置邏輯分辨率大小,相比無模式,可以幫我們解決了屏幕自動(dòng)放大縮小問題,并且保持屏幕寬高比,使得游戲更好設(shè)計(jì),可以將設(shè)計(jì)畫面大小作為默認(rèn)背景圖片大小等,唯一點(diǎn)遺憾就是那點(diǎn)前面所提到的一點(diǎn)點(diǎn)犧牲。
kResolutionShowAll 方案可以作為我們的默認(rèn)解決方案,使得游戲的設(shè)計(jì)更為簡化,但為了補(bǔ)填拉伸或留黑邊這點(diǎn)缺憾,進(jìn)入下一個(gè)模式!
kResolutionNoBorder了解 VisibleSize 與 VisibleOrigin
此模式可以解決兩個(gè)問題,其一:游戲畫面全屏;其二:保持設(shè)置游戲時(shí)的寬高比例,相比 kResolutionShowAll 有所區(qū)別的是,為了填補(bǔ)留下的黑邊,將畫面稍微放大,以至于能夠正好補(bǔ)齊黑邊,而這樣做的后果可想而知,補(bǔ)齊黑邊的同時(shí),另一個(gè)方向上將會有一部分畫面露出屏幕之外,如下示意圖:
Cocos2D-X屏幕適配新解
黑色邊框標(biāo)示實(shí)際的屏幕分辨率,紫色區(qū)域標(biāo)示游戲設(shè)計(jì)大小,而通過放大縮小,保持寬高比固定, 可以看到 Show All 之中的黑色陰影部分為留邊,而 No Border 的紫色陰影部分則不能顯示,而這紫色區(qū)域的大小是游戲設(shè)計(jì)之時(shí)是不可控的。那么原設(shè)計(jì)的畫面大小就失去了 一定的 參考價(jià)值了,因?yàn)檫@可能讓你的畫面顯示殘缺。這時(shí)僅僅通過 WinSize 滿足不了我們的設(shè)計(jì)需求,所以引入了 VisibleSize 與 VisibleOrigin 概念。
Cocos2D-X屏幕適配新解
如上所示,紫色區(qū)域是被屏幕截去的部分,不可顯示的,根據(jù)實(shí)際情況,可能出現(xiàn)橫向截取和豎向截取,這取決于實(shí)際分辨率的寬高比。而 A、B、C、D所標(biāo)示的是設(shè)計(jì)分辨率,固定大小。如果我們想讓一個(gè)精靈元素顯示在屏幕上方靠邊,那么如果使用 WinSize 的高度設(shè)置其位置,可能出現(xiàn)的情況就是顯示到屏幕之外了。FrameSize 和 WinSize 我們已經(jīng)知道其概念,而 VisibleSize 和 VisibleOrigin 所代表的是什么呢,又時(shí)如何為我們解決靠邊的問題!注意上圖下方的定義, VisibleSize = H I J K 是用紫色標(biāo)注的。 而在上圖是 黑色 標(biāo)注,標(biāo)示屏幕實(shí)際分辨率,雖然 FrameSize 和 VisibleSize 都是 H I J K,但其意義不同,紫色表明它是與設(shè)計(jì)分辨率相關(guān)的。
FrameSize 是實(shí)際的屏幕分辨率,而 VisibleSize 是在 WinSize 之內(nèi),保持 FrameSize 的寬高比所能占用的最大區(qū)域,實(shí)際屏幕分辨率 H I J K (黑色) 可以大于 WinSize ,但VisibleSize 一定會小于或者等于 WinSize,這兩者相同的是寬高比。
VisibleSize 有著 WinSize 大小(隨WinSize 的大小改變而改變),還有著 FrameSize 的寬高比,它標(biāo)示 在設(shè)計(jì)分辨率(WinSize)下,在屏幕中的可見區(qū)域大小。 而 VisibleOrigin 則標(biāo)示在設(shè)計(jì)分辨率下被截取的區(qū)域大小,用點(diǎn) K 標(biāo)示,有了這些數(shù)據(jù),我們想讓游戲元素始終在屏幕顯示的區(qū)域之內(nèi)不成難事。下面通過幾個(gè)數(shù)值帶入,加深這些概念的印象。
1.// 組[1] :
2.FrameSize: width = 720, height = 420
3.WinSize: width = 720, height = 480
4.VisibleSize: width = 720, height = 420
5.VisibleOrigin: x = 0, y = 30
6.
7.// 組[2] :相比 組 [1] FrameSize 不變 VisibleSize 和 VisibleOrigin 隨著 WinSize 的變小而變小
8.FrameSize: width = 720, height = 420
9.WinSize: width = 480, height = 320
10.VisibleSize: width = 480, height = 280
11.VisibleOrigin: x = 0, y = 20
12.
13.// 組[3] : 相比組 [1] WinSize 不變,VisibleSize 隨著 FrameSize 的比例改變而改變
14.FrameSize: width = 720, height = 540
15.WinSize: width = 720, height = 480
16.VisibleSize: width = 640, height = 480
17.VisibleOrigin: x = 40, y = 0
18.
19.// WinSize VisibleSize VisibleOrigin 與都設(shè)計(jì)的分辨率相關(guān),滿足如下關(guān)系
20.WinSize.width = (VisibleOrigin.x * 2) + VisibleSize.width
21.WinSize.height = (VisibleOrigin.y * 2) + VisibleSize.height
1.
NoBorder 具體的使用方法可以參考 Cocos2D-X 自帶例程 TestCpp ,有詳細(xì)的使用方法,并且封裝了 VisibleRect 類,可以獲取設(shè)計(jì)分辨率,不同比例屏幕之時(shí)的主要參考點(diǎn),屏幕四個(gè)拐角,和邊的中點(diǎn)等,讓我們設(shè)置元素位置時(shí),使其總能顯示在屏幕之內(nèi),這里就不詳細(xì)介紹了。
基于這幾種模式的程序使用方法, Cocos2D-X 自帶例程或者網(wǎng)上有很多教程,這里只詳細(xì)解釋了其中各種概念,而知道了這些概念,當(dāng)然用起來就沒有多大問題了。
kResolutionLeafsoar
?。。∵@是什么模式!好吧,Leafsoar 是 一葉 的 ID ,或者是本博客的一級域名而已 :P 在 cocos2d-x 中并沒有這種模式。除卻 UnKnown ExactFit 不說,ShowAll 的優(yōu)勢是,只需要一個(gè)設(shè)計(jì)分辨率,然后通過 WinSize 設(shè)置相對對位即可,而且位置的最大長寬都是確定,方便了開發(fā),但屏幕不能填滿, NoBorder 模式的優(yōu)勢是在畫面不變形的情況下,實(shí)現(xiàn)全屏,顯示效果更好,但 WinSize 一定程度失效,需要通過運(yùn)行時(shí)計(jì)算 VisibleSize 和 VisibleOrigin 來設(shè)置位置,由于是運(yùn)行時(shí)計(jì)算,所以也就會出現(xiàn),各種屏幕顯示效果不一樣的情況。
ShowAll 和 NoBorder 各有所長,各有所短,而這里提出的新適配解決方案正是取兩者之長,舍兩者之短的組合模式。簡單說來就是用 NoBorder 去實(shí)現(xiàn) ShowAll 的思想。NoBorder 可以保證全屏利用,ShowAll 可以更好的使用實(shí)際設(shè)計(jì)坐標(biāo)固定位置,而且相對位置不會隨寬高比的改變而改變,這在編寫游戲的時(shí)候能方便不少。先上一個(gè)示意圖,一目了然 (兩個(gè)圖,兩個(gè)方向):
Cocos2D-X屏幕適配新解
在原來 NoBorder 模式示意圖上添加了新的概念,LsSize = X Y M N (leafsoar 簡寫了,為了不跟 Cocos2D-X 的一些概念混淆,什么名字不重要,只要了解其含義即可),在 NoBorder 模式下的 LsSize 相對于 FrameSize 而言,正如 在 ShowAll 模式下的 WinSize 相對于 FrameSize,所以說這是 ShowAll NoBorder 的組合概念,而這里的 LsSize 與 WinSize 的寬高比是一致的
猛地一看,似乎把問題復(fù)雜化了,仔細(xì)一看,還不如猛地一看 ~~
在 ShowAll 中,WinSize 作為最高的寬高,以此參照設(shè)置位置,因?yàn)樵诖朔秶鷥?nèi)都能在屏幕上顯示,用了 NoBorder 使得四周可能被截去一塊區(qū)域,而這個(gè)區(qū)域大小不可控制,所以不能再使用 WinSize 作為參考點(diǎn)來設(shè)置位置,而這里的 LsSize 同樣,因?yàn)?LsSzie 不論在什么情況下,總能顯示在屏幕之內(nèi),我們可以方便的使用 LsSize 作為坐標(biāo)系參考,并且可以全屏顯示,在配合 VisibleSize ,相比純的 NoBorder 加強(qiáng)了不少。它可以怎么用?
可以把 LsSize 當(dāng)作 ShowAll 中的 WinSize 來用,而黑邊可以使用稍大的圖片填充,或者使用其它圖片修飾邊框,修飾的邊框圖案可大可小,可長可短,填充屏幕,保持全屏。
開始基于 LsSize 的游戲設(shè)計(jì)實(shí)現(xiàn)
為了能夠準(zhǔn)確實(shí)現(xiàn)基于 LsSize 的設(shè)計(jì),初步計(jì)劃將 LsSize 設(shè)定在 480×320 的分辨率方案,為此做了些準(zhǔn)備,首先不使用任何模式情況下,在場景內(nèi)調(diào)用如下:
1.CCSize size = CCDirector::sharedDirector()->getWinSize();
2.
3.CCPoint center = ccp(size.width/2, size.height/2);
4.
5.// 大小 600x500 為了 NoBorder 看到效果,使用稍大的背景圖
6.CCSprite* pb = CCSprite::create("Back.jpg");
7.pb->setPosition(center);
8.this->addChild(pb, 0);
9.
10.// 480x320 此圖為使用于設(shè)計(jì)分辨率 LsSize 的圖片
11.CCSprite* pSprite = CCSprite::create("HelloWorld.png");
12.pSprite->setPosition(center);
13.this->addChild(pSprite, 0);
14.
15.// 37x37 在 480x320 畫面的四個(gè)拐角處,添加參照
16.CCSprite* p1 = CCSprite::create("Peas.png");
17.p1->setPosition(ccpAdd(center, ccp(-240, -160)));
18.this->addChild(p1);
19.
20.CCSprite* p2 = CCSprite::create("Peas.png");
21.p2->setPosition(ccpAdd(center, ccp(240, 160)));
22.this->addChild(p2);
23.
24.CCSprite* p3 = CCSprite::create("Peas.png");
25.p3->setPosition(ccpAdd(center, ccp(-240, 160)));
26.this->addChild(p3);
27.
28.CCSprite* p4 = CCSprite::create("Peas.png");
29.p4->setPosition(ccpAdd(center, ccp(240, -160)));
30.this->addChild(p4);
1.
顯示效果:(FrameSize = 640×540)
Cocos2D-X屏幕適配新解
顯示效果:(ShowAll; FrameSize = 520×320; WinSize = 480×320)
Cocos2D-X屏幕適配新解
顯示效果:(NoBorder; FrameSize = 520×320; WinSize = 480×320)
Cocos2D-X屏幕適配新解
通過效果我們可以看到,在相同 FrameSize 下 NoBorder 時(shí),畫面由于填充了黑邊,將畫面放大,以至于上下有部分顯示不全,通過拐角四個(gè)精靈可以看出。
好!既然我們知道是由于放大所致,那么我們將畫面縮小呢?cocos2d-x 提供了一個(gè)方法,我們調(diào)用如下代碼:
1.CCDirector *pDirector = CCDirector::sharedDirector();
2.pDirector->setContentScaleFactor(
3. CCEGLView::sharedOpenGLView()->getScaleY() );
為了彌補(bǔ)畫面因需要不填空白出現(xiàn)的方法,我們將畫面縮小,放大系數(shù)可以通過 CCEGLView::sharedOpenGLView()->getScaleY() 取得。其實(shí) setContentScaleFactor 方法是為了適配不同資源而設(shè)計(jì)的,可以用此方法對不同資源適配,縮放等。效果如下:
Cocos2D-X屏幕適配新解
我們看到 480×320 的圖片顯示完全正確了,也正是我們想要的效果,但唯一的缺點(diǎn)是 ~~ 拐角處四個(gè)精靈的位置依然不是我們想要的,我們設(shè)計(jì)的位置是以 480×320 設(shè)置位置的,而 WinSize 也是 480×320 ,而此時(shí)基于 480×320 的設(shè)計(jì)必然會顯示到屏幕之外,而要想不修改精靈位置,而讓其顯示正確的位置,那么為了保證 LsSize 的固定,我們需要一個(gè)方法,那就是動(dòng)態(tài)設(shè)置 WinSize。
什么意思?我們知道一般這些模式設(shè)計(jì)游戲時(shí),是通過 setDesignResolutionSize 設(shè)置 WinSize 的,這個(gè)值在游戲運(yùn)行其間是定植,動(dòng)態(tài)改變的是 VisibleSize 等,而這里提出了 LsSize 的概念,可想而知,如果 WinSize 固定,那么 LsSize 會隨著屏幕寬高比的改變而改變,那么我們反其道而行,固定 LsSize 值,那么在運(yùn)行時(shí)可以通過實(shí)際的寬高比來算得 WinSize 的值,這樣動(dòng)態(tài)算得的 WinSize 值就能夠保證我們的 LsSize 是一個(gè)定值了。
相對論,WinSize 與 LsSize 的值是相對的,與其通過固定 WinSize 在運(yùn)行時(shí)動(dòng)態(tài)獲得 LsSize (這也是 NoBorder 的默認(rèn)方式,而導(dǎo)致的結(jié)果是 WinSize 沒有參考價(jià)值),不如我們固定 LsSize 而在運(yùn)行時(shí)算得 WinSize 設(shè)置來的要更妙一些。
現(xiàn)在不使用 setContentScaleFactor 方法,而修改 setDesignResolutionSize 這里的值,我們知道 WinSize 是 480×320 時(shí),LsSize 必然會小于此值,而 NoBorder 的放大系數(shù)我們可以通過如下方式算得(可以參考setDesignResolutionSize方法內(nèi)部實(shí)現(xiàn)),并在 AppDelegate 里執(zhí)行:
1.CCSize frameSize = CCEGLView::sharedOpenGLView()->getFrameSize();
2.// 設(shè)置 LsSize 固定值
3.CCSize lsSize = CCSizeMake(480, 320);
4.
5.float scaleX = (float) frameSize.width / lsSize.width;
6.float scaleY = (float) frameSize.height / lsSize.height;
7.
8.// 定義 scale 變量
9.float scale = 0.0f; // MAX(scaleX, scaleY);
10.if (scaleX > scaleY) {
11. // 如果是 X 方向偏大,那么 scaleX 需要除以一個(gè)放大系數(shù),放大系數(shù)可以由樅方向獲取,
12. // 因?yàn)榇藭r(shí) FrameSize 和 LsSize 的上下邊是重疊的
13. scale = scaleX / (frameSize.height / (float) lsSize.height);
14.} else {
15. scale = scaleY / (frameSize.width / (float) lsSize.width);
16.}
17.
18.CCLog("x: %f; y: %f; scale: %f", scaleX, scaleY, scale);
19.
20.// 根據(jù) LsSize 和屏幕寬高比動(dòng)態(tài)設(shè)定 WinSize
21.CCEGLView::sharedOpenGLView()->setDesignResolutionSize(lsSize.width * scale,
22. lsSize.height * scale, kResolutionNoBorder);
1.
顯示效果:(NoBorder 模式 ;FrameSize = 520×320; LsSize = 480×320; WinSize = 動(dòng)態(tài)獲?。?
Cocos2D-X屏幕適配新解
我們看到在沒有修改源代碼,并且在設(shè)計(jì)中使用 480×320 的參考系,也既是基于 LsSize 的設(shè)計(jì)顯示效果如我們預(yù)期,那么我們換一個(gè) FrameSize 來看看是否能夠自動(dòng)適應(yīng)呢?如下:
顯示效果:(NoBorder 模式 ;FrameSize = 600×480; LsSize = 480×320; WinSize = 動(dòng)態(tài)獲?。?
Cocos2D-X屏幕適配新解
到此,基于 LsSize 參考系的游戲設(shè)計(jì)已經(jīng)完成了,這樣做的好處是很明顯的,集 ShowAll 和 NoBorder 的優(yōu)點(diǎn)于一處,這里的圖片元素是為了好定位,實(shí)現(xiàn)的需要而寫的,具體場景可以使用背景地圖,或一張大的圖片顯示,而沒有任何影響,也可以繼續(xù)使用 VisibleSize 得到 LsSize 之外的部分區(qū)域大小,在 LsSize 之外可以使用背景圖片作為裝飾,即保證了游戲的全屏,又保證了游戲設(shè)計(jì)時(shí)的方便,如果使用完全基于 LsSize 的設(shè)計(jì)實(shí)現(xiàn),除了顯示背景裝飾之外,我們不想讓 LsSize 的內(nèi)部元素顯示到 LsSize 之外如何做呢?我們只需要設(shè)定 LsSize 層的的顯示區(qū)域即可,我們可以修改場景的實(shí)現(xiàn):
1.// 這里先簡單實(shí)現(xiàn)思路
2.
3.CCScene* HelloWorld::scene() {
4.
5. CCScene *scene = CCScene::create();
6. // 創(chuàng)建背景層
7. CCLayer* b = CCLayer::create();
8. scene->addChild(b);
9.
10. // 添加背景圖片和設(shè)置位置,可以使用其它裝飾,或者小圖片屏幕都行
11. CCSize size = CCDirector::sharedDirector()->getWinSize();
12. CCPoint center = ccp(size.width/2, size.height/2);
13. CCSprite* pb = CCSprite::create("Back.jpg");
14. pb->setPosition(center);
15. b->addChild(pb, 0);
16.
17. // 創(chuàng)建 LsLayer 層
18. HelloWorld *lsLayer = HelloWorld::create();
19. scene->addChild(lsLayer);
20.
21. return scene;
22.}
23.
24.// 在 HelloWorld 中重寫 visit() 函數(shù) 設(shè)定顯示區(qū)域
25.void HelloWorld::visit() {
26. glEnable(GL_SCISSOR_TEST); // 開啟顯示指定區(qū)域
27. // 在這里只寫上固定值,在特性環(huán)境下,以便快速看效果,實(shí)際的值,需要根據(jù)實(shí)際情況算得
28. glScissor(20, 0, 480, 320); // 只顯示當(dāng)前窗口的區(qū)域
29. CCLayer::visit(); // 調(diào)用下面的方法
30. glDisable(GL_SCISSOR_TEST); // 禁用
31.}
1.
顯示效果:(NoBorder 模式 ;FrameSize = 520×320; LsSize = 480×320; WinSize = 動(dòng)態(tài)獲?。?/div>
Cocos2D-X屏幕適配新解
屏幕適配新解
看完這篇文章想必對Cocos2D-X的屏幕適配方案及其原理有了相當(dāng)?shù)恼J(rèn)識,從內(nèi)部提供的三種模式,再到我們自定義基于 LsSize 的 Leafsoar 模式 (好吧,因該叫做 ShowAllNoBorder)。這里已經(jīng)給出了完全的實(shí)現(xiàn)原理以及實(shí)現(xiàn)方法,并配有效果圖,當(dāng)然這其中還有些細(xì)節(jié)需要注意,比如我們基于 LsSize 的大小設(shè)計(jì),那么實(shí)際的圖片肯定需要比 LsSize 的要大,大多少,太小了不夠適應(yīng),太大了又浪費(fèi),如何取舍等問題,這一點(diǎn)取決的因素是什么,留給讀者思考。
一葉將在 GitHub 處建立一個(gè)ScreenSolutions 項(xiàng)目,讀者可以從這里參考實(shí)現(xiàn)的方案。(也許此時(shí)在 GitHub 所看到的實(shí)現(xiàn)并不完全,但已經(jīng)有了簡單的實(shí)現(xiàn)方法,并且能夠運(yùn)行,如有必要,將會新寫一篇博客,去實(shí)現(xiàn) ScreenSolutions 并且解說)。


向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI