构建 TV 游戏

电视屏幕带来了一些对于移动游戏开发者而言可能是全新的考量因素。这些方面包括屏幕尺寸大、控制方案独特,以及所有玩家都在同时观看同一屏幕的事实。

显示 (Display)

在为电视屏幕开发游戏时,需要牢记两点:一是针对横向屏幕方向设计游戏,二是提供低延迟支持。

支持横向显示

电视始终是横放的:您无法旋转它,也没有纵向模式。请务必将您的电视游戏设计为以横向模式显示。

自动低延迟模式

某些显示设备可以执行图形后处理。这种后处理虽然能提高图形质量,但会增加延迟。支持 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 键的位置不同。您可以获取特定位置预期按键的键码。

Kotlin

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

Java

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_ZkeyLeft 被设置为 KeyEvent.KEYCODE_Q,而 keyDownkeyRight 分别被设置为 KeyEvent.KEYCODE_SKeyEvent.KEYCODE_D。现在,您可以为这些键码创建按键事件处理程序并实现预期的行为。

清单 (Manifest)

游戏应在 Android 清单文件中包含一些特殊内容。

在主屏幕上显示您的游戏

Android TV 主屏幕会在与常规应用不同的行中显示游戏。要使您的游戏出现在游戏列表中,请在应用清单的 <application> 标记中将 android:isGame 属性设置为 "true"。例如:

<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 服务已保存游戏 (Saved Games) 来存储您的游戏存档。您的游戏应将游戏存档绑定到特定的 Google 帐号,以便在不同设备间实现唯一标识:无论玩家使用的是手机还是电视,游戏都应能够从同一用户帐号拉取游戏存档信息。

您还应在游戏界面中提供一个选项,允许玩家删除本地和云端存储的数据。您可以将此选项放在游戏的 Settings(设置)屏幕中。有关使用 Play 服务实现已保存游戏的具体细节,请参阅Android 中的已保存游戏

退出

提供一个一致且显眼的界面元素,让用户可以妥善退出游戏。此元素应可通过方向键导航按钮访问。请使用这种方式,而不要依赖 Home(主页)键来提供退出功能,因为这在不同的控制器上既不一致也不可靠。

Web

请勿在 Android TV 的游戏中启用网页浏览功能。Android TV 不支持网页浏览器。

注意:您可以使用 WebView 类来处理社交媒体服务的登录。

网络

游戏通常需要更大的带宽来提供最佳性能,许多用户更喜欢使用以太网而不是 WiFi 来获得这种性能。您的应用应检查 WiFi 和以太网连接。如果您的应用仅适用于电视,则无需像移动应用那样检查 3G/LTE 服务。