مثال على التنفيذ

تم تصميم واجهة Ad Placement API لدعم مطوّري AdSense وAdMob الذين يستخدمون الإعلانات البينية والإعلانات بمكافأة في ألعاب HTML5 على الويب أو داخل التطبيقات. يوضح هذا المثال كيفية دمج واجهة برمجة التطبيقات لموضع الإعلان في لعبة واستخدامها لوضع إعلان بيني.

المتطلبات الأساسية

قبل البدء، ستحتاج إلى ما يلي:

  • إنشاء ملفين فارغين في الدليل نفسه:
    • index.html
    • اللعبة.js
  • تثبيت Python محليًا أو استخدام خادم ويب لاختبار التنفيذ

نموذج رمز التطبيق

يمكن لناشري AdMob تنزيل نموذج رمز التطبيق لفهم كيفية دمج واجهة برمجة التطبيقات في لعبة تطبيقات بشكل أفضل.

تنزيل نموذج رمز التطبيق

1- بدء تشغيل خادم التطوير

نظرًا لأن واجهة برمجة التطبيقات لمواضع الإعلانات في "إعلانات Google" تحمِّل الاعتماديات على البروتوكول نفسه الذي يتم تحميل الصفحة عليه، عليك استخدام خادم ويب لاختبار تطبيقك. ويمكنك استخدام خادم Python&hl=ar المضمّن لإنشاء بيئة تطوير محلية.

  1. افتح محطة الدفع.

  2. انتقِل إلى الدليل الذي يحتوي على ملف index.html، ثم نفِّذ ما يلي:

    python -m http.server 8000
    
  3. في متصفّح الويب، انتقِل إلى localhost:8000.

يمكنك أيضًا استخدام أي خادم ويب آخر، مثل خادم HTTP في Apache.

2. إنشاء لعبة HTML5

تعديل index.html لإنشاء عنصر لوحة HTML5 وزر لتشغيل اللعبة. وبعد ذلك، أضِف علامة النص البرمجي اللازمة لتحميل ملف game.js.

index.html

<!doctype html>
<html lang="en">
  <head>
    <title>Ad Placement API HTML5 demo</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
  </head>
  <body>
    <canvas id="gameContainer" height="300px" width="300px"></canvas>
    <button id="playButton">Play</button>
    <button style="display:none" id="headsButton">Heads</button>
    <button style="display:none" id="tailsButton">Tails</button>

    <script src="game.js"></script>
  </body>
</html>

عدِّل اللعبة.js لتشغيل لعبة تقلب العملة عند النقر على الزر "تشغيل&quot؛

اللعبة.js

// Create a coin flip game
class Game {
  constructor() {
    // Define variables
    this.score = 0;
    this.choice = '';

    this.canvas = document.getElementById('gameContainer').getContext('2d');
    this.canvas.font = '24px Arial';

    this.playButton = document.getElementById('playButton');
    this.headsButton = document.getElementById('headsButton');
    this.tailsButton = document.getElementById('tailsButton');

    // On click listeners for the game's buttons.
    this.playButton.addEventListener('click', () => {
      this.erase();
      this.play();
    });

    this.headsButton.addEventListener('click', () => {
      this.choice = 'Heads';
      this.flipCoin();
    });

    this.tailsButton.addEventListener('click', () => {
      this.choice = 'Tails';
      this.flipCoin();
    });

    this.erase();
  }

  // Start the game
  play() {
    this.score = 0;
    this.canvas.fillText('Score: ' + this.score, 8, 26);
    this.canvas.fillText('Heads or Tails?', 66, 150);
    this.playButton.style.display = 'none';
    this.headsButton.style.display = 'inline-block';
    this.tailsButton.style.display = 'inline-block';
  }

  // Flip the coin
  flipCoin() {
    this.headsButton.disabled = true;
    this.tailsButton.disabled = true;
    this.erase();
    this.canvas.fillText('Score: ' + this.score, 8, 26);
    this.canvas.fillText('Flipping coin . . .', 60, 150);

    setTimeout(() => { this.coinLanded() }, 2000);
  }

