Разрабатывайте игры для всех экранов

При разработке игры для Android важно учитывать разнообразие возможных сценариев взаимодействия с игроками и адаптироваться к потребностям игроков в реальном времени. Поддерживая разные режимы, вы делаете игру более гибкой и расширяете ее охват.

Вот основные различия:

  • Типы устройств. Хотя телефоны – это традиционные устройства Android, играть можно и на других устройствах. На устройствах с ChromeOS можно запустить контейнер Android, в котором будет показываться ваша игра. Планшеты, на которых можно запустить Android, поддерживают несколько уровней точности. Устройства Android TV поддерживают более детализированные и захватывающие игры. Игроки могут симулировать многооконный режим с помощью инструмента расширения экрана. А на складных устройствах игроки могут менять размер экрана прямо во время игры.
  • Способы взаимодействия. Игроки могут вводить данные, касаясь экрана устройства, а также использовать мышь, сенсорную панель, клавиатуру или контроллер. Кроме того, благодаря инструментам расширения экрана и складным устройствам пользователи могут играть на большом экране, что позволяет проводить более длительные игровые сеансы и использовать более сложные интерфейсы.
  • Поддержка аппаратного обеспечения. На некоторых устройствах Android нет аппаратного обеспечения, которое обычно есть на мобильных устройствах, например задней камеры, GPS и сетевого подключения. Игра должна адаптироваться к доступному оборудованию и корректно обрабатывать ситуации, когда определенные функции недоступны.

В этом руководстве приведены рекомендации по разработке игр для разных типов экранов и способов взаимодействия с пользователем. В этом руководстве также приведены рекомендации по разработке игры и эффективной стратегии тестирования.

Рекомендации по разработке игр

При планировании дизайна и архитектуры игры следуйте рекомендациям, описанным в следующих разделах.

Как реагировать на изменения конфигурации вручную

Когда система Android обнаруживает изменение конфигурации, например изменение размера экрана, ориентации экрана или метода ввода, система по умолчанию перезапускает текущее действие. Чтобы сохранить состояние приложения или игры, по умолчанию вызывается метод onSaveInstanceState() перед перезапуском и onRestoreInstanceState() после него. Однако при этом действию приходится перезагружать все связанные сервисы и ресурсы. Подробнее о режиме работы по умолчанию рассказывается в руководстве по обработке изменений конфигурации.

Во время типичного игрового сеанса конфигурация меняется несколько раз. Если игра позволяет системе обрабатывать каждое изменение конфигурации, сцена игры будет уничтожаться и перезапускаться снова и снова, что снизит производительность игры. Поэтому мы настоятельно рекомендуем вам самостоятельно обрабатывать эти изменения конфигурации в игре.

Чтобы узнать, как добавить в игру логику изменения конфигурации, прочитайте раздел Как создать собственные обработчики изменения конфигурации.

Создайте гибкую архитектуру

Чтобы обеспечить поддержку игры на как можно большем количестве устройств, следуйте этим рекомендациям:

  • Развертывайте наборы Android App Bundle вместо отдельных APK-файлов. Android App Bundle позволяет упаковать объекты с разным разрешением и архитектурой (например, x86 и ARM) в один объект. Кроме того, наборы Android App Bundle поддерживают более крупные файлы: размер основного APK-файла может достигать 150 МБ, а размер набора – нескольких гигабайт.
  • Добавлена поддержка архитектур x86. Это повысит производительность игры на устройствах, которые не поддерживают ARM, поскольку они смогут выполнять инструкции без предварительного преобразования.

Добавьте поддержку Vulkan

Поддержка Vulkan позволяет повысить производительность графики в игре. Большинство устройств поддерживают этот графический API.

Создание пользовательских обработчиков изменения конфигурации

Чтобы указать, какие изменения конфигурации игра обрабатывает самостоятельно, добавьте атрибут android:configChanges в каждый элемент <activity> манифеста, который представляет экран или сложный интерфейс.

В следующем фрагменте кода показано, как объявить, что игра обрабатывает изменения размера экрана, его ориентации и способа ввода:

<activity ...
    android:configChanges="screenSize|orientation|keyboard|keyboardHidden">
</activity>

Когда происходят изменения в объявленной конфигурации, система вызывает другой метод – onConfigurationChanged(). В этом методе добавьте логику для обновления интерфейса игры:

Как обрабатывать изменения конфигурации экрана

