适用于浏览器游戏的 PlayDrop 客户端 SDK
适用于任何 PlayDrop 游戏的可选浏览器 SDK:只需一个 script 标签,即可使用宿主生命周期、登录、存档、排行榜、购买、广告、好友、控制器、多人游戏和共享库。
PlayDrop SDK 是可选的:不使用 SDK 的游戏同样可以在 PlayDrop 上游玩。如需平台功能,例如玩家登录、存档、成就和排行榜、点数购买、广告、PlayDrop Chat 中的好友和游戏卡片、分享链接、由宿主管理的暂停和音频、控制器输入、托管多人游戏以及 AI 生成,请添加 SDK。PlayDrop Cloud 会为你完成集成;使用 PlayDrop Connector 时,你的 Agent 只需添加一个 script 标签。
添加 SDK 并遵循宿主生命周期
<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>从 PlayDrop 的 CDN 加载 SDK,无需安装任何包。先渲染第一个可玩帧并准备好输入,然后再调用 sdk.host.ready()。宿主暂停时暂停模拟,恢复时不要产生重复循环,并遵循宿主的音频策略。
身份、存档和语言
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 页面介绍托管服务器;你自己运行的服务器完全不需要 SDK。旧的中继房间 API 已停用。
发布前用 SDK 测试
照常运行你的开发服务器,然后在 Chrome 中打开 https://www.playdrop.ai/creators/<username>/apps/game/<slug>/dev?url=http://localhost:5173/,即可在真实的 PlayDrop 框架中配合 SDK 宿主游玩。任何 localhost 端口或 https URL 都适用。需要账户的功能(例如存档和购买)在游戏上传过一次后即可使用;私人上传就足够了。浏览器端媒体生成以异步任务运行,并附带经宿主确认的点数费用。商店页面元数据请参阅 catalogue.json。
一起玩
在游戏阶段使用 await sdk.multiplayer.join("game"),可独立加入房间或使用宿主的队伍预留。队伍加入失败时会拒绝请求,不会悄悄把玩家分到其他房间。现有游戏仍可通过 getConnection() 立即获取连接信息。各回合之间应保留同一房间;宿主界面暂停游戏输入时也应保持网络连接。
由玩家操作触发 sdk.social.openParty(),可打开宿主的队伍弹窗。使用 await sdk.social.getParty() 或 sdk.social.onPartyChange(callback) 读取成员。游戏不能修改平台队伍或控制麦克风。队伍和房间语音由网页或原生宿主管理,并遵循玩家同意、静音、屏蔽和功能开放条件。
要实现流畅的空间语音,请使用有限的 { x, y, z } 向量调用 sdk.multiplayer.voice.updateSpatialState({ listener: { position, forward, up }, speakers: [{ userId, position }] })。这些提示只影响音量和声像,不影响授权。服务器负责实施队伍和距离条件。
使用 sdk.device.localPlayers 和 sdk.device.onLocalPlayersChange(callback) 获取选定的本地控制器槽位 { playerIndex, gamepadKey }。已连接控制器清单是独立的;断开的槽位仍保留其标识。本地模式不能加入在线房间。可复制的 playdrop-metagame/recipes/play-together 示例展示两种模式、两个目的地和房间策略。
控制器
在所有平台上都通过 sdk.device 以相同方式读取实体控制器和 PlayDrop 手机控制器。在 init() 之后调用一次 enableControllerInput(),在游戏循环中读取 gamepad(playerIndex)(0 表示 P1),并用 onButton 处理按下和松开。摇杆轴和按键遵循浏览器的标准手柄顺序;按键按位置命名,例如 south 和 east,pad.label("south") 会返回该控制器上的按键名称,例如 "A" 或 "Cross"。菜单键由 PlayDrop 使用,按下会暂停游戏。
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 传给游戏,游戏直接读取浏览器 API 时 PlayDrop 会记录警告。如果宿主无法提供控制器输入,enableControllerInput() 会以 controller_input_unavailable 或 controller_input_timeout 拒绝,游戏会继续运行。pad.has("dpad") 可判断某个操控是否存在;请在 catalogue.json 中声明游戏所需的操控。