導入範例

Ad Placement API 旨在為 AdSense 和 AdMob 開發人員提供插頁式廣告和獎勵廣告,支援在網頁或 HTML5 遊戲中使用 HTML5 遊戲。此範例說明如何將 Ad Placement API 整合到遊戲中,並使用該 API 放置插頁式廣告。

必要條件

開始之前,請備妥下列項目:

  • 在相同目錄中建立兩個空白檔案:
    • index.html
    • game.js
  • 在本機安裝 Python,或使用網路伺服器進行測試

應用程式程式碼範例

AdMob 發布商可下載範例應用程式,進一步瞭解這個 API 可如何融入遊戲中。

下載應用程式程式碼範例

1. 啟動開發環境

由於 Ads Placement API 是透過與載入其頁面相同的通訊協定載入依附元件,因此您必須使用網路伺服器測試應用程式。您可以使用 Python 的內建伺服器建立本機開發環境。

  1. 開啟終端機。

  2. 前往包含 index.html 檔案的目錄,然後執行下列指令:

    python -m http.server 8000
    
  3. 使用網路瀏覽器前往 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 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>

修改 game.js 以便在點擊「Play」按鈕時遊玩硬幣翻轉遊戲。

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 時,應該會看到遊戲面板和「Play」按鈕。如果按下 [開始],錢幣翻轉遊戲就會開始播放。

3. 匯入 Ad Placement API

接下來,請將 index.html 指令碼標記插入 game.js 之前,在您的 Ad Manager 遊戲中新增 Ad Placement API。

指令碼標記可以採用多種參數。系統會使用以下參數來指定 AdSense 資源代碼,並啟用測試模式:

  • data-ad-client=<AdSense property code> 您的 AdSense 資源代碼。即使是在應用程式內執行的遊戲,也一律需要這項權限。
  • data-adbreak-test="on" 啟用測試模式。對於遊戲,請將此項目移除。

設定 AdSense 程式碼並開啟測試模式

Ad Placement API 功能包含在 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 網頁中,請務必在 iframe 元素中加入 allow='autoplay'。這是最佳做法,而且某些廣告必須符合取得遊戲的資格。

<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 自訂分頁中執行。Ad Placement API 可偵測遊戲的執行環境,並正確處理廣告請求。如果您的遊戲是在一般網路瀏覽器中執行,則廣告請求會視為一般 AdSense 要求。如果 Ad Placement API 偵測到應用程式內環境,就會與 GMA SDK 通訊 (如果有這類請求),請求及顯示 AdMob 廣告。

目前,凡是與 AdMob GMA SDK 連結的 Android 應用程式都支援這項功能。如要啟用這項功能,您必須使用 GMA SDK 註冊要用來顯示遊戲的 WebView,然後設定 AdMob 廣告單元,並將其視為額外參數傳遞至 AdSense 代碼。如果您的遊戲是在適當的應用程式中執行,Ad Placement API 會使用這些廣告單元放送廣告。

如要啟用行動裝置支援功能,您必須指定下列其他標記參數:

  • data-admob-interstitial-slot=<AdMob slot ID> 您先前設定的 AdMob 插頁式廣告單元 ID。
  • data-admob-rewarded-slot=<AdMob slot ID> AdMob 獎勵廣告單元 ID。

請務必一律使用 data-ad-client 參數傳送 AdSense 資源代碼,且至少須指定 data-admob-interstitial-slotdata-admob-rewarded-slot。如果遊戲同時使用這兩種格式,應同時指定這兩個參數。

您也可以選擇指定 data-admob-ads-only=on 代碼參數,指出遊戲只應顯示來自 AdMob 的廣告,並且不要在不支援 AdMob 請求的環境中播放 AdSense 請求的廣告 (例如未設定 AdMob GMA SDK 的非應用程式環境或應用程式)。

重要事項:如果您將遊戲設計為嵌入應用程式,且本身就是應用程式的擁有者,或即將與應用程式擁有者簽訂收益分潤協議,則唯一需要以高效能且符合政策規定的方式進行,請使用這項 AdMob 支援。

首先,請使用 GMA SDK 註冊要顯示遊戲的 WebView:

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() 呼叫會將遊戲目前的設定傳遞至 Ad Placement 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>
    <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 提供的控制項會隨時間改變)

新增插頁式廣告,以便在遊戲重新啟動時顯示:在 play() 函式中呼叫 adBreak(),這個遊戲只會在遊戲遊玩一次後執行。

您必須在使用者動作中呼叫 adBreak() (例如點選「播放」按鈕),否則 API 將無法要求及顯示廣告。

建立要在廣告插播之前和之後呼叫的函式,然後在 adBreak() 刊登位置設定中使用這些函式。但請注意,只有在找到合適的廣告時,才會呼叫 beforeAdafterAd 函式。

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

硬幣翻轉應用程式正在建立廣告刊登位置,以便顯示廣告。

遊戲結束後,自家應用程式可能有其他合適的廣告位置。在這些位置呼叫 adBreak() 應與本範例類似。

關閉正式版應用程式測試

發布應用程式前,請務必移除 index.html 中的 data-adbreak-test="on" 這一行,或將其註解排除,因為此程式碼會在實際工作環境中開啟測試設定。