Создавайте телевизионные игры

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

Отображать

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

Поддержка альбомной ориентации

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

Автоматический режим с низкой задержкой

Некоторые дисплеи могут выполнять постобработку графики. Эта постобработка улучшает качество графики, но может увеличить задержку. Новые дисплеи с поддержкой HDMI 2.1 имеют автоматический режим низкой задержки ( ALLM ), который минимизирует задержку, отключая постобработку. Подробнее об ALLM см. в спецификации HDMI 2.1 . Другие дисплеи могут поддерживать игровой режим с аналогичным поведением.

В Android 11 и более поздних версиях окно может запросить использование режима автоматической низкой задержки или игрового режима (если он доступен), запрашивая минимальную постобработку . Это особенно полезно для игр и приложений для видеоконференций, где низкая задержка важнее наилучшей графики.

Чтобы включить или отключить минимальную постобработку, вызовите метод Window.setPreferMinimalPostProcessing() или установите атрибут preferMinimalPostProcessing окна в значение true . Не все дисплеи поддерживают минимальную постобработку; чтобы узнать, поддерживает ли её конкретный дисплей, вызовите метод Display.isMinimalPostProcessingSupported() .

Устройства ввода

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

Раскладки клавиатуры

В Android 13 (уровень API 33) и выше раскладки клавиатуры можно определить с помощью getKeyCodeForKeyLocation() . Например, ваша игра поддерживает перемещение с помощью клавиш WASD, но это может работать некорректно на клавиатуре AZERTY, где клавиши A и W расположены по-разному. Вы можете получить коды клавиш, которые вы ожидаете увидеть в определённых позициях:

Котлин

val inputManager: InputManager? = requireActivity().getSystemService()

inputManager?.inputDeviceIds?.map { inputManager.getInputDevice(it) }
    ?.firstOrNull { it.keyboardType == InputDevice.KEYBOARD_TYPE_ALPHABETIC }
    ?.let { inputDevice ->
        keyUp = inputDevice.getKeyCodeForKeyLocation(KeyEvent.KEYCODE_W)
        keyLeft = inputDevice.getKeyCodeForKeyLocation(KeyEvent.KEYCODE_A)
        keyDown = inputDevice.getKeyCodeForKeyLocation(KeyEvent.KEYCODE_S)
        keyRight = inputDevice.getKeyCodeForKeyLocation(KeyEvent.KEYCODE_D)
    }

Ява

InputManager inputManager = requireActivity().getSystemService(InputManager.class);
InputDevice inputDevice = Arrays.stream(inputManager.getInputDeviceIds())
        .mapToObj(inputManager::getInputDevice)
        .filter( device -> device.getKeyboardType() == InputDevice.KEYBOARD_TYPE_ALPHABETIC)
        .filter(Objects::nonNull)
        .findFirst()
        .orElse(null);
if (inputDevice != null) {
    keyUp = inputDevice.getKeyCodeForKeyLocation(KeyEvent.KEYCODE_W);
    keyLeft = inputDevice.getKeyCodeForKeyLocation(KeyEvent.KEYCODE_A);
    keyDown = inputDevice.getKeyCodeForKeyLocation(KeyEvent.KEYCODE_S);
    keyRight = inputDevice.getKeyCodeForKeyLocation(KeyEvent.KEYCODE_D);
}

В этом примере с клавиатурой AZERTY клавиша keyUp установлена на KeyEvent.KEYCODE_Z , keyLeft — на KeyEvent.KEYCODE_Q , а keyDown и keyRight — на KeyEvent.KEYCODE_S и KeyEvent.KEYCODE_D соответственно. Теперь вы можете создать обработчики событий клавиш для этих кодов клавиш и реализовать ожидаемое поведение.

Манифест

Есть несколько специальных вещей, которые игры должны включать в манифест Android.

Покажите свою игру на главном экране

На главном экране Android TV игры отображаются отдельно от обычных приложений. Чтобы ваша игра появилась в списке игр, установите для атрибута android:isGame значение "true" в теге <application> манифеста вашего приложения. Например:

<application
    ...
    android:isGame="true"
    ...
>

Объявить о поддержке игровых контроллеров

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

  <uses-feature android:name="android.hardware.gamepad" android:required="false"/>

Примечание: При указании поддержки android:hardware:gamepad не устанавливайте атрибут android:required в "true" . В противном случае пользователи не смогут установить ваше приложение на телевизоры.

Дополнительную информацию о записях манифеста см. в разделе Манифест приложения .

Игровые сервисы Google Play

Если ваша игра интегрирует игровые сервисы Google Play , вам следует учитывать ряд моментов, касающихся достижений, входа в систему и сохранения игр.

Достижения

Ваша игра должна включать не менее пяти (зарабатываемых) достижений. Достижения должен получать только пользователь, управляющий игрой с поддерживаемого устройства ввода. Подробнее о достижениях и их реализации см. в разделе «Достижения в Android» .

Войти

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

Экономия

Используйте функцию «Сохранённые игры» в сервисах Google Play для хранения сохранений. Ваша игра должна привязывать сохранения к определённой учётной записи Google, чтобы их можно было однозначно идентифицировать даже на разных устройствах: независимо от того, использует ли игрок телефон или телевизор, игра должна иметь возможность извлекать информацию из одной и той же учётной записи пользователя.

Также следует предоставить в интерфейсе игры возможность удалять локальные и облачные данные. Эту возможность можно добавить на экран Settings игры. Подробнее о реализации сохранений игр с помощью сервисов Play см. в разделе «Сохраненные игры в Android» .

Выход

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

Интернет

Не включайте просмотр веб-страниц в играх для Android TV. Android TV не поддерживает веб-браузер.

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

Нетворкинг

Играм часто требуется более высокая пропускная способность для обеспечения оптимальной производительности, и многие пользователи предпочитают Ethernet, а не Wi-Fi. Ваше приложение должно проверять наличие как Wi-Fi, так и Ethernet-подключений. Если ваше приложение предназначено только для телевизора, вам не нужно проверять наличие сети 3G/LTE, как для мобильного приложения.