  // Logic for when the coin lands
  coinLanded() {
    this.headsButton.disabled = false;
    this.tailsButton.disabled = false;
    let sideUp;
    if(Math.random() < 0.5) {
      sideUp = 'Heads';
    } else {
      sideUp = 'Tails';
    }

    if (sideUp === this.choice ) {
      this.win(sideUp);
    } else {
      this.lose(sideUp);
    }
  }

  // Guess the flip correctly
  win(sideUp) {
    this.erase();
    this.score += 1;
    this.canvas.fillText('Score: ' + this.score, 8, 26);
    this.canvas.fillText('It was ' + sideUp + '!', 66, 150);
    this.canvas.fillText('Guess again', 70, 200);
  }

  // Guess the flip incorrectly
  lose(sideUp) {
    this.erase();
    this.canvas.fillText('Sorry, it was ' + sideUp, 50, 100);
    this.canvas.fillText('Your score was ' + this.score, 50, 150);
    this.canvas.fillText('Want to play again?', 45, 200);

    this.playButton.style.display = 'inline-block';
    this.headsButton.style.display = 'none';
    this.tailsButton.style.display = 'none';
  }

  // Erase the canvas
  erase() {
    this.canvas.fillStyle = '#ADD8E6';
    this.canvas.fillRect(0, 0, 300, 300);
    this.canvas.fillStyle = '#000000';
  }
}

const game = new Game();

بعد إكمال هذه الخطوة، وعند فتح index.html في المتصفّح (من خلال خادم التطوير)، من المفترض أن تظهر لك لوحة اللعبة والزر "&&تشغيل": في حال النقر على "تشغيل"، من المفترض أن تبدأ اللعبة بقطع النقود المعدنية.

3- استيراد واجهة برمجة التطبيقات لموضع الإعلان

بعد ذلك، أضِف Ad Placement API إلى لعبتك من خلال إدراج علامة نص برمجي في index.html، قبل علامة game.js.

يمكن أن تأخذ علامة النص البرمجي عددًا من المعلّمات. سنستخدم المعلَمات التالية لتحديد رمز موقع AdSense وتفعيل وضع الاختبار:

  • data-ad-client=<AdSense property code> رمز موقعك الإلكتروني على AdSense ويكون هذا مطلوبًا دائمًا حتى للألعاب التي سيتم تشغيلها داخل التطبيقات.
  • data-adbreak-test="on" تفعيل وضع الاختبار. عليك إزالة هذه الميزة في الألعاب بعد أن يتم عرضها للاعبين.

إعداد رمز AdSense وتفعيل وضع الاختبار

يتم تضمين وظيفة واجهة برمجة التطبيقات لموضع الإعلان في رمز AdSense. لتفعيل هذه الميزة، عليك أولاً إضافة رمز AdSense وتضمين مقتطف نص برمجي صغير يضبط وظائفه الرئيسية: adBreak() وadConfig().

index.html (الويب)

 [...]
    <canvas id="gameContainer" height="300px" width="300px"></canvas>
    <button id="playButton">Play</button>
    <button style="display:none" id="headsButton">Heads</button>
    <button style="display:none" id="tailsButton">Tails</button>

    <script async
      data-adbreak-test="on"
      src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-123456789"
      crossorigin="anonymous">
    </script>
    <script>
      window.adsbygoogle = window.adsbygoogle || [];
      const adBreak = adConfig = function(o) {adsbygoogle.push(o);}
    </script>
    <script src="game.js"></script>
  </body>
</html>

تضمين لعبتك (اختياري)

إذا أردت تضمين لعبة في صفحات أخرى داخل إطار iframe، وكانت العلامة adsbygoogle ضمن صفحة HTML للعبة، تأكد من إضافة allow='autoplay' إلى عنصر إطار iframe. هذه من أفضل الممارسات، وهي ضرورية لعرض إعلانات معيَّنة حتى تكون مؤهَّلة للعبتك.

<head>
  <!-- The adsbygoogle tag is not here -->
</head>
<body>
  <iframe src="https://www.my-game.com" title="My game" allow="autoplay">
    <!-- The game is loaded here and contains the adsbygoogle tag -->
  </iframe>
