Implementação de exemplo

A API Ad Placement foi criada para oferecer suporte a desenvolvedores do AdSense e da AdMob que usam anúncios intersticiais e premiados em jogos HTML5 na Web ou em apps. Este exemplo demonstra como integrar a API Ad Placement a um jogo e usá-la para inserir um anúncio intersticial.

Pré-requisitos

Antes de começar, você vai precisar do seguinte:

  • Crie dois arquivos vazios no mesmo diretório:
    • index.html
    • game.js
  • Instale o Python localmente ou use um servidor da Web para testar sua implementação.

Exemplo de código do app

Os editores da AdMob podem baixar o código de um app de exemplo para entender melhor como a API pode ser integrada a um jogo para dispositivos móveis.

Baixar o exemplo de código do app

1. Iniciar um servidor de desenvolvimento

Como a API Ads Placement carrega dependências pelo mesmo protocolo da página em que é carregada, você precisa usar um servidor da Web para testar seu app. É possível usar o servidor integrado do Python para criar um ambiente de desenvolvimento local.

  1. Abra o terminal.

  2. Acesse o diretório que contém o arquivo index.html e execute:

    python -m http.server 8000
    
  3. Em um navegador da Web, acesse localhost:8000.

Você também pode usar qualquer outro servidor da Web, como o Apache HTTP Server.

2. Criar um jogo HTML5

Modifique index.html para criar um elemento de tela HTML5 e um botão para acionar o jogo. Em seguida, adicione a tag de script necessária para carregar o arquivo 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>

Modifique game.js para jogar um jogo de cara ou coroa quando o botão "Jogar" for clicado.

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

Depois de concluir essa etapa, ao abrir index.html no navegador (pelo servidor de desenvolvimento), você poderá ver a tela do jogo e o botão "Jogar". Se você clicar em "Jogar", o jogo de cara ou coroa vai começar.

3. Importar a API Ad Placement

Em seguida, adicione a API Ad Placement ao seu jogo inserindo uma tag script em index.html, antes da tag para game.js.

A tag de script pode usar vários parâmetros. Vamos usar os seguintes parâmetros para especificar o código da propriedade do AdSense e ativar o modo de teste:

  • data-ad-client=<AdSense property code> Seu código de propriedade do AdSense. Isso é sempre necessário, mesmo para jogos que serão executados em apps.
  • data-adbreak-test="on" Ativa o modo de teste. Remova isso para jogos assim que eles forem disponibilizados aos jogadores.

Configurar o código do Google AdSense e ativar o modo de teste

A funcionalidade da API Ad Placement está incluída no código do AdSense. Para ativar, primeiro adicione o código do AdSense e inclua um pequeno snippet de script que inicializa as duas funções principais: adBreak() e adConfig().

index.html (Web)

 [...]
    <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>

Incorporar seu jogo (opcional)

Se você quiser incorporar um jogo em outras páginas dentro de um iframe e a tag adsbygoogle estiver na página HTML do jogo, adicione allow='autoplay' ao elemento iframe. Essa é uma prática recomendada e necessária para que determinados anúncios se qualifiquem para seu jogo.

<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>

Compatibilidade com apps para dispositivos móveis

Um jogo H5 pode ser executado em um navegador da Web comum, em um WebView ou em uma guia personalizada do Chrome em um app. A API Ad Placement pode detectar em qual ambiente o jogo está sendo executado e direcionar as solicitações de anúncios de maneira adequada. Se o jogo estiver sendo executado em um navegador da Web comum, as solicitações de anúncios serão tratadas como solicitações normais do Google AdSense. Se a API Ad Placement detectar um ambiente no app, ela vai se comunicar com o SDK dos anúncios para dispositivos móveis do Google, se ele estiver presente, para solicitar e mostrar anúncios da AdMob.

Esse recurso é compatível com apps Android vinculados ao SDK dos anúncios para dispositivos móveis do Google. Para ativar, é necessário registrar o WebView que vai mostrar seu jogo com o SDK de anúncios para dispositivos móveis do Google e, em seguida, configurar os blocos de anúncios da AdMob e transmiti-los como parâmetros adicionais à tag do Google AdSense. Quando o jogo é executado em um app adequado, a API Ad Placement usa esses blocos de anúncios para mostrar anúncios.

Para ativar o suporte a dispositivos móveis, especifique os seguintes parâmetros de tag adicionais:

  • data-admob-interstitial-slot=<AdMob slot ID> Um ID de bloco de anúncios intersticiais da AdMob que você configurou anteriormente.
  • data-admob-rewarded-slot=<AdMob slot ID> Um ID de bloco de anúncios premiado da AdMob.

O código de propriedade do Google AdSense sempre precisa ser transmitido com o parâmetro data-ad-client, e pelo menos um dos parâmetros data-admob-interstitial-slot ou data-admob-rewarded-slot precisa ser especificado. Os dois parâmetros precisam ser especificados se o jogo usar os dois formatos.

