大屏幕和摺疊屏: 讓您的 Android 遊戲登上更大的舞臺

做者 / Ben Gable, Partner Developer Advocatehtml

讓咱們繼續《讓您的應用適配更多屏幕》中的話題,不過今天會更專一於遊戲的範疇。在不久前的 GDC 上,咱們很高興能和你們分享多樣化的設備爲遊戲體驗帶來的可能性。這些年咱們親歷了諸多移動硬件的演進,如 3D 顯示器和高分辨率屏幕等,也由於這些演進,讓咱們在應用商店中看到愈來愈多新穎的遊戲出現,讓玩家們在更沉浸的畫面和遊戲體驗中流連忘返。android

若是能在更大的屏幕上體驗的話,這些遊戲也會擁有更好的視覺效果。這意味着開發者能夠經過針對不一樣的外形和更大的顯示設備優化遊戲,來吸引正在快速增加的大量受衆羣體。shell

若是您在應用商店上架了遊戲,那它可能已經能夠在 Chrome OS 上運行了。Chromebook 在一個容器中運行完整版的 Android 框架,所以遊戲的體驗就像在 Android 設備上運行同樣。但這並非終點,經過進行一些調整,開發者能夠進一步針對性地優化遊戲,使其在大屏幕設備上擁有最佳的視覺效果和運行性能,併爲可摺疊設備上的最佳遊戲體驗奠基基礎。bash

GDC 期間咱們的不少演講都涉及到了這個話題。這裏咱們爲您系統地整理了一遍,並給出了能讓您馬上上手的代碼示例和開發技巧。app

大屏幕遊戲的常見問題

做爲遊戲開發者,您固然想要在每臺設備上都提供最佳的遊戲體驗——不管用戶是在使用豎屏模式,仍是使用鍵鼠,甚至在可摺疊設備 (擁有更多可切換的分辨率和寬高比配置) 上進行遊戲。經過遵循 Android 最佳實踐,開發者能夠在全部這些使用場景中都提供出色的體驗。框架

在 APK 中,適配的全部操做都是從配置 (configuration) 的變更開始。系統在檢測到設備配置的變更後,會自動重啓您的 Activity 並在這個過程當中調用適配新設備配置的遊戲資源,從而確保您的遊戲在該配置下達到理想的效果。ide

在默認狀況下,系統將在從新啓動 Activity 以前經過調用 onSaveInstanceState 自動處理配置更改。但對於素材量很大的遊戲來講,這一過程可能須要更長的時間,尤爲是在涉及到狀態數據的序列化和反序列化時,可能會由於大量的內存消耗而出現遲滯現象,所以您可能須要本身對這一步操做進行鍼對性的改進,好比讓系統在特定的配置變化以後不重啓 Activity,而是調用 onConfigurationChanged 方法讓您自行處理適配細節:工具

public void onConfigurationChanged(Configuration newConfig) {
    //Scale UI
    //Toggle control scheme
    //Adjust orientation
    //etc
}
複製代碼

屏幕和窗口管理

在 Chromebook 和三星 DeX 等設備上,遊戲默認在窗口模式中啓動,用戶能夠動態調整畫面大小;在三星 Galaxy Fold 等設備上,當用戶展開設備時,屏幕尺寸和寬高比將會改變。這些設備配置變化的場景均可以觸發 onConfigurationChanged 事件。性能

您能夠在 manifest 中這樣指定須要監聽的配置變更項目:測試

<activity android:name=".MyActivity"
  android:configChanges="screenSize|orientation"
  android:label="@string/app_name">
複製代碼

正如前文所述,在遊戲運行時若是發生配置更改,默認狀況下系統會關閉 Activity 而後將其從新啓動,但若是您使用 android:configChanges 屬性聲明瞭須要監聽的配置,將會阻止 Activity 從新啓動。這時 Activity 反而會保持運行狀態,而且系統會調用其 onConfigurationChanged() 方法。如此一來,您就能夠定製化地處理任何變化了。例如,您能夠縮放 OpenGL 內容以匹配新的分辨率或寬高比,防止 UI 元素被畫面裁切。

好比當用戶動態調節畫面大小時:

public void onConfigurationChanged(Configuration newConfig) {
  //Get native surface size
  //NativeActivity.mLastContent[X/Y/Width/Height]()
  //findViewById(android.R.id.content).get[Width/Height]()
}
複製代碼

