Пример реализации

API размещения рекламы разработан для поддержки разработчиков AdSense и AdMob, использующих полноэкранную и вознагражденную рекламу в HTML5-играх на веб-сайтах и в приложениях. В этом примере показано, как интегрировать API размещения рекламы в игру и использовать его для размещения полноэкранной рекламы.

Предпосылки

Прежде чем начать, вам понадобится следующее:

  • Создайте два пустых файла в одном каталоге:
    • index.html
    • game.js
  • Установите Python локально или используйте веб-сервер для тестирования своей реализации.

Пример кода приложения

Издатели AdMob могут загрузить пример кода приложения, чтобы лучше понять, как интегрировать API в игровое приложение.

Загрузить пример кода приложения

1. Запустите сервер разработки

Поскольку API размещения рекламы загружает зависимости по тому же протоколу, что и страница, на которой он загружается, для тестирования приложения необходимо использовать веб-сервер. Вы можете использовать встроенный сервер Python для создания локальной среды разработки.

  1. Откройте терминал.

  2. Перейдите в каталог, содержащий файл index.html, затем выполните:

    python -m http.server 8000
    
  3. В веб-браузере перейдите по адресу localhost:8000

Вы также можете использовать любой другой веб-сервер, например Apache HTTP Server .

2. Создайте игру HTML5

Измените index.html , чтобы создать элемент HTML5 Canvas и кнопку для запуска игрового процесса. Затем добавьте необходимый тег script для загрузки файла 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>
    <br>
    <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>

Измените game.js так, чтобы при нажатии кнопки «Играть» запускалась игра с подбрасыванием монетки.

game.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. Импортируйте API размещения рекламы

Затем добавьте API размещения рекламы в свою игру, вставив тег script в index.html перед тегом game.js

Тег script может принимать ряд параметров . Мы будем использовать следующие параметры для указания кода свойства AdSense и включения режима тестирования:

  • data-ad-client= <AdSense property code> Ваш код свойства AdSense. Он обязателен всегда, даже для игр, которые будут запускаться в приложениях.
  • data-adbreak-test="on" Включает режим тестирования . Удалите этот параметр для игр, когда они уже доступны игрокам.

Настройте код AdSense и включите режим тестирования.

Функциональность API размещения рекламы включена в код AdSense. Чтобы включить её, необходимо сначала добавить код AdSense и небольшой фрагмент скрипта, который инициализирует две ключевые функции: adBreak() и adConfig() .

index.html (веб)

 [...]
    <canvas id="gameContainer" height="300px" width="300px"></canvas>
    <br>
    <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 внутри приложения. API размещения рекламы может определить, в какой среде запущена ваша игра, и соответствующим образом направлять запросы на рекламу. Если ваша игра запущена в обычном веб-браузере, запросы на рекламу обрабатываются как обычные запросы AdSense. Если API размещения рекламы обнаруживает внутреннюю среду приложения, он обращается к Google Mobile Ads SDK (если он есть), чтобы запросить и показать рекламу AdMob.

Эта возможность поддерживается в приложениях Android, подключенных к Google Mobile Ads SDK. Чтобы включить её, необходимо зарегистрировать WebView , который будет отображать вашу игру, в Google Mobile Ads SDK, а затем настроить рекламные блоки AdMob и передать их в качестве дополнительных параметров тегу AdSense. При запуске игры в подходящем приложении API размещения рекламы будет использовать эти рекламные блоки для показа рекламы.

Для включения поддержки мобильных устройств необходимо указать следующие дополнительные параметры тега:

  • data-admob-interstitial-slot= <AdMob slot ID> Идентификатор рекламного блока Interstitial 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 (например, в средах, отличных от приложений, или в приложениях без настроенного Google Mobile Ads SDK).

Важно : если вы разрабатываете игру для встраивания в приложение и являетесь владельцем приложения или заключаете соглашение о разделе доходов с владельцем приложения, то единственный способ сделать это эффективно и с соблюдением политики — использовать поддержку AdMob.

Сначала зарегистрируйте WebView , который будет отображать вашу игру, с помощью Google Mobile Ads SDK:

MainActivity.java (приложение)

Настройки WebView по умолчанию не оптимизированы для рекламы. Используйте API WebSettings для настройки WebView для:

  • JavaScript
  • Доступ к локальному хранилищу
  • Автоматическое воспроизведение видео

Ява

import android.webkit.CookieManager;
import android.webkit.WebView;

public class MainActivity extends AppCompatActivity {
  private WebView webView;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    webView = findViewById(R.id.webview);

    // Let the web view accept third-party cookies.
    CookieManager.getInstance().setAcceptThirdPartyCookies(webView, true);
    // Let the web view use JavaScript.
    webView.getSettings().setJavaScriptEnabled(true);
    // Let the web view access local storage.
    webView.getSettings().setDomStorageEnabled(true);
    // Let HTML videos play automatically.
    webView.getSettings().setMediaPlaybackRequiresUserGesture(false);

    // Set the H5AdsWebViewClient.
    h5AdsWebViewClient = new H5AdsWebViewClient(this, webView);
    webView.setWebViewClient(h5AdsWebViewClient);
    h5AdsWebViewClient.setDelegateWebViewClient(pubWebViewClient);

    // Register the web view.
    MobileAds.registerWebView(webView);
  }
}

Котлин

import android.webkit.CookieManager
import android.webkit.WebView

class MainActivity : AppCompatActivity() {
  lateinit var webView: WebView

