L'API Ad Placement est conçue pour aider les développeurs AdSense et AdMob à utiliser des annonces interstitielles et avec récompense dans des jeux HTML5 sur le Web ou dans des applications. Cet exemple montre comment intégrer l'API Ad Placement dans un jeu et l'utiliser pour placer une annonce interstitielle.
Prérequis
Avant de commencer, vous aurez besoin des éléments suivants :
- Créez deux fichiers vides dans le même répertoire :
- index.html
- game.js
- Installez Python en local ou utilisez un serveur Web pour tester votre implémentation.
Exemple de code d'application
Les éditeurs AdMob peuvent télécharger un exemple de code d'application pour mieux comprendre comment l'API peut être intégrée à un jeu d'application.
Télécharger l'exemple de code de l'application
1. Démarrer un serveur de développement
Étant donné que l'API Ads Placement charge les dépendances via le même protocole que la page sur laquelle elle est chargée, vous devez utiliser un serveur Web pour tester votre application. Vous pouvez utiliser le serveur intégré de Python pour créer un environnement de développement local.
Ouvrez le terminal.
Accédez au répertoire contenant votre fichier index.html, puis exécutez la commande suivante :
python -m http.server 8000
Dans un navigateur Web, accédez à
localhost:8000
.
Vous pouvez également utiliser tout autre serveur Web, tel que le serveur HTTP Apache.
2. Créer un jeu HTML5
Modifiez index.html
pour créer un élément de canevas HTML5 et un bouton pour déclencher le jeu. Ajoutez ensuite le tag de script nécessaire pour charger le fichier 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>
Modifiez game.js pour jouer à un jeu de pile ou face lorsque l'utilisateur clique sur le bouton "Play" (Jouer).
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();
Une fois cette étape terminée, lorsque vous ouvrirez index.html
dans votre navigateur (via votre serveur de développement), vous devriez pouvoir voir le canevas du jeu et le bouton "Jouer".
Si vous cliquez sur "Jouer", le jeu de pile ou face devrait démarrer.
3. Importer l'API Ad Placement
Ensuite, ajoutez l'API Ad Placement à votre jeu en insérant un tag de script dans index.html
, avant le tag pour game.js
.
La balise de script peut accepter un certain nombre de paramètres. Nous utiliserons les paramètres suivants pour spécifier le code de propriété AdSense et activer le mode test :
data-ad-client=<AdSense property code>
Code de propriété AdSense. Cette autorisation est toujours requise, même pour les jeux qui s'exécutent dans des applications.data-adbreak-test="on"
Active le mode test. Supprimez-le pour les jeux une fois qu'ils sont proposés aux joueurs.
Configurer le code AdSense et activer le mode test
La fonctionnalité de l'API Ad Placement est incluse dans le code AdSense. Pour l'activer, vous devez d'abord ajouter le code AdSense et inclure un petit extrait de script qui initialise ses deux fonctions clés : adBreak()
et 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>
Intégrer votre jeu (facultatif)
Si vous souhaitez intégrer un jeu dans d'autres pages à l'intérieur d'un iFrame et que la balise adsbygoogle
se trouve dans la page HTML du jeu, veillez à ajouter allow='autoplay'
à l'élément iFrame. Il s'agit d'une bonne pratique, qui est nécessaire pour que certaines annonces soient éligibles à votre jeu.
<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>
Compatibilité avec les applications mobiles
Un jeu H5 peut s'exécuter dans un navigateur Web standard, dans un WebView
ou dans un onglet personnalisé Chrome au sein d'une application. L'API Ad Placement peut détecter l'environnement dans lequel votre jeu s'exécute et diriger les demandes d'annonces de manière appropriée. Si votre jeu s'exécute dans un navigateur Web standard, les demandes d'annonces sont traitées comme des demandes AdSense normales. Si l'API Ad Placement détecte un environnement intégré à une application, elle communique avec le SDK Google Mobile Ads, s'il est présent, pour demander et afficher des annonces AdMob.
Cette fonctionnalité est disponible dans les applications Android associées au SDK Google Mobile Ads. Pour l'activer, vous devez enregistrer le WebView
qui affichera votre jeu avec le SDK Google Mobile Ads, puis configurer les blocs d'annonces AdMob et les transmettre en tant que paramètres supplémentaires à la balise AdSense. Lorsque votre jeu est exécuté dans une application appropriée, l'API Ad Placement utilise ces blocs d'annonces pour diffuser des annonces.
Pour activer la compatibilité avec les appareils mobiles, vous devez spécifier les paramètres de balise supplémentaires suivants :
data-admob-interstitial-slot=<AdMob slot ID>
ID de bloc d'annonces interstitielles AdMob que vous avez configuré précédemment.data-admob-rewarded-slot=<AdMob slot ID>
ID de bloc d'annonces avec récompense AdMob.
Votre code de propriété AdSense doit toujours être transmis avec le paramètre data-ad-client
. De plus, au moins l'un des paramètres data-admob-interstitial-slot
ou data-admob-rewarded-slot
doit être spécifié. Les deux paramètres doivent être spécifiés si votre jeu utilise les deux formats.
Vous pouvez également spécifier le paramètre de tag data-admob-ads-only=on
pour indiquer que votre jeu ne doit diffuser que des annonces AdMob et ne pas revenir à AdSense dans les cas où le jeu est joué dans un environnement qui ne prend pas en charge les demandes AdMob (par exemple, les environnements non applicatifs ou les applications sans le SDK Google Mobile Ads configuré).
Important : Lorsque vous concevez votre jeu pour qu'il soit intégré dans une application et que vous êtes le propriétaire de celle-ci ou que vous concluez un accord de partage des revenus avec le propriétaire de l'application, s'appuyer sur la compatibilité d'AdMob est la seule façon de procéder pour obtenir d'excellentes performances tout en respectant les règles applicables.
Commencez par enregistrer l'WebView
qui affichera votre jeu avec le SDK Google Mobile Ads :
MainActivity.java (application)
Les paramètres par défaut de WebView
ne sont pas optimisés pour les annonces. Utilisez les API WebSettings
pour configurer votre WebView
pour :
- JavaScript
- Accès au stockage local
Lecture automatique des vidéos
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)
}
}
Ensuite, transmettez les blocs d'annonces AdMob (un pour les annonces interstitielles et un pour les annonces avec récompense) comme suit :
index.html (application)
[...]
<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. Appeler adConfig()
L'appel adConfig()
communique la configuration actuelle du jeu à l'API Ad Placement. L'API peut ensuite utiliser ces informations pour filtrer les types d'annonces qu'elle demande afin qu'elles soient adaptées au jeu (par exemple, les annonces vidéo qui nécessitent du son, si le son est activé).
Un appel doit être effectué à adConfig()
chaque fois que cette configuration change, par exemple lorsqu'un utilisateur coupe ou réactive le son du jeu. Appelez adConfig()
dans le constructeur du jeu, puis ajoutez un bouton pour couper et réactiver le son du jeu qui effectue un appel adConfig()
supplémentaire.
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();
[...]
Ajoutez maintenant le bouton de désactivation du son à votre fichier 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. Appeler adBreak()
à la fin du jeu
L'appel adBreak()
définit un emplacement publicitaire et prend l'objet appelé "placement config" qui spécifie tout ce qui est nécessaire pour afficher une annonce à ce moment-là dans votre jeu. La prise en charge de différents types d'annonces vous obligera à initialiser différents sous-ensembles de la configuration de l'emplacement.
L'appel adBreak()
définit un emplacement où une annonce peut être diffusée, ou en d'autres termes, une opportunité de diffuser une annonce. L'affichage d'une annonce dépend de plusieurs facteurs :
- Type d'emplacement d'annonce que vous avez déclaré.
- Si l'utilisateur a interagi de manière appropriée avant l'emplacement de l'annonce.
- Indique si une annonce appropriée existe pour le lecteur actuel :
- qui les concerne.
- sont cohérentes avec leurs paramètres de confidentialité et de consentement des données.
- Nombre d'annonces que l'utilisateur a vues récemment.
- Les paramètres de contrôle que vous avez configurés pour ce jeu sont les suivants :
- Indices dans le tag.
- Dans AdSense (remarque : les paramètres disponibles dans AdSense évolueront au fil du temps)
Ajoutez du code pour qu'une annonce interstitielle s'affiche lorsque le jeu redémarre : effectuez un appel à adBreak()
dans la fonction play()
, qui ne s'exécute qu'une fois le jeu terminé.
adBreak()
doit être appelé dans le cadre d'une action de l'utilisateur, comme un clic sur le bouton "Play" (Lecture). Sinon, l'API ne pourra pas demander ni afficher d'annonces.
Créez des fonctions à appeler avant et après la coupure publicitaire, que vous utiliserez ensuite dans la configuration de l'emplacement adBreak()
. Il est important de noter que les fonctions beforeAd
et afterAd
ne seront appelées que si une annonce appropriée est trouvée.
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. Appeler adBreak()
pour une annonce avec récompense
Ajoutez le code permettant d'afficher une annonce avec récompense lorsque le jeu se termine, mais que l'utilisateur souhaite relancer son score existant au lieu de recommencer à zéro. Appelez adBreak()
dans la fonction lose()
pour vérifier si une annonce avec récompense est disponible. Si c'est le cas, affichez une invite demandant à l'utilisateur s'il souhaite obtenir la récompense (c'est-à-dire la réanimation dans ce cas). S'il accepte de regarder l'annonce, appelez la méthode showAdFn()
correspondante. Vous pouvez configurer ce qu'il faut faire si l'utilisateur regarde ou ignore les annonces avec récompense à l'aide des rappels adViewed
et adDismissed
.
Une nouvelle instance adBreak()
doit être appelée chaque fois qu'une annonce avec récompense doit être affichée. Cela permet de s'assurer que l'annonce est actualisée si l'annonce précédente a expiré ou n'était pas disponible.
showAdFn()
doit être appelé dans le cadre d'une action directe de l'utilisateur pour regarder une annonce, sinon l'annonce risque de ne pas s'afficher.
Créez des fonctions à appeler avant et après la coupure publicitaire, que vous utiliserez ensuite dans la configuration de l'emplacement adBreak()
. Il est important de noter que les fonctions beforeReward
, adViewed
, adDismissed
, beforeAd
et afterAd
ne seront appelées que si une annonce appropriée est trouvée.
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();
Ajoutez maintenant le bouton "Continuer" à votre fichier 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>
[...]
L'application de pile ou face crée maintenant des emplacements publicitaires pour les annonces à diffuser.
Votre propre application peut comporter d'autres emplacements appropriés pour les annonces que la fin du jeu. L'appel de adBreak()
à ces emplacements doit être semblable à cet exemple.
Désactiver les tests pour les applications de production
Avant de déployer votre application, il est important de supprimer ou de mettre en commentaire la ligne data-adbreak-test="on"
dans index.html
, car ce code active les paramètres de test en production.