有一點須要牢記,那就是每次畫面尺寸發生變化時,輸入區域也會發生變化。若是您的遊戲打算保持全屏運行,或者您須要在修 bug 時快速略過配置更改問題,則只需在 manifest 中將 resizableActivity 設置爲 false 便可。這一操做將阻止用戶手動調整畫面大小,但它也會阻止分屏模式 (split-screen view),所以請謹慎使用,以免影響玩家體驗。

<activity android:name=".MyActivity"
  android:resizeableActivity="false"
  android:label="@string/app_name">
複製代碼

△ 將 resizableActivity 設置爲 false 能夠強制遊戲處於全屏模式

設備方向

在智能手機上,屏幕方向默認爲縱向 (豎屏)。而在其餘設備上,默認值則有多是橫向。請在 manifest 中指定您支持的傳感器方向,讓系統處理它們,從而確保您的遊戲不會意外翻轉。

<activity … android:screenOrientation=」...」>
複製代碼

或者,若是您打算在 onConfigurationChanged() 中動態處理方向,請在代碼中使用 Display.getRotation() 獲取當前屏幕方向。

Display.getRotation()
複製代碼

△ 屏幕方向的數值可能會在不一樣的設備上互換,具體取決於該硬件默認的設備方向值,請必定要在測試中考慮到這一點

設備分辨率

在解決了上面兩個問題後,您還須要考慮用戶設備的分辨率。較大的屏幕須要更高分辨率的素材資源,所以您可使用應用束 (App Bundle) 來爲不一樣的設備配置分割打包遊戲的代碼和資源。這樣,Google Play 就會爲遊戲所在的設備提供正確的資源——例如,爲較小屏幕的設備略去超高分辨率素材。這將爲用戶節省寶貴的下載空間,同時也免去了爲不一樣像素密度的屏幕維護多個 APK 的麻煩。

△ App Bundle 能夠針對不一樣配置或功能分割打包代碼和資源,使得 Play Store 能根據用戶的實際設備進行動態交付

另外,更多的屏幕像素也能夠爲畫面和界面設計賦予更大的靈活性。當用戶在更大的屏幕上玩遊戲時,他們可能會坐得離屏幕更遠,這時您須要考慮擴展、添加或更改畫面 / 界面元素,以確保屏幕上的全部內容都清晰可辨。

輸入設備

愈來愈多的手機遊戲開始爲玩家提供如同臺式機和主機通常的體驗。因此,愈來愈多的 Android 設備開始支持各類不一樣的輸入方式,包括鍵鼠和手柄等等。儘管 Android 提供了支持鍵盤、鼠標和手柄的 API,但想要這些額外的輸入方式真正可用,仍是須要遊戲開發者們更多地理解玩家的遊玩訴求。好比玩家可能在沒有觸摸屏的 Chromebook 上用鍵盤玩遊戲,或者打算插上鼠標來玩本身最喜歡的第一人稱射擊遊戲,這些時候若是玩家發現本身期待的操做方式沒有被遊戲支持,失望之情也就不難理解了。

另外,許多新設備也支持在使用時動態切換配置,例如從摺疊模式轉換到平板電腦模式。想要支持這些場景,最佳的方法是檢測設備上可用的硬件,以便爲玩家提供最佳體驗。

要作到這一點,仍是要從 android:configChanges 開始。例如檢測鍵盤的鏈接:

而後,您能夠在啓動時或在配置更改時查詢 InputManager,並根據觸摸屏或者鍵盤的可用與否來切換控制方案。另外,當從觸摸控制方案切換成鍵盤控制方案時, 即便 InputManager 說鍵盤可用,您也須要進一步確保鍵盤真的可用 (好比在畫面上提示用戶 "按任意鍵繼續")。畢竟,用戶這時用的多是一臺平板電腦模式下的 Chromebook。

△ 切換操做模式時,一個推薦的作法是暫停遊戲並讓用戶使用對應的輸入設備進行一次確認操做
若是您是在遊戲作完後纔打算支持鍵盤,請考慮實現下面的功能,這樣能夠大幅提升可用性和完成度:

  • 技能鍵綁定
  • WASD / 方向鍵移動
  • 菜單導航
  • Enter 鍵輸入
  • Tab 鍵切換 (依遊戲所需)
  • 上下翻頁鍵功能
  • 返回鍵
  • 自定義鍵位映射

