# دورة حياة اللعبة على PlayDrop: التحميل والجاهزية والإيقاف والصوت

هيّئ PlayDrop SDK، وأعلن الجاهزية عند أول إطار قابل للعب، وأوقف مؤقتًا واستأنف بسلاسة، واتبع سياسة الصوت، وحمّل الملفات مسبقًا للعب دون اتصال.

Source: https://www.playdrop.ai/ar/create/learn/lifecycle

يعرض PlayDrop شاشة التحميل وقائمة الإيقاف المؤقت وزر كتم الصوت ونوافذ أخرى خاصة به حول لعبتك. وتُبقي واجهة دورة الحياة اللعبة متوافقة معها: تتوقف اللعبة عندما يوقفها PlayDrop مؤقتًا، ولا تشغّل الصوت إلا عندما تسمح سياسة الصوت في PlayDrop بذلك.

## هيّئ، ثم أعلن الجاهزية

حمّل SDK، واقرأ الحالة الأولية، واشترك في التغييرات، وجهّز الشاشة الأولى، وبعد ذلك فقط استدعِ `ready()`. يُبقي PlayDrop شاشة التحميل ظاهرة حتى ذلك الحين.

```html
<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` في إطار التطوير المحلي.

## الإيقاف المؤقت والاستئناف

تنطلق `onPause(reason)` و`onResume(reason)` عندما يفتح اللاعب قائمة الإيقاف المؤقت، أو يخفي التبويب، أو يسجّل الدخول، أو يشتري شيئًا، أو عندما يغطي إعلان أو نافذة من PlayDrop اللعبة. قيمة `reason` واحدة من `tab_hidden` أو `auth_prompt` أو `purchase_flow` أو `host_overlay` أو `detail_hidden` أو `route_change` أو `native_background`؛ وتمثل `sdk.host.isPaused` الحالة الحالية.

أثناء الإيقاف المؤقت، أوقف المحاكاة والمؤقتات. وعند الاستئناف، أعد ضبط ساعة الإطارات حتى لا تقفز اللعبة إلى الأمام:

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

مفتاح Escape وزر Menu في وحدة التحكم مخصصان لقائمة الإيقاف المؤقت في PlayDrop؛ فلا تربطهما بشيء في لعبتك. وفي اللعبة الشبكية، أبقِ الاتصال بالغرفة قائمًا أثناء الإيقاف المؤقت: يجب ألا يؤدي إيقاف لاعب واحد إلى إيقاف الآخرين.

## الصوت

اقرأ `sdk.host.audioAllowed` مرة واحدة بعد `init()`، ثم اتبع `onAudioAllowedChange`. تجمع هذه القيمة بين كتم اللاعب للصوت والمرحلة والإيقاف المؤقت، وتبقى true أثناء الإيقاف بسبب إخفاء التبويب حتى تحتفظ الموسيقى بموضعها. وتبلّغ `onAudioPolicyChange` عن `{ enabled, reason, volume }` عندما تحتاج أيضًا إلى السبب أو مستوى صوت المضيف.

```js
const audio = new AudioContext();
function setAudio(allowed) {
  (allowed ? audio.resume() : audio.suspend()).catch(() => {});
}
```

يبدأ الصوت مكتومًا حتى يسمح به المضيف، وما زالت المتصفحات تحتاج إلى تفاعل من اللاعب قبل تشغيل الصوت. احتفظ بأي إعداد لمستوى الصوت داخل اللعبة بوصفه حدًا إضافيًا؛ فكتم الصوت من المضيف له الأولوية دائمًا. والتقط الوعود المرفوضة من `play()` و`resume()`.

## التحميل المسبق واللعب دون اتصال في التطبيقات

تستطيع التطبيقات الأصلية تنزيل ملفات اللعبة قبل بدئها والاحتفاظ بها للعب دون اتصال. صرّح بها في [catalogue.json](https://www.playdrop.ai/ar/create/learn/catalogue-json):

```json
{
  "prefetch": { "required": ["game.js", "assets/level-1.png"], "optional": ["assets/music.mp3"] },
  "offlineSupported": true
}
```

صفحة الدخول مضمّنة دائمًا. تُجلب ملفات `required` قبل اللعب، وملفات `optional` بعده. ويتيح `offlineSupported: true` للتطبيقات أن تعرض اللعبة دون اتصال بعد تخزين ملفاتها المطلوبة. وتُتجاهل القيم غير الصالحة ولا تمنع الرفع أبدًا. أما الموقع فيحمّل الألعاب كالمعتاد. وفي ألعاب [Instant](https://www.playdrop.ai/ar/create/learn/instant-games)، تمثل الملفات المطلوبة حجم البدء.

في البيئات المضيفة التي تعلن دعم بيانات الجهاز، يبقى الحفظ والنقاط والإنجازات التي تتم دون اتصال على الجهاز وتُزامن عند عودة الاتصال؛ ولا تعرض لوحات المتصدرين دون اتصال إلا أفضل نتيجة للاعب نفسه. وفي المتصفح لا يوجد طابور للعمل دون اتصال، لذا عالج فشل الحفظ. وكل ما تحمّله اللعبة من الإنترنت ما زال يحتاج إلى اتصال.

## الاهتزاز

في التطبيقات الأصلية، تعطي `sdk.haptics.selection()` و`impact("light" | "medium" | "heavy")` و`notification("success" | "warning" | "error")` استجابة اهتزازية قصيرة؛ وتبيّن `sdk.haptics.supported` هل يستطيع المضيف ذلك. لا تفعل شيئًا على الويب، وهي مستقلة عن كتم الصوت.

## أدلة ذات صلة

- [ملء الشاشة والمناطق الآمنة](https://www.playdrop.ai/ar/create/learn/viewport): اجعل لعبة PlayDrop تملأ الشاشة، وأبقِ واجهة اللعب داخل مناطق CSS الآمنة وبعيدًا عن أدوات تحكم المضيف باستخدام reservedCorners المقيسة من SDK.
- [الحفظ السحابي](https://www.playdrop.ai/ar/create/learn/cloud-saves): احفظ تقدم اللاعب وحمّله باستخدام sdk.me.appData وupdateAppData، للضيوف والمسجّلين، مع قواعد الكتابة والمعاينات واللعب دون اتصال.
- [ألعاب Instant](https://www.playdrop.ai/ar/create/learn/instant-games): ما يجعل لعبة PlayDrop من ألعاب Instant: اللعب العمودي ودخول الضيوف و10 MiB كحد أقصى لملفات البدء والبدء خلال ثانيتين، والفرق عن الألعاب العادية.
- [SDK للعميل](https://www.playdrop.ai/ar/create/learn/sdk): مرجع PlayDrop SDK للمتصفح: دورة حياة المضيف والهوية والحفظ ووحدات التحكم والتواصل واللعب الجماعي والمتجر والإعلانات ولوحات المتصدرين والأصول والذكاء الاصطناعي.
