PlayDrop 上的游戏生命周期:加载、就绪、暂停和音频
初始化 PlayDrop SDK,在第一个可玩帧时发出就绪信号,干净地暂停和恢复,遵循宿主的音频策略,并为原生应用和离线游玩预加载文件。
PlayDrop 会在你的游戏周围显示自己的加载画面、暂停菜单、静音控制和其他窗口。生命周期 API 让游戏与它们保持同步:PlayDrop 暂停游戏时游戏就停下,并且只在 PlayDrop 的音频策略允许时才播放声音。
先初始化,再发出就绪信号
加载 SDK,读取初始状态,订阅变化,准备好第一个画面,然后才调用 ready()。在此之前,PlayDrop 会一直显示它的加载画面。
<script src="https://assets.playdrop.ai/sdk/playdrop.js"></script>
<script type="module">
const sdk = await playdrop.init();
let paused = sdk.host.isPaused;
setAudio(sdk.host.audioAllowed);
sdk.host.onAudioAllowedChange(setAudio);
sdk.host.onPause(() => { paused = true; });
sdk.host.onResume(() => { paused = false; last = performance.now(); });
try {
await loadFirstLevel();
} catch (error) {
sdk.host.error("Could not load the first level");
throw error;
}
drawFirstFrame();
sdk.host.ready();
</script>等你设计的第一个画面已经显示、并且输入可用时再调用 ready(),不要在素材加载完成之前调用。sdk.host.error(message) 会告诉 PlayDrop 游戏无法启动。setLoadingState 和 firstFrameReady 是同一步骤的旧名称;请使用 ready()。
阶段:预览、游玩和编辑器
sdk.host.phase 为 preview、play 或 editor,onPhaseChange 会报告阶段切换。预览和录制会在没有真实会话的情况下展示游戏:在 play 之外,绝不能写入存档、分数、成就或购买。sdk.host.mode 通常为 play,在本地 Dev 框架中为 dev。
暂停和恢复
当玩家打开暂停菜单、隐藏标签页、登录、购买东西,或者广告或 PlayDrop 窗口遮住游戏时,会触发 onPause(reason) 和 onResume(reason)。reason 为 tab_hidden、auth_prompt、purchase_flow、host_overlay、detail_hidden、route_change 或 native_background 之一;sdk.host.isPaused 是当前状态。
暂停期间,停止模拟和计时器。恢复时,重置你的帧时钟,避免游戏突然向前跳:
let last = performance.now();
function frame(now) {
const dt = paused ? 0 : Math.min((now - last) / 1000, 0.05);
last = now;
if (!paused) update(dt);
render();
requestAnimationFrame(frame);
}
requestAnimationFrame(frame);Esc 键和控制器的菜单键属于 PlayDrop 的暂停菜单;不要在游戏中绑定它们。在联网游戏中,暂停期间也要保持房间连接:一位玩家暂停不能让其他玩家停下来。
音频
在 init() 之后读取一次 sdk.host.audioAllowed,之后遵循 onAudioAllowedChange。它综合了玩家的静音设置、阶段和暂停状态;在因隐藏标签页而暂停时仍为 true,这样音乐可以保持播放位置。如果你还需要知道原因或宿主音量,onAudioPolicyChange 会报告 { enabled, reason, volume }。
const audio = new AudioContext();
function setAudio(allowed) {
(allowed ? audio.resume() : audio.suspend()).catch(() => {});
}在宿主允许之前,音频一开始是静音的;而且浏览器仍需要玩家先操作一次才能播放声音。游戏内的音量设置可以作为额外的限制保留;宿主的静音始终优先。请捕获被拒绝的 play() 和 resume() promise。
在应用中预加载和离线游玩
原生应用可以在游戏启动前下载它的文件,并保留下来供离线游玩。请在 catalogue.json 中声明这些文件:
{
"prefetch": { "required": ["game.js", "assets/level-1.png"], "optional": ["assets/music.mp3"] },
"offlineSupported": true
}入口页面始终包含在内。required 文件会在游玩前下载;optional 文件在之后下载。offlineSupported: true 让应用在保存好必需文件后提供离线游玩。无效的值会被忽略,绝不会阻止上传。网站会照常加载游戏。对于即玩游戏,必需文件的大小就是启动大小。
在声明支持设备数据的宿主上,离线时产生的存档、分数和成就会保留在设备上,并在联网后同步;离线时排行榜只显示玩家自己的最佳成绩。浏览器中没有离线队列,所以请处理存档失败的情况。游戏从互联网加载的任何内容仍然需要网络连接。
触感反馈
在原生应用中,sdk.haptics.selection()、impact("light" | "medium" | "heavy") 和 notification("success" | "warning" | "error") 可以提供短暂的触感反馈;sdk.haptics.supported 表示宿主是否支持。它们在网页上不起作用,并且与静音无关。