還有,別忘記使用鼠標的玩家——特別是在第一人稱射擊遊戲或第三人稱遊戲裏。

public void onClick(View view) {
    view.requestPointerCapture();
}

public boolean onCapturedPointerEvent(MotionEvent motionEvent) {
  // Get the coordinates required by your app
  float verticalOffset = motionEvent.getY();
  float horizontalOffset = motionEvent.getX();
  return true;
}
//...
view.releasePointerCapture();
複製代碼

最後,考慮加入對手柄的支持,由於標準的 Android 手柄 API 適用於 Chromebook 和三星 DeX 等設備——這些都爲使用手柄提供了可能性。

構建

如今,讓咱們繼續構建和配置您的 APK,以確保它支持各類大屏幕 Android 設備。

第一步是檢查您的遊戲所要求的權限,以及肯定您是否真的須要這些權限。某些設備 (如 Chrome OS) 就不支持某些權限,例如:

  • android.hardware.location.gps—— GPS
  • android.hardware.nfc——近場通訊 (NFC)
  • android.hardware.camera——後置攝像頭

另外,請考慮運行遊戲的硬件配置,並考慮調整如下內容:

  • 自動畫質控制: 調整自動畫質控制邏輯或建立新的畫質配置,以便針對特定設備進行最佳優化。
  • x86 和 ARM: 嘗試提供 x86 版本,以便在 Chromebook 等設備上實現最佳性能。只有 ARM 版本的話遊戲仍然能夠運行,可是您會由於指令翻譯而產生額外的性能開銷。
  • 對 Vulkan 的支持: 大多數設備如今都支持 Vulkan,它能夠大大提升渲染速度和圖形表現。

最後一步是在全部大屏幕設備上測試。添加涵蓋不一樣設備的、更多樣遊玩流程的測試用例,例如最小化最大化、在小屏幕和大屏幕之間切換、變動輸入設備和調整窗口大小。您可使用 Android 和 Chrome OS 模擬器或 Firebase Test Lab 等工具來讓測試過程變得更加自動化。

您也可使用在 Android 設備和 Android Studio AVD 上運行的摺疊屏模擬器應用,來測試不一樣窗口大小和像素密度時的運行情況:

$ adb install FoldableEmulator.apk
$ adb shell pm grant com.samsung.android.foldable.emulator android.permission.WRITE_SECURE_SETTINGS
$ adb shell pm grant com.samsung.android.foldable.emulator android.permission.SYSTEM_ALERT_WINDOW
複製代碼

可摺疊設備

可摺疊智能手機經過將智能手機和平板電腦合二爲一,讓遊戲玩家能夠魚與熊掌兼得: 能夠作到多窗口操做,也可讓遊戲畫面的尺寸倍增。

爲 Chromebook 構建的應用在優化原則上和可摺疊設備高度相通。所以在完成前面的優化適配後,您只需考慮如下四個關鍵事項:

最大寬高比

支持全屏模式對於確保遊戲玩家得到最佳的沉浸式體驗相當重要。可摺疊設備在摺疊起來時畫面將擁有較長的寬高比 (可達 21:9),所以請執行如下步驟,以確保您的遊戲能夠處理最大寬高比,從而填充整個屏幕:

  • 聲明目標 SDK 版本: 以 Android 8.0 (API 級別 26) 或更高級別爲目標的遊戲能夠填滿整個屏幕。
  • 聲明 resizeableActivity (若是您的遊戲支持多窗口,則只聲明爲 "true"): android:resizeableActivity=[「true」 | 「false」]
  • 聲明最大寬高比: 可摺疊設備寬高比可達 21:9,這要求您將最大寬高比提升到 2.4。

您能夠按照以下示例在 manifest 中聲明最大寬高比:

<!-- Render on full screen up to aspect ratio of 2.4 -->
<!-- Use a letterbox on screens larger than 2.4 -->
<meta-data android:name="android.max_aspect" android:value="2.4" />
複製代碼

△ 設置最大寬高比爲 2.4,若是寬高比超過 2.4,則左右兩側會留空

處理屏幕凹口區域

