概要

Ad Placement API は、インタースティシャル広告の事前キャッシュと読み込みをサポートします。デベロッパーは API を使用して、ゲームなどのインタラクティブ メディアで広告ブレークとなる可能性を通知しますが、広告を表示するタイミングや表示する広告を正確に決定することは Google 側に任されています。

Ad Placement API は、ウェブ上の HTML5 ベースのゲーム、スーパーアプリなどインタラクティブ メディアでインタースティシャル広告を使用する AdSense デベロッパーをサポートするために準備されました。 このガイドでは、Ad Placement API をシンプルなゲームに組み込む方法を説明します。

前提条件

前提条件は次のとおりです。

  • 以下の空のファイルを作成すること:
    • index.html
    • game.js
  • Python がパソコン、またはテストに使用するウェブサーバーにインストールされている。

1. 開発用サーバーを起動する

Ads Placement API は、読み込まれたページと同じプロトコルを介して依存関係を読み込むため、ウェブサーバーを使用してアプリをテストする必要があります。ローカルの開発用サーバーを起動する最も簡単な方法は、Python が組み込みまれているサーバーを使用することです。

  1. index.html ファイルを含むディレクトリから次のコマンドを実行します。
    python -m http.server 8000
  2. ウェブブラウザで http://localhost:8000/ にアクセスします。

Apache HTTP Server などの他のウェブサーバーも使用できます。

2. シンプルな HTML5 キャンバスのゲームを作成する

index.html を変更して、シンプルな HTML5 キャンバス要素と、ゲームプレイをトリガーするボタンを作成します。また、game.js ファイルを読み込むために必要なスクリプトタグを追加します。

index.html

<!doctype html>
<html lang="en">
  <head>
    <title>Ad Placement API HTML5 simple 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>

[Play] ボタンがクリックされたときに、coin flip(コイントス)ゲームを開始するように game.js を変更します。

game.js
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 を開くと、ゲーム キャンバスと「Play」ボタンが表示されるようになります。[Play] をクリックすると、コイントス ゲームが始まります。

3.Ad Placement API をインポートする

index.html で、game.js のタグの前にスクリプトタグを挿入して、ゲームに Ad Placement API を追加します。

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-ad-client="ca-pub-123456789"
      data-adbreak-test="on"
      src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js">
    </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() 呼び出しにより、ゲームの現在の設定が Ad Placement API に伝えられます。API はこの情報を使用して、リクエストする広告の種類をフィルタし、ゲームに適したもの(音声が有効であれば、音声が必要な動画広告など)を選別します。adConfig() の呼び出しは、ゲームアプリが初期化された場合や、設定が変更された場合(ユーザーがゲームをミュートまたはミュート解除したときなど)に、必ず行う必要があります。具体的には、ゲームのコンストラクタで adConfig() を呼び出してから、広告をミュート / ミュート解除するボタンを追加し、そのボタンの動作の中でさらに adConfig() を呼び出します。

現在のところ、adConfig() が受け取るのは 'on''off' の値を受け入れる sound パラメータのみです。音声が設定されていない場合、デフォルトで off になります。API の今後のリリースでさらにパラメータが追加される予定です。

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>
    <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-ad-client="ca-pub-123456789"
      data-adbreak-test="on"
      src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js">
    </script>
    ...

5. ゲームの終了時に adBreak() を呼び出す

adBreak() の呼び出しは広告プレースメントを定義し、プレースメント設定と呼ばれるオブジェクトを受け取ります。このオブジェクトにより、その時点でゲームに広告を表示するために必要な要素がすべて指定されます。さまざまなタイプの広告に対応するには、プレースメント設定のさまざまなサブセットを初期化する必要があります。具体的なサブセットについては、adBreak プレースメント設定ガイドをご覧ください。

adBreak() 呼び出しにより、広告を表示できる可能性のあるプレースメント、つまり広告を表示する機会を定義します。広告が実際に表示されるかどうかは、次のさまざまな要素によって決まります。

  • 宣言した広告プレースメントのタイプ。
  • この広告プレースメントの前に適切なユーザー インタラクションがあったかどうか。
  • 現在のプレーヤーに適した広告が存在するかどうか。適した広告とは次のような広告のことです。
    • ユーザーに関係がある。
    • データのプライバシーと同意に関するユーザー設定と一致している。
  • ユーザーに最近表示された広告の数。
  • このゲームに設定したコントロール設定。次のいずれかになります。
    • タグ内のヒント。
    • AdSense(注: AdSense で利用可能なコントロールは今後さらに改良が加えられます)

このガイドでは、ゲームの再開時に表示されるインタースティシャル広告のコードを追加します。 そのためには、ゲームが 1 度プレイされて初めて実行される play() 関数内で adBreak() を呼び出します。adBreak() は、[Play] ボタンのクリックなどのユーザー アクションの一部として呼び出す必要があります。そうでないと、API は広告のリクエストも表示もできません。また、広告ブレークの前後に呼び出す関数を作成します。この関数は、adBreak() プレースメント設定で使用することになります。beforeBreak 関数と afterBreak 関数は、適切な広告が見つかった場合にのみ呼び出されることに留意してください。

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',
        beforeBreak: () => { this.disableButtons(); },  // You may also want to mute the game's sound.
        afterBreak: () => { 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() を呼び出す方法は、このガイドで説明した方法とほぼ同じです。 アプリをリリースする前に、本番環境でテスト設定を使用しないように、忘れずに index.htmldata-adbreak-test="on" の行を削除してください。