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 です。
一時停止と再開
onPause(reason) と onResume(reason) は、プレイヤーが一時停止メニューを開いたとき、タブを隠したとき、サインインしたとき、何かを購入したとき、または広告や PlayDrop のウィンドウがゲームを覆ったときに呼ばれます。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 の一時停止メニューに使われます。ゲームで割り当てないでください。ネットワーク対応のゲームでは、一時停止中もルームの接続を維持してください。1人のプレイヤーが一時停止しても、ほかのプレイヤーを止めてはいけません。
オーディオ
init() のあとに sdk.host.audioAllowed を1回読み取り、その後は onAudioAllowedChange に従います。この値はプレイヤーのミュート、フェーズ、一時停止をまとめたもので、タブが隠れたことによる一時停止中は true のままなので、音楽は再生位置を保てます。理由やホストの音量も必要な場合は、onAudioPolicyChange が { enabled, reason, volume } を通知します。
const audio = new AudioContext();
function setAudio(allowed) {
(allowed ? audio.resume() : audio.suspend()).catch(() => {});
}オーディオはホストが許可するまでミュートで始まり、さらにブラウザでは、音が鳴る前にプレイヤーの操作が必要です。ゲーム内の音量設定は、追加の上限として残してください。ホストのミュートが常に優先されます。拒否された play() と resume() の Promise は catch してください。
アプリでの事前読み込みとオフラインプレイ
ネイティブアプリは、ゲームの開始前にファイルをダウンロードし、オフラインで遊べるよう保存しておけます。ファイルは 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 でわかります。ウェブでは何も起きず、ミュートとは関係なく動作します。