</body>

دعم التطبيقات المتوافقة مع الأجهزة الجوّالة

ويمكن تشغيل لعبة H5 في متصفح ويب عادي أو في علامة تبويب WebView أو Chrome مخصّصة داخل تطبيق. ويمكن أن تكتشف واجهة برمجة التطبيقات لمواضع الإعلانات في البيئة التي تعمل فيها لعبتك وتوجّه طلبات الإعلان بشكل مناسب. وإذا كانت لعبتك تعمل ضمن متصفّح ويب عادي، سيتم التعامل مع طلبات الإعلان على أنها طلبات عادية من AdSense. وإذا اكتشفت واجهة برمجة التطبيقات لموضع الإعلان بيئة داخل التطبيق، فإنها تتواصل مع حزمة تطوير البرامج (SDK) لإعلانات Google على الأجهزة الجوّالة، إذا كانت موجودة، لطلب إعلانات AdMob وعرضها.

في الوقت الحالي، هذه الإمكانية متاحة في تطبيقات Android التي تم ربطها بحزمة تطوير البرامج (SDK) لإعلانات Google على الأجهزة الجوّالة من AdMob. ولتفعيله، عليك تسجيل WebView الذي سيعرض لعبتك باستخدام حزمة تطوير البرامج (SDK) لإعلانات Google على الأجهزة الجوّالة، ثم ضبط وحدات AdMob الإعلانية وتمريرها إلى معلَمات إضافية إلى علامة AdSense. عندما يتم تشغيل لعبتك داخل تطبيق مناسب، ستستخدم Ad Placement API هذه الوحدات الإعلانية لعرض الإعلانات.

لتفعيل التوافق مع الأجهزة الجوّالة، يجب تحديد معلمات العلامة الإضافية التالية:

  • data-admob-interstitial-slot=<AdMob slot ID> رقم تعريف الوحدة الإعلانية البينية على AdMob التي تم ضبطها مسبقًا.
  • data-admob-rewarded-slot=<AdMob slot ID> رقم تعريف الوحدة الإعلانية بمكافأة في AdMob.

ويجب دائمًا تمرير رمز موقعك على AdSense باستخدام المعلَمة data-ad-client ويجب تحديد واحدة على الأقل من data-admob-interstitial-slot أو data-admob-rewarded-slot. يجب تحديد كلتا المعلّمتَين إذا كانت لعبتك تستخدم التنسيقَين.

اختياريًا، يمكنك أيضًا تحديد معلَمة علامة data-admob-ads-only=on للإشارة إلى أن لعبتك يجب أن تعرض الإعلانات من AdMob فقط وليس على AdSense في الحالات التي يتم فيها تشغيل اللعبة في بيئة لا تتوافق مع طلبات AdMob (مثل البيئات غير التابعة للتطبيقات أو التطبيقات التي لم يتم فيها ضبط AdMob SDK لإعلانات Google على الأجهزة الجوّالة).

ملاحظة مُهمة: عندما تصمّم لعبتك لتضمينها في تطبيق وتملك التطبيق، أو إذا كنت تبرم اتفاقية مشاركة أرباح مع مالك التطبيق، ستكون الطريقة الوحيدة لتنفيذ ذلك بطريقة عالية الأداء ومتوافقة مع السياسة هي استخدام دعم AdMob هذا.

أولاً، سجِّل WebView الذي سيعرض لعبتك باستخدام حزمة تطوير البرامج (SDK) لإعلانات Google على الأجهزة الجوّالة (GMA):

MainActivity.java (تطبيق)

...
public void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    webView = findViewById(R.id.webview_minigame);

    WebSettings settings = webView.getSettings();
    settings.setJavaScriptEnabled(true);

    h5AdsWebViewClient = new H5AdsWebViewClient(this, webView);
    webView.setWebViewClient(h5AdsWebViewClient);

    h5AdsWebViewClient.setDelegateWebViewClient(pubWebViewClient);

بعد ذلك، عليك بتمرير وحدات AdMob الإعلانية (واحدة للإعلانات البينية وأخرى للإعلانات بمكافأة) على النحو التالي:

index.html (تطبيق)

 [...]
    <canvas id="gameContainer" height="300px" width="300px"></canvas>
    <button id="playButton">Play</button>
    <button style="display:none" id="headsButton">Heads</button>
    <button style="display:none" id="tailsButton">Tails</button>
    <script async
      data-admob-interstitial-slot="ca-app-pub-0987654321/1234567890"
      data-admob-rewarded-slot="ca-app-pub-0987654321/0987654321"
      src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-123456789"
      crossorigin="anonymous">
    </script>
    <script>
      window.adsbygoogle = window.adsbygoogle || [];
      const adBreak = adConfig = function(o) {adsbygoogle.push(o);}
    </script>
    <script src="game.js"></script>
  </body>
</html>

4. إجراء مكالمة إلى adConfig()

يستدعي طلب adConfig() الضبط الحالي للعبة إلى واجهة برمجة تطبيقات موضع الإعلان. ويمكن لواجهة برمجة التطبيقات بعد ذلك استخدام هذه المعلومات لفلترة أنواع الإعلانات التي تطلبها لتلائم اللعبة (مثل إعلانات الفيديو التي تتطلّب صوتًا، في حال تفعيل الصوت).

ويجب إجراء مكالمة إلى adConfig() في أي وقت يتغير فيه هذا الإعداد، مثلاً عندما يكتم المستخدم صوت اللعبة أو يعيد الصوت إليها. يمكنك الاتصال بـ adConfig() في منشئ اللعبة، ثم إضافة زر لكتم صوت اللعبة وإعادة صوتها لإجراء مكالمة adConfig() إضافية.

اللعبة.js

