# UI 만들기

Phaser3에서 UI를 쉽게 만들고 관리하는 방법에 대해 정리하려고 한다.

# UI Scene 분리하기

UI만을 위한 Scene을 만들어서 관리하는 것이 좋다.

단순히 Scene을 하나 추가하고 scene을 launch하는 것으로 UI Scene을 분리할 수 있다.

UI만의 Scene을 갖게되면 코드를 분리할 수 있고, UI를 show, hidden처리, camera zoom에 영향을 안받게 하는 처리등 제어가 쉬워진다.

// in InGameScene create method
this.scene.launch('InGameUIScene');

# 타이머 예제

뷰포트 상단에 타이머를 표시하고, 타이머가 끝나면 callback을 호출하는 예제이다.

// InGameUIScene.ts
createTimer(min: number, callback: () => void) {
  let remainingTime = min * 60;
  const inGameScene = this.scene.get('InGameScene') as InGameScene;

  const remainingTimeText = this.add
    .text(this.cameras.main.centerX, 10, convertSecondsToMinSec(remainingTime), {
      fontSize: '20px',
      color: '#ffffff',
      stroke: '#000000',
      strokeThickness: 2,
    })
    .setOrigin(0.5, 0)
    .setScrollFactor(0);

  const timer = this.time.addEvent({
    delay: 1000,
    callback: () => {
      if (inGameScene.player.body.isDestroyed()) {
        return;
      }
      remainingTime--;
      remainingTimeText.setText(convertSecondsToMinSec(remainingTime));
      if (remainingTime < 0) {
        callback();
        remainingTimeText.destroy();
        timer.destroy();
      }
    },
    loop: true,
  });
}
// InGameScene.ts
const inGameUIScene = this.scene.get('InGameUIScene') as InGameUIScene;
inGameUIScene.createTimer(10, () => {
  // do something when timer is over
});

# DOM을 이용한 UI그리기

html의 button이나 input처럼 interaction이 필요하다면 DOM을 이용한 방법이 좋고, interaction이 필요하지 않다면 Phaser의 Graphics를 이용한 방법이 좋다.

DOM을 이용한 방법은 Phaser의 Scene에 DOM을 추가하는 방법이다.

DOM을 추가하는 방법은 다음과 같다.

this.add.dom(x, y, element);

DOM을 추가하면 Phaser의 Scene에 DOM이 추가되고, Phaser의 Scene에 추가된 DOM은 Phaser의 Scene에 추가된 Sprite처럼 Phaser의 Scene에 추가된다.

프론트 개발자라면 DOM을 이용한 방법이 더 친숙할것이다. API가 매우 유사하기 때문이다.

HTML element는 실제 html로 작성하고, phaser에서 불러오면 된다.

this.load.html('upgrade', 'phaser/upgrade.html');

new Phaser.GameObjects.DOMElement(scene, 50, 50).createFromCache('player_state');

html, body 등의 태그도 굳이 필요없다. 실제 필요한 코드조각만 추가하자.