# PlayDrop 游戏中的本地队伍、手柄和手机控制器

通过 sdk.device 读取实体手柄和 PlayDrop 手机控制器，跟踪本地玩家槽位，并声明控制器支持和本地队伍人数。

Source: https://www.playdrop.ai/zh-hans/create/learn/local-party

本地队伍是几个人在同一块屏幕上一起玩，每人一个控制器：实体手柄，或者扫码后被 PlayDrop 变成控制器的手机。无论在网站上还是在应用中，你的游戏都通过 SDK 以相同的方式读取每个控制器。

## 声明控制器和队伍人数

```json
{
  "types": ["solo", "party"],
  "party": { "local": [1, 2, 3, 4] },
  "controller": { "support": "optional", "type": "simpler" }
}
```

- `controller.support` 为 `off`、`optional` 或 `required`。每款游戏都要声明，包括 `off`。
- `controller.type` 指定游戏所需的最低操控：`any`（方向输入、确认和取消）、`simpler`（一根摇杆、四个正面按键和菜单键；手机控制器符合要求）或 `standard`（方向键、两根可按下的摇杆、四个正面按键、两个肩键、两个扳机和菜单键）。
- `party.local` 列出同一屏幕上的确切玩家人数；`1` 需要 `solo` 类型。开启控制器支持时，列出的每种人数都必须能用控制器游玩。

## 读取控制器

```js
await sdk.device.enableControllerInput().catch(() => { /* keep keyboard and touch */ });

const stop = sdk.device.onButton(({ playerIndex, button, pressed }) => {
  if (button === "south" && pressed) jump(playerIndex);
});

function update() {
  for (const slot of sdk.device.localPlayers) {
    const pad = sdk.device.gamepad(slot.playerIndex);
    if (pad?.connected) move(slot.playerIndex, pad.axes[0], pad.axes[1]);
  }
  requestAnimationFrame(update);
}
update();
```

- 在 `init()` 之后调用一次 `enableControllerInput()`。宿主无法提供输入时，它会以 `controller_input_unavailable` 或 `controller_input_timeout` 拒绝；游戏会继续运行。
- `gamepad(playerIndex)` 按浏览器的标准布局返回一份快照：`axes`（左摇杆 x/y、右摇杆 x/y，范围 -1 到 1）、十七个 `buttons`、`source`（`physical` 或 `virtual`）和 `id`。`playerIndex` 为 0 表示玩家 1。
- 按键按位置命名，例如 `south` 和 `east`。`pad.label("south")` 会给出要显示的按键提示：根据控制器不同，为“A”、“Cross”或“B”。`pad.has("dpad")` 可判断某个操控是否存在。
- 菜单键和主页键属于 PlayDrop，读取时始终为松开状态。
- 绝不能调用 `navigator.getGamepads()`：手机控制器只能通过 SDK 传给游戏，PlayDrop 也会记录一条警告。

## 本地玩家槽位

`sdk.device.localPlayers` 列出玩家选择的槽位 `{ playerIndex, gamepadKey }`，`onLocalPlayersChange(callback)` 会报告变化。断开的控制器会保留它的槽位。当玩家名单变化或变为空时，返回一个合适的菜单，而不是让游戏崩溃。单独一个控制器只是普通输入，不算队伍。

从一个按钮调用 `sdk.social.openParty({ mode: "local" })`，可以打开 PlayDrop 的配对窗口，里面有手机二维码和已连接的手柄。只提供你声明过的模式。

## 本地或在线，二选一

宿主启动游戏时，要么作为本地队伍，要么作为在线队伍，绝不会同时进行：本地玩家不能加入在线房间。和朋友在线一起玩，请参阅[在线队伍和语音](https://www.playdrop.ai/zh-hans/create/learn/online-party)。

## 为沙发游戏而设计

显示每位玩家的颜色和控制器按键提示，让任何人按一个键就能加入，并让 HUD 从沙发上也能看清。为单人游玩保留触屏和键盘操控。

## 相关指南

- [在线队伍和语音](https://www.playdrop.ai/zh-hans/create/learn/online-party): 让朋友们在线一起玩你的游戏：声明队伍人数，打开 PlayDrop 的队伍窗口，用 sdk.multiplayer.join 加入预留的房间，并控制房间语音。
- [全屏和安全区域](https://www.playdrop.ai/zh-hans/create/learn/viewport): 让 PlayDrop 游戏铺满屏幕，借助 SDK 测得的 reservedCorners，让 HUD 留在 CSS 安全区域内并避开宿主的控件。
- [catalogue.json](https://www.playdrop.ai/zh-hans/create/learn/catalogue-json): PlayDrop 游戏使用的 catalogue.json 字段：标识、商店页面、游玩方式、显示形态、登录、即玩、预加载、媒体、翻译、分数和服务器。
