支援大螢幕大小調整功能

從手機到各種大螢幕板型規格,將介紹遊戲處理視窗管理作業的方式。在 ChromeOSGoogle Play 遊戲電腦版中,遊戲可在主要電腦介面上以視窗模式執行。在搭載 Android 12L (API 級別 32) 以上版本的全新 Android 平板電腦和折疊式裝置上,遊戲可以透過分割畫面模式與其他應用程式並排執行、調整其大小,甚至可以在折疊式裝置的內外螢幕之間移動,進而導致視窗大小設定變更。

基本大螢幕設定

宣告遊戲是否能處理大小調整功能:

<android:resizeableActivity="true" or "false" />

如果無法支援調整大小功能,請確保遊戲資訊清單明確定義支援的最小和最大顯示比例:

<!-- Render full screen between 3:2 and 21:9 aspect ratio -->
<!-- Let the platform letterbox otherwise -->
<activity android:minAspectRatio="1.5">
<activity android:maxAspectRatio="2.33">

Google Play 遊戲電腦版

在 Google Play 遊戲電腦版中,平台會依照指定的顯示比例處理視窗大小調整作業。視窗大小會自動鎖定為最佳尺寸。如果遊戲的主要螢幕方向為橫向,顯示比例為 9:16,如果遊戲為直向模式,則須支援至少 16:9 的顯示比例。為獲得最佳體驗,對於橫向遊戲,請明確支援 21:9、16:10 和 3:2 的顯示比例。雖然這裡不必調整視窗大小,但還是適合與其他板型規格相容。

如需詳細資訊和最佳做法,請參閱「設定 Google Play 遊戲電腦版的圖形」。

ChromeOS 和 Android 大螢幕

如要在 ChromeOS 和大螢幕 Android 裝置上,最大化遊戲的可視區域,請支援全螢幕沉浸模式,並透過 decorView 設定旗標、系統 UI 顯示設定或 WindowInsetsCompat API,藉此隱藏系統資訊列。此外,建議您妥善處理旋轉和調整設定事件,或避免 ChromeOS 裝置發生上述事件。

請注意,在大螢幕 Android 裝置上,遊戲可以在尚未處理的設定中執行。如果遊戲不支援所有視窗大小和方向設定,平台會在相容模式中為遊戲加上黑邊,並視需要提示玩家,然後變更為不支援的設定。

圖 1. 設定相容性對話方塊。

在某些裝置上,當玩家進入不支援的設定時,系統可能會提示玩家選擇重新載入遊戲,並配合新的視窗版面配置重新建立活動,以免干擾遊戲體驗。以各種多視窗模式設定測試遊戲 (2/3、1/2、1/3 視窗大小),確認遊戲過程或 UI 元素不會遭到截斷或無法存取。此外,請測試遊戲在折疊式裝置的內側和外部螢幕之間移動時,會如何回應折疊式裝置連續性。如果遇到問題,請明確處理這些設定事件,並新增進階的大螢幕大小調整支援。

進階大螢幕大小調整功能

圖 2. 桌面型態和摺疊式裝置上的不同使用者介面。

如要退出相容模式,並避免活動重建,請按照下列步驟操作:

  1. 將主要活動宣告為可調整大小:

    <android:resizeableActivity="true" />
    
  2. 在遊戲資訊清單 <activity> 元素的 android:configChanges 屬性中,宣告「orientation」、「screenSize」、「smallestScreenSize」、「screenLayout」和「density」的明確支援,以便接收所有大螢幕設定事件

    <android:configChanges="screenSize | smallestScreenSize | screenLayout | orientation | keyboard |
                            keyboardHidden | density" />
    
  3. 覆寫 onConfigurationChanged() 並處理設定事件,包括目前的螢幕方向、視窗大小、寬度和高度:

    Kotlin

    override fun onConfigurationChanged(newConfig: Configuration) {
       super.onConfigurationChanged(newConfig)
       val density: Float = resources.displayMetrics.density
       val newScreenWidthPixels =
    (newConfig.screenWidthDp * density).toInt()
       val newScreenHeightPixels =
    (newConfig.screenHeightDp * density).toInt()
    
       // Configuration.ORIENTATION_PORTRAIT or ORIENTATION_LANDSCAPE
       val newScreenOrientation: Int = newConfig.orientation
    
       // ROTATION_0, ROTATION_90, ROTATION_180, or ROTATION_270
       val newScreenRotation: Int =
    windowManager.defaultDisplay.rotation
    }
    

    Java

    @Override
    public void onConfigurationChanged(Configuration newConfig) {
       super.onConfigurationChanged(newConfig);
       float density = getResources().getDisplayMetrics().density;
       int newScreenWidthPixels = (int) (newConfig.screenWidthDp * density);
       int newScreenHeightPixels = (int) (newConfig.screenHeightDp * density);
    
       // Configuration.ORIENTATION_PORTRAIT or ORIENTATION_LANDSCAPE
       int newScreenOrientation = newConfig.orientation;
    
       // ROTATION_0, ROTATION_90, ROTATION_180, or ROTATION_270
       int newScreenRotation = getWindowManager().getDefaultDisplay()
               .getRotation();
    }
    

您也可以查詢 WindowManager,檢查目前的裝置旋轉情形。使用這些中繼資料,檢查新的視窗尺寸,並顯示為完整的視窗大小。由於顯示比例差異,這項功能可能無法在所有情況下正常運作,因此,請將遊戲 UI 固定在新的視窗大小,並加上黑邊,讓核心遊戲內容出現上下黑邊。如因技術或設計上的限製而無法採用上述任一做法,請自行產生引擎黑邊來保持顯示比例,並在宣告 resizeableActivity = false 並避免設定模式時,根據可能的尺寸進行調整。

無論採取哪種做法,請以各種設定來測試遊戲 (折疊和展開、不同的旋轉變更、分割畫面模式),確保遊戲中的 UI 元素不會遭到截斷或重疊、觸控目標無障礙功能相關問題或顯示比例問題不會導致遊戲畫面拉長、縮放或變形。

此外,較大的螢幕通常表示像素較大,因為針對較大的區域具有相同的像素數量。進而導致縮小版轉譯緩衝區或解析度較低的資產產生像素化。在大螢幕裝置上使用最高品質的素材資源,並對遊戲進行效能設定檔,確保沒有任何問題。如果遊戲支援多種品質等級,請確認遊戲適用於大螢幕裝置。

多視窗模式

多視窗模式可讓多個應用程式同時共用同一個畫面。多視窗模式不會變更活動生命週期;不過,多個視窗中應用程式的重新啟用狀態會因 Android 版本而異 (請參閱「多視窗模式支援」中的多視窗模式活動生命週期相關說明)。

當玩家將應用程式或遊戲設為多視窗模式時,系統會通知活動設定變更,詳情請參閱「進階大螢幕大小調整」一節。如果玩家調整遊戲大小或將遊戲重新進入全螢幕模式,也會發生設定變更。

即使應用程式進入多視窗模式,也無法保證應用程式會重新取得焦點。因此,如果您使用任何應用程式狀態事件暫停遊戲,請勿仰賴取得焦點事件 (聚焦值為 true 的 onWindowFocusChanged()) 即可繼續遊戲。請改用其他事件處理常式或狀態變更處理常式,例如 onConfigurationChanged()onResume()。請注意,您隨時可以使用 isInMultiWindowMode() 方法偵測目前活動是否在多視窗模式下執行。

使用 ChromeOS 的多視窗模式時,初始視窗尺寸會成為重要考量因素。遊戲不一定要是全螢幕,而您可以宣告該情境的視窗大小。我們提供兩種建議做法。

第一個選項會使用 Android 資訊清單中 <layout> 標記的特定屬性運作。defaultHeightdefaultWidth 屬性可控制初始維度。此外,也要留意 minHeightminWidth 屬性,避免玩家將遊戲視窗調整為不支援的尺寸。最後,gravity 屬性決定了視窗啟動時在畫面上的顯示位置。以下是使用這些屬性的版面配置標記範例:

<layout android:defaultHeight="500dp"
        android:defaultWidth="600dp"
        android:gravity="top|end"
        android:minHeight="450dp"
        android:minWidth="300dp" />

第二個設定視窗大小的選項必須使用動態啟動邊界。您可以使用 setLaunchBounds(Rect)⁠⁠ 定義起始視窗維度。如果指定空矩形,活動就會以最大狀態啟動。

此外,如果您使用 Unity 或 Unreal 遊戲引擎,請務必使用最新版本 (Unity 2019.4.40 和 Unreal 5.3 以上版本),以便為多視窗模式提供良好支援。

支援折疊型態

使用 Jetpack WindowManager 版面配置程式庫支援折疊型態 (例如桌面),讓玩家更身歷其境:

圖 3. 採用桌面型態的遊戲,主要檢視畫面聚焦於螢幕的垂直部分,水平區塊。

Kotlin

fun isTableTopPosture(foldFeature : FoldingFeature?) : Boolean {
    contract { returns(true) implies (foldFeature != null) }
    return foldFeature?.state == FoldingFeature.State.HALF_OPENED &&
            foldFeature.orientation == FoldingFeature.Orientation.HORIZONTAL
}

Java

boolean isTableTopPosture(FoldingFeature foldFeature) {
    return (foldFeature != null) &&
           (foldFeature.getState() == FoldingFeature.State.HALF_OPENED) &&
           (foldFeature.getOrientation() == FoldingFeature.Orientation.HORIZONTAL);
}