天天看點

cocos2dx 多分辨率适配

文章原始位址:http://or7rccl.blog.163.com/blog/static/70836367201401314947502/

寫的很詳細,值得的

從Cocos2d-x 2.0.4開始,Cocos2d-x提出了自己的多分辨率支援方案,廢棄了之前的retina相關設定接口,提出了design resolution概念。

有以下相關接口:

  1. CCEGLView::sharedOpenGLView()->setDesignResolutionSize() //設計分辨率大小及模式
  2. CCDirector::sharedDirector()->setContentScaleFactor() //内容縮放因子
  3. CCFileUtils::sharedFileUtils()->setResourceDirectory() //deprecated
  4. CCFileUtils::sharedFileUtils()->setSearchPaths() //資源搜尋路徑
  5. CCEGLView::sharedOpenGLView()->getFrameSize() //螢幕分辨率
  6. CCDirector::sharedDirector()->getWinSize() //設計分辨率
  7. CCDirector::sharedDirector()->getVisibleSize() //設計分辨率可視區域大小
  8. CCDirector::sharedDirector()->getVisibleOrigin() //設計分辨率可視區域起點

從cocos2d-2.1beta3-x-2.1.1開始,

CCFileUtils::sharedFileUtils()->setResourceDirectory()

被新接口

CCFileUtils::sharedFileUtils()->setSearchPaths(searchPath)

替代

從Cocos2d-x 2.1.3開始,新加入了兩種ResolutionPolicy(kResolutionFixedHeight, kResolutionFixedWidth),共5中模式。

官方分别在Multi_resolution_support 和 Mechanism_of_loading_resources有介紹。

本文從引擎使用者角度分析Cocos2d-x的多分辨率适配技術。

從Retina 到 design resolution

在Cocos2d-x 2.0.4之前,有Retina的概念,這個是從cocos2d-iphone過來的概念。

cocos2d-iphone為了支援Retina iphone 裝置,使用了-hd等字尾來區分iphone和Retine iphone的圖檔資源。在設計遊戲的時候,使用point 坐标系,而非真正的pixel坐标系。這點和iOS native應用開發提出的point概念一至,不用修改代碼,就能在640×960的裝置上跑之前320×480的程式,隻是圖檔會看起來模糊,一旦加入@2x的圖檔,iOS自動加載@2x的圖檔,實作對Retna iphone的支援。

point坐标系,在一定範圍内能解決多分辨率支援的問題。但是當iphone5,ipad 3出來以後,iOS總共有5個分辨率需要支援,如果做一個universal的程式,是相當痛苦的。point坐标系并不能完全解決問題,android上的分辨率情況更加複雜。

design resolution應該是從point坐标系進化過來的概念,目的是屏蔽裝置分辨率,精靈坐标都在design resolution上布局,但要實作這個目标并不簡單。Cocos2d-x提供了一組相關的接口和5種分辨率适配政策,哪種政策才是我們需要的,下面我們一同探尋。

資源分辨率,設計分辨率,螢幕分辨率

Resources width 以下簡寫為RW,Resources height 以下簡寫為RH

Design width 以下簡寫為DW,Design height 以下簡寫為DH

Screen width 以下簡寫為SW,Screen height 以下簡寫為SH

在SDK的samples中有個HelloCpp項目。展示了如何使用多分辨率方案。

以下以HelloCpp的AppMacros.h配置基本相同,但是交換了寬高的數值,以豎屏遊戲為例子。

Cocos2d-x圖檔顯示有下面兩個邏輯過程。

資源布局到 到 設計分辨率,設計分辨率 布局到 螢幕。

如下圖所示:

cocos2dx 多分辨率适配

接口setContentScaleFactor()和setSearchPaths()控制着第一個轉換過程。

而setDesignResolutionSize()控制第二個過程。兩個過程結合在一起,影響最終的顯示效果。

從資源分辨率到設計分辨率

setSearchPaths()需要根據目前螢幕分辨率做恰當的設定,HelloCpp展示了一套簡單方案,但可能不是最佳的。

setContentScaleFactor()決定了圖檔顯示到螢幕的縮放因子,但是這個接口的參數不是通過資源圖檔的寬、高比螢幕寬、高得來。Cocos2d-x引擎設計試圖屏蔽遊戲開發者直接去關注螢幕,是以這個因子是資源寬、高比設計分辨率寬、高。

