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.
Abra o terminal.
Acesse o diretório que contém o arquivo index.html e execute:
python -m http.server 8000
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.