# Nhóm chơi cục bộ, tay cầm và điện thoại làm tay cầm trong game PlayDrop

Đọc tay cầm vật lý và tay cầm điện thoại PlayDrop qua sdk.device, theo dõi ô người chơi cục bộ, khai báo hỗ trợ tay cầm và quy mô nhóm chơi cục bộ.

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

Nhóm chơi cục bộ là nhiều người cùng chơi trên một màn hình, mỗi người cầm một tay cầm: tay cầm vật lý hoặc một chiếc điện thoại được PlayDrop biến thành tay cầm khi quét mã. Game của bạn đọc mọi tay cầm theo cùng một cách qua SDK, trên trang web lẫn trong các ứng dụng.

## Khai báo tay cầm và quy mô nhóm chơi

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

- `controller.support` là `off`, `optional` hoặc `required`. Hãy khai báo trường này cho mọi game, kể cả `off`.
- `controller.type` nêu bộ điều khiển tối thiểu game cần: `any` (hướng, Xác nhận và Hủy), `simpler` (một cần điều khiển, bốn nút mặt và Menu; tay cầm điện thoại đáp ứng được) hoặc `standard` (D-pad, hai cần điều khiển nhấn được, bốn nút mặt, hai nút vai, hai cò và Menu).
- `party.local` liệt kê chính xác số người chơi trên một màn hình; giá trị `1` yêu cầu loại `solo`. Khi bật hỗ trợ tay cầm, mọi số lượng được liệt kê đều phải chơi được bằng tay cầm.

## Đọc tay cầm

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

- Gọi `enableControllerInput()` một lần sau `init()`. Lệnh này bị từ chối với `controller_input_unavailable` hoặc `controller_input_timeout` khi host không cung cấp được đầu vào; game vẫn tiếp tục chạy.
- `gamepad(playerIndex)` trả về một ảnh chụp trạng thái theo bố cục chuẩn của trình duyệt: `axes` (trái x/y, phải x/y từ -1 đến 1), mười bảy `buttons`, `source` (`physical` hoặc `virtual`) và `id`. `playerIndex` 0 là người chơi 1.
- Các nút có tên theo vị trí như `south` và `east`. `pad.label("south")` cho biết nhãn cần hiển thị: "A", "Cross" hoặc "B" tùy tay cầm. `pad.has("dpad")` cho biết một điều khiển có tồn tại hay không.
- Menu và Home thuộc về PlayDrop và luôn được đọc là không được nhấn.
- Không bao giờ gọi `navigator.getGamepads()`: tay cầm điện thoại chỉ đến được game qua SDK, và PlayDrop sẽ ghi một cảnh báo.

## Ô người chơi cục bộ

`sdk.device.localPlayers` liệt kê các ô người chơi đã chọn, `{ playerIndex, gamepadKey }`, và `onLocalPlayersChange(callback)` báo các thay đổi. Một tay cầm bị ngắt kết nối vẫn giữ ô của nó. Khi danh sách người chơi thay đổi hoặc trở nên trống, hãy quay về một menu hợp lý thay vì để game gặp lỗi. Một tay cầm đơn lẻ chỉ là đầu vào thông thường, không phải nhóm chơi.

Từ một nút bấm, `sdk.social.openParty({ mode: "local" })` mở cửa sổ ghép nối của PlayDrop với mã QR cho điện thoại và các tay cầm đã kết nối. Chỉ cung cấp những chế độ bạn đã khai báo.

## Cục bộ hoặc trực tuyến, không cả hai

Host khởi động game dưới dạng nhóm chơi cục bộ hoặc nhóm chơi trực tuyến, không bao giờ cả hai: người chơi cục bộ không thể tham gia phòng trực tuyến. Để chơi trực tuyến với bạn bè, hãy xem [nhóm chơi trực tuyến và thoại](https://www.playdrop.ai/vi/create/learn/online-party).

## Thiết kế cho chơi chung trên ghế sofa

Hiển thị màu và nhãn nút tay cầm của từng người chơi, cho phép bất kỳ ai nhấn một nút để tham gia, và giữ HUD dễ đọc từ ghế sofa. Hãy giữ điều khiển cảm ứng và bàn phím cho chế độ chơi đơn.

## Hướng dẫn liên quan

- [Nhóm chơi trực tuyến và thoại](https://www.playdrop.ai/vi/create/learn/online-party): Cho bạn bè chơi cùng nhau trực tuyến: khai báo quy mô nhóm chơi, mở cửa sổ nhóm chơi của PlayDrop, vào phòng đã giữ chỗ bằng sdk.multiplayer.join, điều khiển thoại phòng.
- [Toàn màn hình và vùng an toàn](https://www.playdrop.ai/vi/create/learn/viewport): Cho game PlayDrop lấp đầy màn hình, giữ HUD trong vùng an toàn CSS và tránh nút điều khiển của host bằng reservedCorners do SDK đo.
- [catalogue.json](https://www.playdrop.ai/vi/create/learn/catalogue-json): Các trường catalogue.json game PlayDrop dùng: định danh, trang giới thiệu, chế độ chơi, màn hình, đăng nhập, Instant, tải trước, media, bản dịch, điểm và máy chủ.
