# SDK ฝั่งไคลเอนต์ของ PlayDrop สำหรับเกมบนเบราว์เซอร์

SDK บนเบราว์เซอร์แบบไม่บังคับสำหรับเกม PlayDrop: การเข้าสู่ระบบ การบันทึก ลีดเดอร์บอร์ด การซื้อ โฆษณา เพื่อน คอนโทรลเลอร์ และผู้เล่นหลายคน ด้วยแท็กสคริปต์เดียว

Source: https://www.playdrop.ai/th/create/learn/sdk

PlayDrop SDK ไม่บังคับ: เกมที่ไม่มี SDK ก็เล่นบน PlayDrop ได้ เพิ่มเมื่อต้องการฟีเจอร์ของแพลตฟอร์ม เช่น การเข้าสู่ระบบของผู้เล่น การบันทึก ความสำเร็จและลีดเดอร์บอร์ด การซื้อด้วยเครดิต โฆษณา เพื่อนและการ์ดเกมใน PlayDrop Chat ลิงก์แชร์ การหยุดชั่วคราวและเสียงที่โฮสต์จัดการ อินพุตคอนโทรลเลอร์ ผู้เล่นหลายคนที่โฮสต์ให้ และการสร้างด้วย AI [PlayDrop Cloud](https://www.playdrop.ai/th/create) ผสานให้คุณแล้ว และเมื่อใช้ [PlayDrop Connector](https://www.playdrop.ai/th/create/connectors) เอเจนต์ของคุณจะเพิ่มแท็กสคริปต์เดียวให้

## เพิ่ม SDK และทำตามวงจรชีวิตของโฮสต์

โหลด SDK จาก CDN ของ PlayDrop ไม่ต้องติดตั้งแพ็กเกจ เรนเดอร์เฟรมแรกที่เล่นได้และเตรียมอินพุตก่อนเรียก `sdk.host.ready()` หยุดการจำลองเมื่อโฮสต์หยุดชั่วคราว เล่นต่อโดยไม่สร้างลูปซ้ำ และทำตามนโยบายเสียงของโฮสต์

```html
<script src="https://assets.playdrop.ai/sdk/playdrop.js"></script>
<script type="module">
  const sdk = await playdrop.init();
  // Render the game and prepare input, then:
  sdk.host.ready();
  sdk.host.onPause(() => pauseGame());
  sdk.host.onResume(() => resumeGame());
  sdk.host.onAudioPolicyChange(({ enabled }) => setAudioEnabled(enabled));
</script>
```

## ตัวตน การบันทึก และภาษา

`sdk.me` เปิดเผยตัวตนของผู้เล่น และ `sdk.me.appData` เก็บการบันทึกส่วนตัว `sdk.achievements` และ `sdk.leaderboards` จัดการความสำเร็จและคะแนน การบันทึก ความสำเร็จ และลีดเดอร์บอร์ดทำงานได้โดยไม่ต้องตรวจสอบการเข้าสู่ระบบล่วงหน้า ใช้ `sdk.me.isLoggedIn` สำหรับฟีเจอร์ที่ต้องมีบัญชีจริง เช่น การซื้อหรือผู้เล่นหลายคน โหมดตัวอย่างและโหมดจับภาพต้องไม่เขียนความคืบหน้าของผู้เล่น `sdk.host.language` ให้ภาษาของผู้เล่น: ส่งภาษาอังกฤษพร้อมภาษาของคุณเองเมื่อต่างกัน การแปลหน้าเกมไม่ได้แปลเนื้อหาในเกม ในจังหวะพักตามธรรมชาติ เช่นตอนชนะ `sdk.host.requestReview()` ให้ PlayDrop ขอรีวิวจากผู้เล่นได้ สูงสุดหนึ่งครั้งต่อเกม เกมของคุณจะไม่ทราบคำตอบ จึงอย่าให้รางวัลตอบแทน

## ไลบรารี แอสเซ็ต และผู้เล่นหลายคน

`sdk.libs` โหลดเวอร์ชันที่รองรับของ Three.js, Phaser, Rapier, nipplejs และ Colyseus `sdk.assets` ให้การอ้างอิงแคตตาล็อก แพ็ก และแอสเซ็ต `sdk.social` ให้เพื่อน การ์ดเกม และการดำเนินการแชร์ สำหรับผู้เล่นหลายคนที่โฮสต์ให้ `sdk.multiplayer.getConnection()` ส่งคืนที่อยู่เซิร์ฟเวอร์และโทเค็นของผู้เล่นที่เข้าสู่ระบบ เข้าร่วมด้วยไคลเอนต์ Colyseus หน้า [SDK ฝั่งเซิร์ฟเวอร์](https://www.playdrop.ai/th/create/learn/server-sdk) ครอบคลุมเซิร์ฟเวอร์ที่โฮสต์ให้ ส่วนเซิร์ฟเวอร์ที่คุณรันเองไม่ต้องใช้อะไรจาก SDK API ห้องรีเลย์แบบเดิมเลิกใช้แล้ว

## ทดสอบด้วย SDK ก่อนเผยแพร่

รันเซิร์ฟเวอร์พัฒนาตามปกติและเปิด `https://www.playdrop.ai/creators/<username>/apps/game/<slug>/dev?url=http://localhost:5173/` ใน Chrome เพื่อเล่นภายในเฟรม PlayDrop จริงพร้อมโฮสต์ SDK พอร์ต localhost ใดก็ได้หรือ URL แบบ https ก็ใช้ได้ ฟีเจอร์ที่ต้องมีบัญชี เช่น การบันทึกและการซื้อ ใช้งานได้เมื่ออัปโหลดเกมแล้วหนึ่งครั้ง การอัปโหลดแบบส่วนตัวก็เพียงพอ การสร้างสื่อบนเบราว์เซอร์ทำงานเป็นงานแบบอะซิงโครนัสที่โฮสต์ยืนยันค่าเครดิต ดู [catalogue.json](https://www.playdrop.ai/th/create/learn/catalogue-json) สำหรับข้อมูลเมตาของหน้าเกม

## เล่นด้วยกัน

ใช้ `await sdk.multiplayer.join("game")` ในช่วงเล่น มันเข้าร่วมแบบอิสระ หรือใช้การจองปาร์ตี้ของโฮสต์ หากปาร์ตี้ล้มเหลวจะปฏิเสธ แทนที่จะแยกผู้เล่นไปอยู่อีกห้องอย่างเงียบๆ `getConnection()` ยังคงเป็น API รายละเอียดการเชื่อมต่อทันทีสำหรับเกมที่มีอยู่ ใช้ห้องเดิมตลอดทุกรอบ และคงการเชื่อมต่อเครือข่ายไว้ขณะที่โอเวอร์เลย์ของโฮสต์หยุดอินพุตของเกม

ใช้ `sdk.social.openParty()` จากการกระทำของผู้เล่นเพื่อเปิดป๊อปอัปปาร์ตี้ของโฮสต์ อ่านสมาชิกด้วย `await sdk.social.getParty()` หรือ `sdk.social.onPartyChange(callback)` เกมแก้ไขปาร์ตี้ของแพลตฟอร์มหรือควบคุมไมโครโฟนไม่ได้ แชทเสียงของปาร์ตี้และห้องอยู่ในโฮสต์เว็บ/เนทีฟ และยังขึ้นกับความยินยอมของผู้เล่น การปิดเสียง การบล็อก และสิทธิ์ในการเปิดใช้งานแบบทยอย

เพื่อการเล่นในห้องที่ลื่นไหล เรียก `sdk.multiplayer.voice.updateSpatialState({ listener: { position, forward, up }, speakers: [{ userId, position }] })` โดยใช้เวกเตอร์ `{ x, y, z }` ที่มีค่าจำกัด คำใบ้มีผลต่อระดับเสียงและการแพนเท่านั้น ไม่เกี่ยวกับการอนุญาต เซิร์ฟเวอร์บังคับใช้สิทธิ์ของทีมและความใกล้เคียง

ใช้ `sdk.device.localPlayers` และ `sdk.device.onLocalPlayersChange(callback)` สำหรับช่องคอนโทรลเลอร์ในเครื่องที่เลือก `{ playerIndex, gamepadKey }` รายการคอนโทรลเลอร์ที่เชื่อมต่อแยกต่างหาก ช่องที่ตัดการเชื่อมต่อยังคงตัวตนไว้ โหมดในเครื่องเข้าร่วมห้องออนไลน์ไม่ได้ สูตรที่คัดลอกได้ `playdrop-metagame/recipes/play-together` สาธิตทั้งสองโหมด สองปลายทาง และนโยบายห้อง

## คอนโทรลเลอร์

อ่านคอนโทรลเลอร์จริงและคอนโทรลเลอร์บนโทรศัพท์ของ PlayDrop ผ่าน `sdk.device` แบบเดียวกันทุกแพลตฟอร์ม เรียก `enableControllerInput()` หนึ่งครั้งหลัง `init()` อ่าน `gamepad(playerIndex)` ในลูปเกม (0 คือ P1) และใช้ `onButton` สำหรับการกดและปล่อย แกนและปุ่มเรียงตามลำดับเกมแพดมาตรฐานของเบราว์เซอร์ ปุ่มมีชื่อตามตำแหน่ง เช่น `south` และ `east` และ `pad.label("south")` ส่งคืนข้อความบนปุ่มของคอนโทรลเลอร์นั้น เช่น `"A"` หรือ `"Cross"` เมนูเป็นของ PlayDrop และหยุดเกม

```js
await sdk.device.enableControllerInput();
const stop = sdk.device.onButton(({ playerIndex, button, pressed }) => {
  if (button === "south" && pressed) jump(playerIndex);
});
function update() {
  const pad = sdk.device.gamepad(0);
  if (pad?.connected) move(pad.axes[0], pad.axes[1]);
  requestAnimationFrame(update);
}
update();
```

อย่าเรียก `navigator.getGamepads()`: คอนโทรลเลอร์บนโทรศัพท์ส่งถึงเกมผ่าน SDK เท่านั้น และ PlayDrop บันทึกคำเตือนเมื่อเกมอ่าน API ของเบราว์เซอร์โดยตรง หากโฮสต์ให้อินพุตคอนโทรลเลอร์ไม่ได้ `enableControllerInput()` จะปฏิเสธด้วย `controller_input_unavailable` หรือ `controller_input_timeout` และเกมจะทำงานต่อ `pad.has("dpad")` บอกว่ามีปุ่มควบคุมนั้นหรือไม่ ประกาศการควบคุมที่เกมต้องการใน [catalogue.json](https://www.playdrop.ai/th/create/learn/catalogue-json)
