시작하기

광고 게재위치 API는 전면 광고의 사전 캐싱과 로드를 지원합니다. 개발자는 API를 사용하여 게임 또는 기타 상호작용 미디어에서 잠재적인 광고 시점이나 순간을 알릴 수 있지만 광고 게재 시점 및 게재할 광고에 대한 정확한 결정은 Google에 위임됩니다.

광고 게재위치 API는 웹, 슈퍼앱 내 또는 기타 상호작용 미디어의 HTML5 게임에서 전면 광고를 사용하는 애드센스 개발자를 지원하도록 설계되었습니다. 이 가이드에서는 광고 게재위치 API를 간단한 게임에 통합하는 방법을 설명합니다.

기본 요건

시작하기 전에 다음 사항이 필요합니다.

  • 다음 빈 파일 만들기:
    • index.html
    • game.js
  • 컴퓨터에 설치된 Python 또는 테스트에 사용할 웹 서버

1. 개발 서버 시작하기

광고 게재위치 API는 로드되는 페이지와 동일한 프로토콜을 통해 종속 항목을 로드하므로 웹 서버를 사용하여 앱을 테스트해야 합니다. 로컬 개발 서버를 시작하는 가장 간단한 방법은 Python의 내장 서버를 사용하는 것입니다.

  1. index.html 파일이 있는 디렉터리에서 명령줄을 사용하여 다음을 실행합니다.
    python -m http.server 8000
  2. 웹브라우저에서 http://localhost:8000/으로 이동합니다

Apache HTTP 서버와 같은 기타 웹 서버도 사용할 수 있습니다.

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>

'재생' 버튼을 클릭하여 동전 던지기 게임을 즐길 수 있도록 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를 클릭하면 동전 던지기 게임이 시작됩니다.

3. 광고 게재위치 API 가져오기

다음으로, game.js의 태그 앞 index.html에 스크립트 태그를 삽입하여 게임에 광고 게재위치 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() 호출은 게임의 현재 구성을 광고 게재위치 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() 호출은 광고를 표시할 수 있는 위치, 즉 광고를 표시할 기회를 정의합니다. 광고가 실제로 표시되는지 여부는 다음과 같은 여러 요인에 따라 결정됩니다.

  • 선언한 광고 게재위치의 유형
  • 광고 게재위치 이전에 적절한 사용자 상호작용이 발생했는지 여부
  • 현재 플레이어에게 적합한 광고가 있는지 여부. 예를 들어
    • 플레이어와 관련이 있는 광고
    • 플레이어의 데이터 공개 및 동의 설정과 일치하는 광고
  • 사용자가 최근에 본 광고의 개수
  • 다음 형태 중 하나로 게임에 대해 구성한 컨트롤 설정
    • 태그 내 힌트
    • 애드센스 내(참고: 애드센스에서 사용할 수 있는 컨트롤은 시간이 지남에 따라 변경됨)

이 가이드에서는 게임이 다시 시작될 때 전면 광고가 표시되도록 코드를 추가합니다. play() 함수 내에서 게임을 1회 완전히 플레이한 후에만 발생할 adBreak()를 호출합니다. adBreak()는 '재생' 버튼 클릭과 같은 사용자 작업의 일부로 호출되어야 합니다. 그렇지 않으면 API에서 광고를 요청하고 표시할 수 없습니다. 또한 광고 시점 전후에 호출할 함수를 만들어 adBreak() 게재위치 구성에서 사용합니다. beforeBreakafterBreak 함수는 적합한 광고가 있는 경우에만 호출된다는 점을 잊지 마세요.

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.html에서 data-adbreak-test="on" 줄을 삭제해야 합니다.