以 Galaxy Fold 爲例,在展開狀態時,其屏幕的左上角會有一個凹口,您須要保證遊戲畫面中的必要內容不被遮擋。

若是您的遊戲在渲染時會覆蓋到凹口區域,可使用 WindowInsets.getDisplayCutout() 來得到 DisplayCutout 對象。這裏有三個值須要注意:

  1. LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT
  2. LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES
  3. LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER
  • MODE_DEFAULT: 內容在豎屏模式時會在凹口區域內渲染,但在橫屏模式下左右會留空。
  • MODE_SHORT_EDGES: 不論橫豎屏模式,內容都會在凹口區域內渲染。
  • MODE_NEVER: 內容永遠不會在凹口區域內渲染。

您能夠參考以下示例來給您的 Activity 設置凹口渲染模式:

<style name="ActivityTheme">
   <item name="android:windowLayoutInDisplayCutoutMode">
       shortEdges <!-- default, shortEdges, never -->
   </item>
</style>
複製代碼

△ 直接將 LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES 應用於 Activity

遊戲連續性

當用戶展開他們的設備時,您須要確保您的遊戲無縫過渡到全尺寸狀態。這意味着您的遊戲能夠適應兩種實體屏幕尺寸,對實體設備摺疊機制及其狀態做出正確響應,而且可以調整畫面大小。

  1. 確保您的遊戲能夠處理兩種屏幕尺寸,這個機制與在 Android 上適配不一樣屏幕尺寸的方法基本相同。惟一的區別是,這種狀況在可摺疊設備上會更頻繁地發生。
  1. 處理摺疊和展開,開發者不須要針對 Galaxy Fold 這樣的設備處理特殊事件或 API,由於這個過程就是 Android 平臺標準的屏幕尺寸變化事件。更具體到 Activity 的 configChanges 上,會觸發這麼幾個變化: Screensize、smallestScreenSize、ScreenLayout。
  1. 讓遊戲畫面尺寸實現自適應,以在不一樣顯示模式之間靈活切換,從而讓用戶在摺疊和展開屏幕時都能體驗到無縫的切換過程。

多重恢復

正如咱們以前在適配可摺疊設備的話題中提到過的,多重恢復 (Multi-resume) 意味着在多窗口模式時讓全部可見的 Activity 處於 resumed 狀態。在 Android 9 Pie 中,遊戲和應用均可以選擇打開 Multi-resume 功能,只需將聲明添加到 manifest 中便可:

<application>
  <meta-data
    android:name="android.allow_multiple_resumed_activities"
    android:value=」true」 />
  <activity ... />
</application>
複製代碼

成功案例: Gameloft Asphalt 9

在瞭解到玩家們的大屏幕遊戲需求後,Gameloft 利用這個契機調整了 Asphalt 9 的遊戲設置,以便優化這款遊戲在大屏幕設備上的體驗。團隊在構建遊戲時考慮了各類輸入方式和顯示器尺寸,並確保了遊戲在不一樣種類的設備上擁有一致的高速性能表現。

  • Gameloft 在 GDC 2019 上的分享

www.youtube.com/watch?v=ZfB…

咱們還與 Gameloft 合做,針對Chrome OS 和可摺疊設備優化了 Asphalt 9 的前做,Asphalt 8: Revolution。

針對 Chrome OS 進行適配後,Asphalt 8 的每日活躍用戶數量增長了 6 倍,Chrome 用戶帶來的收入則增加了 9 倍。也正是在看到適配帶來的優點後,Gameloft 的核心工做就涵蓋了爲較大屏幕進行設計的要素。

打造移動遊戲的將來

咱們但願您在閱讀完本文後,能認識到 Android 遊戲再也不是專屬於移動設備的體驗——今天的玩家正在各類外形和尺寸的設備上體驗遊戲。經過遵循 Android 最佳實踐並額外投入一些時間思考您的遊戲在大屏幕上體驗的可能性,您能夠將您的遊戲帶到更大的舞臺上,真正作到爲每一個玩家提供最佳的遊戲體驗。

您的遊戲有適配更多的屏幕尺寸嗎?歡迎在評論區和咱們分享遊戲適配中的疑問和心得。

點擊這裏即刻開始適配更多屏幕

相關文章
相關標籤/搜索