  override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)
    webView = findViewById(R.id.webview)

    // Let the web view accept third-party cookies.
    CookieManager.getInstance().setAcceptThirdPartyCookies(webView, true)
    // Let the web view use JavaScript.
    webView.settings.javaScriptEnabled = true
    // Let the web view access local storage.
    webView.settings.domStorageEnabled = true
    // Let HTML videos play automatically.
    webView.settings.mediaPlaybackRequiresUserGesture = false

    // Set the H5AdsWebViewClient.
    val h5AdsWebViewClient = H5AdsWebViewClient(this, webView)
    webView.webViewClient = h5AdsWebViewClient
    h5AdsWebViewClient.delegateWebViewClient = pubWebViewClient

    // Register the web view.
    MobileAds.registerWebView(webView)
  }
}

Затем передайте рекламные блоки AdMob (один для полноэкранной рекламы и один для рекламы с вознаграждением) следующим образом:

index.html (приложение)

 [...]
    <canvas id="gameContainer" height="300px" width="300px"></canvas>
    <br>
    <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() передаёт текущую конфигурацию игры в API размещения рекламы. API затем может использовать эту информацию для фильтрации типов запрашиваемой рекламы, чтобы она соответствовала игре (например, видеореклама со звуком, если он включён).

Вызов adConfig() следует выполнять каждый раз при изменении этой конфигурации, например, когда пользователь включает или выключает звук в игре. Вызовите adConfig() в конструкторе игры, а затем добавьте кнопку для отключения и включения звука в игре, которая будет вызывать дополнительный вызов adConfig() .

game.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>
    <br>
    <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() должен вызываться как часть действия пользователя, например нажатия кнопки «Воспроизвести», в противном случае API не сможет запрашивать и отображать рекламу.

Создайте функции, которые будут вызываться до и после рекламной паузы, и которые затем будут использоваться в конфигурации размещения adBreak() . Важно отметить, что функции beforeAd и afterAd будут вызываться только при наличии подходящей рекламы.

game.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();

6. Вызовите adBreak() для показа рекламы с вознаграждением.

Добавьте код для показа рекламы с вознаграждением, когда игра заканчивается, но пользователь хочет восстановить свой текущий счёт, а не начинать заново. Вызовите adBreak() внутри функции lose() , проверяя, доступна ли реклама с вознаграждением. Если доступна, покажите пользователю запрос на получение награды (в данном случае — восстановление), а когда пользователь согласится посмотреть рекламу, вызовите соответствующий showAdFn() . Вы можете настроить действия, которые будут выполняться, если пользователь посмотрит или пропустит рекламу с вознаграждением, с помощью обратных вызовов adViewed и adDismissed .

Новый adBreak() следует вызывать при каждой возможности показать объявление с вознаграждением. Это гарантирует обновление объявления, если предыдущее объявление устарело или было недоступно.

showAdFn() должен вызываться как часть прямого действия пользователя по просмотру рекламы, в противном случае реклама может не отображаться.

Создайте функции, которые будут вызываться до и после рекламной паузы, и которые затем будут использоваться в конфигурации размещения adBreak() . Важно отметить, что функции beforeReward , adViewed , adDismissed , beforeAd и afterAd будут вызываться только при наличии подходящей рекламы.

game.js

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

    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');
    this.continueButton = document.getElementById('continueButton');

    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.continueButton.addEventListener('click', () => {
      if (this.showRewardedAdFn) {
        this.showRewardedAdFn();
      }
    });

    this.erase();
  }

  // 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.continueButton.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;

    adBreak({
      type: 'reward',  // rewarded ad
      name: 'reward-continue',
      beforeReward: (showAdFn) => {
        this.showRewardedAdFn = () => { showAdFn(); };
        // Rewarded ad available - prompt user for a rewarded ad
        this.continueButton.style.display = 'inline-block';
      },
      beforeAd: () => { this.disableButtons(); },     // You may also want to mute the game's sound.
      adDismissed: () => {
        this.continueButton.style.display = 'none';   // Hide the reward button and continue lose flow.
      },
      adViewed: () => { this.continueGame(); },       // Reward granted - continue game at current score.
      afterAd: () => { this.enableButtons(); },       // Resume the game flow.
    });
  }

  // Continue gameplay at current score
  continueGame() {
    this.erase();
    this.canvas.fillText('Score: ' + this.score, 8, 26);
    this.canvas.fillText('Heads or Tails?', 66, 150);
    this.playButton.style.display = 'none';
    this.continueButton.style.display = 'none';
    this.headsButton.style.display = 'inline-block';
    this.tailsButton.style.display = 'inline-block';
  }
  [...]
}

const game = new Game();

Теперь добавьте кнопку «Продолжить» в ваш HTML-файл.

index.html

[...]
    <canvas id="gameContainer" height="300px" width="300px"></canvas>
    <br>
    <button id="playButton">Play</button>
    <button style="display:none" id="headsButton">Heads</button>
    <button style="display:none" id="tailsButton">Tails</button>
    <button style="display:none" id="continueButton">Watch Ad to continue?</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>
[...]

Приложение для подбрасывания монеты теперь создает места размещения рекламы для показа.

В вашем приложении могут быть дополнительные подходящие места для рекламы, помимо момента окончания игры. Вызов adBreak() в этих местах должен быть аналогичен этому примеру.

Отключить тестирование для производственных приложений

Перед выпуском приложения важно удалить или закомментировать строку data-adbreak-test="on" в index.html , так как этот код включает тестовые настройки в рабочей среде.