setContentScaleFactor()通常有兩個方式來設定參數。

RH/DH或RW/DW,不同的因子選擇有不同的縮放負作用。

先看一張圖:

cocos2dx 多分辨率适配

用高度比作為内容縮放因子,保證了背景資源的垂直方向在設計分辨率範圍内的全部顯示。

用寬度比作為内容縮放因子,保證了背景資源的水準方向在設計分辨率範圍内的全部顯示。

從設計分辨率到螢幕分辨率

setDesignResolutionSize(DW, DH, resolutionPolicy)

有三個參數,設計分辨率寬,設計分辨率高,分辨率政策。

前兩個很好了解,複雜點在分辨率政策的選擇上。

先來看kResolutionExactFit,kResolutionNoBorder,kResolutionShowAll這三種情況,2.1.3新加入的政策稍後分析。

三種政策的設計分辨率都是傳入值,内部不做修正。

先看一張圖:

cocos2dx 多分辨率适配

kResolutionShowAll

螢幕寬、高分别和設計分辨率寬、高計算縮放因子,取較(小)者作為寬、高的縮放因子。保證了設計區域全部顯示到螢幕上,但可能會有黑邊。

kResolutionExactFit

螢幕寬 與 設計寬比 作為X方向的縮放因子,螢幕高 與 設計高比 作為Y方向的縮放因子。保證了設計區域完全鋪滿螢幕,但是可能會出現圖像拉伸。

kResolutionNoBorder

螢幕寬、高分别和設計分辨率寬、高計算縮放因子,取較(大)者作為寬、高的縮放因子。保證了設計區域總能一個方向上鋪滿螢幕,而另一個方向一般會超出螢幕區域。

kResolutionNoBorder是之前官方推薦使用的方案,他沒有拉伸圖像,同時在一個方向上撐滿了螢幕,但是2.1.3新加入的兩種政策将撼動kResolutionNoBorder的地位。

kResolutionFixedHeight和kResolutionFixedWidth都是會在内部修正傳入設計分辨率,以保證螢幕分辨率到設計分辨率無拉伸鋪滿螢幕。

如圖:

cocos2dx 多分辨率适配

kResolutionFixedHeight

保持傳入的設計分辨率高度不變,根據螢幕分辨率修正設計分辨率的寬度。

kResolutionFixedWidth

保持傳入的設計分辨率寬度不變,根據螢幕分辨率修正設計分辨率的高度。

結合兩個過程

第一過程有兩種情況,第二過程有5種情況,在一個分辨率下會有10種可能的方案組合。

如何選擇自己需要的?

我們需要作出選擇,是犧牲效果還是犧牲部分顯示區域。

這裡我們選者犧牲一個方向的顯示區域為例,結果說明兩個過程。

在我的遊戲裡面,背景圖的高需要全部顯示,而寬方向可以裁減。

要實作這個目的,需要保證兩個過程都是在寬方向裁減。

  • 第一過程選擇 setContentScaleFactor(RH/DH)
  • 第二過程有兩個選擇:kResolutionNoBorder和kResolutionFixedHeight

為了說明兩者的差別,需要結合VisibleOrigin和VisibleSize。

看圖

cocos2dx 多分辨率适配

kResolutionNoBorder情況下,設計分辨率并不是可見區域,我們布局精靈需要根據VisibleOrigin和VisibleSize來做判斷處理。

而kResolutionFixedHeight則不同,設計分辨率就是可見區域,VisibleOrigin總是(0,0)

getVisibleSize() = getWinSize(),kResolutionFixedHeight達到了同樣的目的,但是卻簡化了代碼。

kResolutionFixedHeight和kResolutionFixedWidth是kResolutionNoBorder的進化,新項目中建議立即開始使用這兩種方式。

小結

kResolutionFixedHeight

适合高方向需要撐滿,寬方向可裁減的遊戲,結合setContentScaleFactor(RH/DH)使用。

kResolutionFixedWidth

适合寬方向需要撐滿,高方向可裁減的遊戲,結合setContentScaleFactor(RW/DW)使用。

tip:正确設定AppMacros.h裡面的寬高,注意橫屏遊戲和豎屏遊戲的不同。

繼續閱讀