class Game {
  constructor() {
    // Define variables
    this.score = 0;
    this.choice = '';
    this.muted = false;

    this.canvas = document.getElementById('gameContainer').getContext('2d');
    this.canvas.font = '24px Arial';

    this.playButton = document.getElementById('playButton');
    this.headsButton = document.getElementById('headsButton');
    this.tailsButton = document.getElementById('tailsButton');
    this.muteButton = document.getElementById('muteButton');

    adConfig({
      sound: 'on',
    });

    // On click listeners for the game's buttons.
    this.playButton.addEventListener('click', () => {
      this.erase();
      this.play();
    });

    this.headsButton.addEventListener('click', () => {
      this.choice = 'Heads';
      this.flipCoin();
    });

    this.tailsButton.addEventListener('click', () => {
      this.choice = 'Tails';
      this.flipCoin();
    });

    this.muteButton.addEventListener('click', () => {
      var soundString = this.muted ? 'on' : 'off';
      this.muteButton.innerHTML = this.muted ? 'Mute sound' : 'Un-mute sound';
      this.muted = !this.muted;
      adConfig({
        sound: soundString,
      });
    });

    this.erase();
  [...]

والآن، أضِف زر كتم الصوت إلى ملف HTML.

index.html

[...]
    <canvas id="gameContainer" height="300px" width="300px"></canvas>
    <button id="playButton">Play</button>
    <button style="display:none" id="headsButton">Heads</button>
    <button style="display:none" id="tailsButton">Tails</button>
    <button id="muteButton">Mute sound</button>

    <script async
      data-adbreak-test="on"
      src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-123456789"
      crossorigin="anonymous">
    </script>
[...]

5. إجراء مكالمة مع adBreak() عند انتهاء اللعبة

تحدّد الاستدعاء adBreak() موضع إعلان ويأخذ العنصر الذي يُسمّى "ضبط موضع الإعلان" والذي يحدّد كل ما هو مطلوب لعرض إعلان في هذه المرحلة في لعبتك. سيسمح لك دعم أنواع مختلفة من الإعلانات بإعداد مجموعات فرعية مختلفة من إعدادات مواضع الإعلانات.

تحدّد المكالمة adBreak() موضع عرض الإعلان، أو بمعنى آخر، فرصة لعرض الإعلان. يعتمد ظهور الإعلان على عدد من العوامل:

  • نوع موضع الإعلان الذي أعلنته.
  • إذا كان هناك تفاعلات مناسبة من المستخدمين قبل موضع الإعلان هذا.
  • سواء كان هناك إعلان مناسب للمشغّل الحالي، فإنّ:
    • تكون ملائمة له
    • يتوافق مع إعدادات خصوصية البيانات والموافقة.
  • عدد الإعلانات التي شاهدها المستخدم مؤخرًا.
  • إعدادات التحكُّم التي ضبطتها لهذه اللعبة إما:
    • تلميحات في العلامة
    • في AdSense (ملاحظة: ستتطوّر عناصر التحكّم المتوفرة في AdSense بمرور الوقت)

أضِف رمزًا لإعلان بيني ليتم عرضه عند إعادة تشغيل اللعبة: أجرِ مكالمة على adBreak() داخل الدالة play()، والتي لا يتم تشغيلها إلا بعد تشغيل اللعبة مرة واحدة.

يجب طلب adBreak() كجزء من إجراء المستخدم، مثل النقر على الزر "تشغيل"، وإلا، لن تتمكّن واجهة برمجة التطبيقات من طلب الإعلانات وعرضها.

أنشئ دوالًا ليتم طلبها قبل الفاصل الإعلاني وبعده، وستستخدمه عندئذٍ في ضبط موضع الإعلان adBreak(). وتجدر الإشارة إلى أنه لن يتم استدعاء الدالتَين beforeAd وafterAd إلا إذا تم العثور على إعلان مناسب.

اللعبة.js

class Game {
  constructor() {
    // Define variables
    this.score = 0;
    this.choice = '';
    this.muted = false;
    this.shouldShowAdOnPlay = false;

  [...]

  // Start the game
  play() {
    if (this.shouldShowAdOnPlay) {
      this.shouldShowAdOnPlay = false;

      adBreak({
        type: 'next',  // ad shows at start of next level
        name: 'restart-game',
        beforeAd: () => { this.disableButtons(); },  // You may also want to mute the game's sound.
        afterAd: () => { this.enableButtons(); },    // resume the game flow.
      });
    }

    this.score = 0;
    this.canvas.fillText('Score: ' + this.score, 8, 26);
    this.canvas.fillText('Heads or Tails?', 66, 150);
    this.playButton.style.display = 'none'
    this.headsButton.style.display = 'inline-block'
    this.tailsButton.style.display = 'inline-block'
  }

  [...]

  // Guess the flip incorrectly
  lose(sideUp) {
    this.erase()
    this.canvas.fillText('Sorry, it was ' + sideUp, 50, 100);
    this.canvas.fillText('Your score was ' + this.score, 50, 150);
    this.canvas.fillText('Want to play again?', 45, 200);

    this.playButton.style.display = 'inline-block'
    this.headsButton.style.display = 'none'
    this.tailsButton.style.display = 'none'
    this.shouldShowAdOnPlay = true;
  }

  [...]

  // Erase the canvas
  erase() {
    this.canvas.fillStyle = '#ADD8E6';
    this.canvas.fillRect(0, 0, 300, 300);
    this.canvas.fillStyle = '#000000';
  }

  enableButtons() {
    this.playButton.disabled = false;
    this.headsButton.disabled = false;
    this.tailsButton.disabled = false;
  }

  disableButtons() {
    this.playButton.disabled = true;
    this.headsButton.disabled = true;
    this.tailsButton.disabled = true;
  }
}

const game = new Game();

ينشئ تطبيق "تحويل العملات" الآن مواضع للإعلانات لكي يتم عرض الإعلانات.

قد يوفّر تطبيقك الخاص أماكن إضافية مناسبة لعرض الإعلانات غير عند انتهاء اللعبة. يجب أن يكون الاتصال بالرقم adBreak() في هذه الأماكن مشابهًا لهذا المثال.

إيقاف الاختبار لتطبيقات الإنتاج

قبل إصدار تطبيقك، من المهم إزالة السطر data-adbreak-test="on" أو تعليقه في index.html، لأن هذا الرمز يؤدي إلى تفعيل إعدادات الاختبار في مرحلة الإنتاج.