Você também pode especificar o parâmetro de tag data-admob-ads-only=on para indicar que o jogo só deve mostrar anúncios da AdMob e não fazer fallback para o Google AdSense nos casos em que o jogo está sendo jogado em um ambiente que não oferece suporte a solicitações da AdMob (por exemplo, ambientes que não são de apps ou apps sem o SDK dos anúncios para dispositivos móveis do Google configurado).

Importante: quando você cria o jogo para ser incorporado ao seu próprio app ou quando assina um contrato de participação na receita com o proprietário do aplicativo, a única maneira de fazer isso com alto desempenho e em conformidade com a política é usar este suporte da AdMob.

Primeiro, registre a WebView que vai mostrar seu jogo com o SDK dos anúncios para dispositivos móveis do Google:

MainActivity.java (app)

As configurações padrão do WebView não são otimizadas para anúncios. Use as APIs WebSettings para configurar o WebView para:

  • JavaScript
  • Acesso ao armazenamento local
  • Reprodução automática de vídeo

Java

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

Kotlin

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)
  }
}

Em seguida, transmita os blocos de anúncios da AdMob (um para intersticiais e outro para anúncios premiados) da seguinte forma:

index.html (app)

 [...]
    <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. Faça uma chamada para adConfig()

A chamada adConfig() comunica a configuração atual do jogo à API Ad Placement. Em seguida, a API pode usar essas informações para filtrar os tipos de anúncios que ela solicita para que sejam adequados ao jogo (como anúncios em vídeo que exigem som, se o som estiver ativado).

Uma chamada precisa ser feita para adConfig() sempre que essa configuração mudar, como quando um usuário silencia ou ativa o som do jogo. Faça uma chamada para adConfig() no construtor do jogo e adicione um botão para ativar e desativar o som do jogo que faz uma chamada adConfig() adicional.

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

Agora, adicione o botão de mudo ao arquivo 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. Faça uma chamada para adBreak() quando o jogo terminar.

A chamada adBreak() define uma posição de anúncio e usa o objeto chamado configuração de posição, que especifica tudo o que é necessário para mostrar um anúncio nesse ponto do jogo. Para oferecer suporte a diferentes tipos de anúncios, é necessário inicializar diferentes subconjuntos da configuração de posição.

A chamada adBreak() define uma posição em que um anúncio pode ser exibido ou, em outras palavras, uma oportunidade de mostrar um anúncio. A exibição de um anúncio depende de vários fatores:

  • O tipo de posicionamento de anúncio que você declarou.
  • Se houver interações adequadas do usuário antes da veiculação do anúncio.
  • Se existe um anúncio adequado para o player atual que:
    • É relevante para elas.
    • É consistente com as configurações de privacidade de dados e consentimento.
  • O número de anúncios que o usuário viu recentemente.
  • As configurações de controle que você configurou para este jogo como:
    • Dicas na tag.
    • No Google AdSense. Observação: os controles disponíveis no Google AdSense vão evoluir com o tempo.

Adicione o código de um anúncio intersticial para ser mostrado quando o jogo for reiniciado: faça uma chamada para adBreak() dentro da função play(), que é executada somente depois que o jogo é jogado uma vez.

adBreak() precisa ser chamado como parte de uma ação do usuário, como clicar no botão "Reproduzir". Caso contrário, a API não poderá solicitar e mostrar anúncios.

Crie funções para serem chamadas antes e depois do intervalo do anúncio, que você vai usar na configuração de posição adBreak(). É importante observar que as funções beforeAd e afterAd só serão chamadas se um anúncio adequado for encontrado.

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. Fazer uma chamada para adBreak() em um anúncio premiado

Adicione código para um anúncio premiado ser mostrado quando o jogo terminar, mas o usuário quiser reviver a pontuação atual em vez de começar de novo. Faça uma chamada para adBreak() dentro da função lose(), verificando se um anúncio premiado está disponível. Se for, mostre ao usuário uma solicitação perguntando se ele quer a recompensa (ou seja, o retorno à vida, neste caso) e, quando ele concordar em assistir ao anúncio, chame o showAdFn() correspondente. É possível configurar o que fazer se o usuário assistir ou pular os anúncios premiados usando os callbacks adViewed e adDismissed.

Um novo adBreak() precisa ser chamado para cada oportunidade de mostrar um anúncio premiado. Isso garante que o anúncio seja atualizado se o anterior tiver expirado ou não estiver disponível.

showAdFn() precisa ser chamado como parte de uma ação direta do usuário para assistir um anúncio. Caso contrário, o anúncio pode não ser exibido.

Crie funções para serem chamadas antes e depois do intervalo do anúncio, que você vai usar na configuração de posição adBreak(). É importante observar que as funções beforeReward, adViewed, adDismissed, beforeAd e afterAd só serão chamadas se um anúncio adequado for encontrado.

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

Agora, adicione o botão "Continuar" ao seu arquivo 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>
[...]

O app de cara ou coroa agora está criando posições de anúncio para veiculação.

Seu app pode ter outros lugares adequados para anúncios além do final do jogo. Chamar adBreak() nesses lugares deve ser semelhante a este exemplo.

Desativar os testes para apps de produção

Antes de lançar o app, é importante remover ou comentar a linha data-adbreak-test="on" em index.html, porque esse código ativa as configurações de teste em produção.