Если вы добавите значения screenSize и orientation в атрибут android:configChanges, то сможете вручную настраивать размер и ориентацию экрана. Вы можете использовать эти новые значения, чтобы обновить контент сцены и области ввода игрока. Чтобы узнать, как разработать макет игры, который будет проще обновлять, ознакомьтесь с руководством по поддержке экранов разных размеров.

В реализации onConfigurationChanged() используйте переданный объект Configuration и объект Display менеджера окон, чтобы определить обновленные значения размера и ориентации экрана соответственно.

В следующем фрагменте кода показано, как получить обновленный размер и ориентацию экрана игры:

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()

    // Get general orientation; either Configuration.ORIENTATION_PORTRAIT or
    // Configuration.ORIENTATION_LANDSCAPE.
    val newScreenOrientation: Int = newConfig.orientation

    // Get general rotation; one of: 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);

    // Get general orientation; either Configuration.ORIENTATION_PORTRAIT or
    // Configuration.ORIENTATION_LANDSCAPE.
    int newScreenOrientation = newConfig.orientation;

    // Get general rotation; one of: ROTATION_0, ROTATION_90, ROTATION_180,
    // or ROTATION_270.
    int newScreenRotation = getWindowManager().getDefaultDisplay()
            .getRotation();
}

Обратите внимание, что изменение положения складного устройства меняет конфигурацию, даже если приложение работает в полноэкранном режиме. В результате ваше приложение должно будет обрабатывать изменения размера экрана или плотности пикселей, если пользователь складывает или раскладывает устройство во время работы игры.

Особенности экрана для игр

В следующих разделах описывается, как настроить реакцию игры на изменение размера или ориентации экрана в зависимости от ее особенностей.

Полноэкранный режим

На некоторых платформах, например ChromeOS, приложения Android и игры по умолчанию могут открываться в окне, размер которого можно менять. Если игра должна всегда запускаться в полноэкранном режиме, вы можете задать атрибуту android:resizeableActivity значение false в одном из элементов <activity>, как показано в следующем фрагменте кода:

<activity ...
    android:resizeableActivity="false">
</activity>

Вы также можете задать для атрибута android:resizeableActivity значение false, чтобы предотвратить изменения конфигурации, связанные с размером. Если ваша игра не всегда работает в полноэкранном режиме, используйте этот атрибут только в качестве временного решения для тестирования.

Ориентация экрана

Если для игры требуется определенная ориентация датчиков устройства, укажите значение android:screenOrientation в действии игры, как показано в следующем фрагменте кода. Это поможет предотвратить неожиданный переворот сцены в игре.

<activity ...
    android:screenOrientation="landscape">
</activity>

Качество экрана на разных устройствах

В следующих разделах описывается, как обрабатывать изменения конфигурации на основе экрана с учетом определенных качеств, которыми обладают некоторые устройства.

Соотношение сторон

Некоторые устройства поддерживают разные соотношения сторон. Например, складные устройства в сложенном состоянии поддерживают соотношение сторон 21:9. Чтобы избежать проблем с соотношением сторон, выполните хотя бы одно из следующих действий:

  • Обеспечьте поддержку Android 8.0 (уровень API 26) или более поздней версии.
  • Сделайте так, чтобы размер сцены и интерфейса игры можно было менять. Для устройств с Android 7.0 (уровень API 24) и более поздними версиями задайте для параметра android:resizeableActivity значение true.
  • Укажите максимальное поддерживаемое соотношение сторон. В атрибуте <meta-data>, связанном с вашей игрой, задайте для android.max_aspect значение 2.4, как показано в следующем фрагменте кода. Однако имейте в виду, что если соотношение сторон экрана больше указанного вами, то игра будет отображаться с черными полосами по краям.

    <application>
    <meta-data android:name="android.max_aspect"
               android:value="2.4" />
    </application>

Одновременно показывается несколько действий.

Многие современные устройства поддерживают различные макеты экрана, включая разделенный экран, картинку в картинке и большие области отображения. При использовании одного из этих макетов система может сделать видимыми несколько действий одновременно.

На устройствах с Android 9 (уровень API 28) или более поздней версией ОС все видимые действия могут возобновляться одновременно. Чтобы это работало, и игра, и OEM-производитель устройства должны поддерживать эту функцию. Чтобы добавить поддержку, задайте для атрибута android.allow_multiple_resumed_activities значение true в манифесте игры, как показано в следующем фрагменте кода:

<application>
    <meta-data android:name="android.allow_multiple_resumed_activities"
               android:value="true" />
</application>

Затем вы можете протестировать игру на разных устройствах, чтобы узнать, какие из них поддерживают OEM-функции, необходимые для правильной работы одновременной работы нескольких приложений.

Подробнее о том, как добавить поддержку многооконного режима…

Поддержка разных типов взаимодействия

Если вы добавите значения keyboard и keyboardHidden в атрибут android:configChanges, то сможете вручную управлять наличием и доступностью клавиатуры. Вы можете использовать эти новые значения, чтобы обновить основной способ ввода в игре.

При настройке игры для поддержки нескольких типов пользовательского ввода учитывайте следующее:

  • Определяйте способы ввода, а не отдельные устройства. Такой подход позволяет улучшать игровой процесс, не зацикливаясь на конкретном устройстве, которое может быть у игрока.
  • Добавьте атрибут keyboardHidden в список изменений конфигурации, обрабатываемых вручную. Таким образом, ваша игра может отслеживать, когда клавиатура физически подключена к устройству, но непригодна для использования.
  • Определите, какие способы ввода доступны в настоящее время. Для этого вызовите getInputDeviceIds() при запуске игры и после каждого изменения конфигурации.

    Часто можно определить, как игрок планирует взаимодействовать с вашей игрой, на основе его предпочтительного устройства ввода:

    • Обычно игроки используют клавиатуру или контроллер, чтобы быстро нажимать нужные кнопки.
    • Для выполнения более сложных жестов игроки обычно используют сенсорный экран или сенсорную панель.
    • Обычно мышь используется для более точного ввода.

В следующих разделах приведены рекомендации для определенных типов устройств ввода.

Клавиатура

При создании раскладки клавиатуры для игры учитывайте, как игрок перемещается по сцене и как он взаимодействует с настройками игры.

Для управления движением персонажа обычно лучше всего подходят клавиши WASD или клавиши со стрелками. Также лучше назначить определенную клавишу для каждого важного действия или навыка, которые может выполнять управляемый персонаж в вашей игре. Чтобы сделать игру максимально удобной, добавьте поддержку пользовательских сочетаний клавиш.

Игроки также должны иметь возможность открывать меню игры и перемещаться по ним с помощью клавиатуры. Клавиша Esc часто используется для приостановки игры и открытия меню.

Дополнительную информацию о поддержке ввода с клавиатуры в игре можно найти в руководствах по поддержке навигации с помощью клавиатуры и обработке действий с клавиатуры.

Игровой контроллер

Подробнее о том, как настроить поддержку игровых контроллеров…

Мышь или сенсорная панель

Если в вашей игре поддерживается ввод с помощью мыши или сенсорной панели, помните, что игроки взаимодействуют с устройством не только во время игры. Важно знать, что при запросе захвата указателя все управление мышью направляется в вашу игру. Поэтому, когда игра получит нужную информацию, отмените захват указателя, чтобы игроки могли управлять устройством с помощью мыши.

На устройствах с Android 8.0 (уровень API 26) и более поздними версиями можно использовать Mouse Capture API, чтобы упростить захват указателя. В играх, которые реагируют на высокоточный ввод, вы можете получить текущие координаты указателя, вызвав методы getX() и getY().

Дополнительную информацию о том, как добавить в игру поддержку мыши и сенсорной панели, можно найти в руководствах по отслеживанию касаний и движений указателя и обработке жестов с несколькими касаниями.

Как протестировать игру

Прежде чем запускать игру, проверьте, как она реагирует на изменения конфигурации. Для этого выполните действия, описанные в следующих разделах.

Обновите план тестирования

При проверке функциональности игры включите следующие тестовые сценарии:

  • Сверните и разверните окно с игрой. (Не применяется, если игра всегда открывается в полноэкранном режиме.)
  • Изменить размер экрана.
  • Изменить ориентацию экрана. (Не применяется, если в игре фиксированная ориентация.)
  • Подключать и отключать устройства ввода, например клавиатуры и мыши.
  • Если игра поддерживает одновременную работу нескольких приложений, запустите ее в этом режиме.

Также рекомендуем обновить систему контроля качества игры, чтобы оптимизировать ее для разных игроков.

Рекомендации по тестированию игр можно найти в руководстве по основам тестирования.

Используйте инструменты для тестирования и отладки

Вы можете проводить тестирование с помощью различных инструментов, которые поддерживает платформа: