cocos2d-x屏幕分辨率,窗口大小總結


這個東西很煩人,相信很多人都不理解

今天來總結一下,首先有很多概念都要事先弄得清楚明白

1.屏幕分辨率

所謂屏幕分辨率相信很多人都知道他的概念,不就是1280pxX720PX嗎?不就是這種形式嗎?有什么難的,這幾個詞在各種手機評測上面不是已經用爛了嗎?

可是很多人都沒有真正理解這個概念!!!

1280pxX720px

它的意思是縱向1280個像素,橫向720個像素。

記住!只是像素而已,和尺寸,和大小,和比例沒有半毛錢的直接關系

我一直都以為為什么這個東西要叫做屏幕分辨率,為什么要叫做分辨率?之前一直覺得名不符實,一直以為像素不過是另一種度量單位,深受我們攝影老師的影響,誤人子弟,現在想起來,真是naive!

記住,像素不是一種新的,類似cm,mm的單位,像素並不是一種計量長度的單位,至於他究竟是什么,對不起,無可奉告,自己看百度百科

可以知道的是:像素越密,清晰度越高

2.屏幕分辨率和屏幕尺寸

  先說說屏幕尺寸,這東西,才是我們直觀感受到的東西,什么屏幕的大小啊,屏幕的尺寸啊,屏幕的比例啊,一切的一切都落在這個屏幕尺寸上,

  接下來就是干貨了

  1.相同比例和大小的尺寸,屏幕上的像素分辨率越高,屏幕,越清晰!!!(這個足可以證明尺寸,大小和分辨率無關吧)

  2.同樣的屏幕分辨率(比如1280pxX720px),用在不同的屏幕上,我們看到的效果天差地別!!!

 

 

  接下來進入正題!在游戲中是怎么做的!!

  接觸過各種引擎或者直接做游戲的人應該都知道,在游戲中我們做游戲都是以像素作為單位的,比如,一張精靈的圖片,100pxX30px,怎樣處理呢?

  在windows平台是這樣的,因為windows平台是窗口式程序,一個游戲程序可以設置它的窗口大小,也就是說,他的屏幕尺寸並不是固定的!!

  這個時候是分為兩部分處理的:

      1.設置窗口的大小:長寬;這一步相當於人為地規定了屏幕的尺寸(以像素的形式)

      2.設置設計尺寸:根據各種手段,使精靈圖片適配窗口的大小

 

  而在移動端,包括安卓端和蘋果端:因為並不是窗口式的OS,事實上就那么點屏幕,也做不了窗口式的OS,所以屏幕並不可更改所以只有一個步驟:

      設置設計尺寸:根據各種手段,使屏幕適配窗口的大小

 

好,解決方案就是以上兩種思想,我來仔細解釋一下,我們知道,因為各種電腦,各種手機,尺寸都不一樣,分辨率也他媽不一樣,這對於開發者來說是一個很復雜的問題,你想想,不同的尺寸,市面上真是數不勝數,我們怎么辦呢?

好,開發者決定以像素為單位,進行開發,這個方法不錯,畢竟各種圖片,紋理,都是以像素為單位的

,可是相同的像素大小,也就是相同的分辨率,在不同平台上的尺寸都不一樣,比如說,同樣是960pxX720px,在這個手機上也許尺寸更大一些,那個手機上,也許尺寸更小一些?我們怎么緊緊跟隨尺寸呢?畢竟,尺寸和分辨率是兩回事啊!!

這個任務實際上是交給手機廠商的!!怎么樣?是不是有一種很爽的感覺!!,這就是產業鏈啊!!!以前總在知乎上看他們辯論產業鏈優勢,現在終於體會到了,對於廠商來說,分辨率就是寫上去的事兒,很簡單,可是解決了我們一個大麻煩,這樣,對於我們來說,從手機設備廠商上獲得的分辨率,就是尺寸啊!!!!  他在邏輯上並不是尺寸,但是這並不妨礙我們把他當作尺寸來看待!!!!

 

 

好了,有了以上的解釋,

  對於PC端:第一步設置窗口大小的時候,實際上可以認為我們是在認為設置安卓手機的大小尺寸,怎么樣,是不是有一種很吊的感覺!!!模仿手機端,我們是以像素來代替尺寸

  第二步的處理接下來在手機端一起講

  對於安卓端:

      第一步對於安卓端來說不用考慮。

      第二步:獲得固定的尺寸分辨率(自己發明的:即可以代表尺寸的分辨率):這一步對於開發者來說是透明的,也就是說,開發者這一步並不知道 具體的分辨率是多少,系統會自動給與

      記作ScreenX和ScreenY

      開發者自定義一個尺寸,我們稱之為設計尺寸,仍然以像素為單位,記作designX和designY

      scaleX=ScreenX/designX

      scaleY=ScreenY/designY

      然后就選擇適配方式:

        有鋪滿屏幕:那就用scaleXxdesignX,scaleYXdesignY來獲得實際的尺寸,注意在這個過程中,場景中的精靈等等都這樣變換,也就是說,游戲場景可能會變形得比較厲害

        有保持比例而且不超出屏幕:也就是保持比例不變形且不對素材進行裁剪:實現的時候是對選擇scaleX和scaleY中較小的一個作為縮放因子,對designX和designY進行縮放

        有保持比例而且不留空白:也就是保持比例不變形,且充分利用屏幕的每個空間:實現的時候是對選擇scaleX和scaleY中較大的一個作為縮放因子,對designX和designY進行縮放

        有保持比例且按照寬度鋪滿屏幕:也就是保持比例不變形,且讓寬度剛好鋪滿屏幕,實現的時候用scaleX作為縮放因子,對designX和designY進行縮放

        有保持比例且按照高度度鋪滿屏幕:也就是保持比例不變形,且讓寬度剛好鋪滿屏幕,實現的時候用scaleY作為縮放因子,對designX和designY進行縮放

 

 

總結一下,后四種其實是一種類似的思想,

 

 

終於把理論部分說完了,感覺上面講完了,cocos2d-x里面的也沒有什么講的了,cocos里面的思想和這個就是一樣的,

直接上函數

glview->setDesignResolutionSize(720,1280,ResolutionPolicy::SHOW_ALL);

  這個函數其實就是第二步驟的完整函數,這個前一部分指定我們設計游戲的時候用的尺寸分辨率,然后后面的就是適配風格了

怎么實現這種適配風格可以看看源碼

void GLView::setDesignResolutionSize(float width, float height, ResolutionPolicy resolutionPolicy)
{
    CCASSERT(resolutionPolicy != ResolutionPolicy::UNKNOWN, "should set resolutionPolicy");
    
    if (width == 0.0f || height == 0.0f)
    {
        return;
    }

    _designResolutionSize.setSize(width, height);
    _resolutionPolicy = resolutionPolicy;
    
    updateDesignResolutionSize();
 }

  這個是setDesignResolutionsize函數,可以看到,通過參數指定了私有成員_designResolutionSize的值,這個就是設計分辨率!!但是注意一下,opengl創建窗口的時候(請原諒我用窗口這個詞),並不是以設計尺寸分辨率創建的,

  可以看到,這個函數里只是指定了設計尺寸和適配風格,並沒有實現適配風格,可以猜一下,實現應該封裝在updateDesignResoltionSize里了,進去看看

void GLView::updateDesignResolutionSize()
{
    if (_screenSize.width > 0 && _screenSize.height > 0
        && _designResolutionSize.width > 0 && _designResolutionSize.height > 0)
    {
        _scaleX = (float)_screenSize.width / _designResolutionSize.width;
        _scaleY = (float)_screenSize.height / _designResolutionSize.height;
        
        if (_resolutionPolicy == ResolutionPolicy::NO_BORDER)
        {
            _scaleX = _scaleY = MAX(_scaleX, _scaleY);
        }
        
        else if (_resolutionPolicy == ResolutionPolicy::SHOW_ALL)
        {
            _scaleX = _scaleY = MIN(_scaleX, _scaleY);
        }
        
        else if ( _resolutionPolicy == ResolutionPolicy::FIXED_HEIGHT) {
            _scaleX = _scaleY;
            _designResolutionSize.width = ceilf(_screenSize.width/_scaleX);
        }
        
        else if ( _resolutionPolicy == ResolutionPolicy::FIXED_WIDTH) {
            _scaleY = _scaleX;
            _designResolutionSize.height = ceilf(_screenSize.height/_scaleY);
        }
        
        // calculate the rect of viewport
        float viewPortW = _designResolutionSize.width * _scaleX;
        float viewPortH = _designResolutionSize.height * _scaleY;
        
        _viewPortRect.setRect((_screenSize.width - viewPortW) / 2, (_screenSize.height - viewPortH) / 2, viewPortW, viewPortH);
        
        // reset director's member variables to fit visible rect
        auto director = Director::getInstance();
        director->_winSizeInPoints = getDesignResolutionSize();
        director->_isStatusLabelUpdated = true;
        director->setGLDefaultValues();
    }
}

  

 可以看到,這個里面實現了上面講的那些適配風格的適配方法

看到這里,我們應該大體能猜到,最終創建的窗口應該是那個叫做_viewPortRect的東西,好了,屏幕適配就寫到這里了,今天狀態不好,從今天起,決定戒掉小說,OK!

今天更新一下,主要是最近自己的項目中間出現一個非常麻煩的問題,今天終於解決了,關於觸摸響應位置不准確的問題,其實主要是windows平台上設置產生的窗口大小超過了PC的物理尺寸大小!!!

詳細的解釋見下面的鏈接

觸摸位置不准確

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM