본문 바로가기
프로그래밍/Game Dev

[Phaser] UI Text, Camera, Switching Scene

by YuminK 2023. 10. 3.

UI Text

장면에서 text를 추가한다.

scrollFactor를 1로 주면 카메라의 좌표에 영향을 받게 된다. (World 상에 출력하고 싶다면 1)

  createTextInfo() {
    this.posText = this.add
      .text(8, 8, "", {
        font: "16px",
        fill: "#000000",
      })
      .setScrollFactor(0)
      .setDepth(100);
  }

 

플레이어의 x, y 좌표와 fps 정보를 출력한다.

  updateTextInfo() {
    this.posText.setText(
      `x: ${Math.round(this.player.x)}\ny: ${Math.round(
        this.player.y
      )}\nfps: ${Math.round(this.game.loop.actualFps)}`
    );
  }

 

Camera

카메라와 world의 bounds(이동 가능 크기)를 지정하고 player를 따라가도록 처리한다.

플레이어가 중간에 있도록 하고, 충분한 영역이 나오지 않으면 offset 비율을 무시한다. 

    // add main camera to player
    this.cameras.main.setBounds(0, 0, this.mapWidth, this.mapHeight);
    this.matter.world.setBounds(0, 0, this.mapWidth, this.mapHeight);
    this.cameras.main.startFollow(this.player);

 

Switching Scene

Phaser.Scene을 상속받는 Scene을 만들고 config 쪽에 추가를 해준다.

이후에 포탈 오브젝트를 Scene에 하나 만들고 플레이어와 충돌시 Scene을 변경해버린다. (matter 플러그인 사용중)

 

GameScene.js (BaseScene)

  createPortal(portalData) {
    // {portalName: "", destScene: "", x, y, width, height, data(json) }
    const { portalName, destScene, x, y, width, height } = portalData;
    const data = portalData.data || {};

    let portal = this.matter.add.rectangle(x, y, width, height);
    portal.onCollideCallback = (pair) => {
      if (pair.bodyA.label === "playerSensor") {
        this.scene.start(destScene, data);
      }
    };

    this.matter.add.gameObject(portal, {
      isStatic: true,
      label: portalName,
    });
  }

 

포탈 생성 예시( MainScene.js )

   super.createPortal({
      portalName: "portal1",
      destScene: "HouseScene",
      x: 398,
      y: 185,
      width: 32,
      height: 32,
      data: { spawnPosX: 225, spawnPosY: 970 },
    });

 

참고로 플레이어의 생성자에는 다음 코드가 있다. (PlayerSensor가 충돌체로 들어가 있다)

    const { Body, Bodies } = Phaser.Physics.Matter.Matter;
    var playerCollider = Bodies.circle(this.x, this.y, 12, {
      isSenor: false,
      label: "playerCollider",
    });
    var playerSensor = Bodies.circle(this.x, this.y, 12, {
      isSensor: true,
      label: "playerSensor",
      onCollideCallback: (pair) => {},
    });

    const compoundBody = Body.create({
      parts: [playerCollider, playerSensor],
      frictionAir: 0.35,
    });

    this.setExistingBody(compoundBody);
    this.setFixedRotation();

 

Scene을 변경하는 처리에 대한 부연 설명하자면, 필요한 데이터를 모두 로드하는 것이다.

 

공통 이미지 로드
플레이어 로드
맵 생성
포탈 위치 추가
공통 UI 처리
글로벌 변수 처리
플레이어 업데이트 처리
UI 업데이트 처리

 

같은 모든 로직을 Scene에서 처리하도록 하면 된다. BaseScene을 상속받아서 처리하면 중복 코드를 없앨 수 있다.

참고로 Scene을 교체했을 때 기존 Scene은 update되지 않는다. 

 

scene.start에 넘겨준 데이터는 Scene의 init함수에서 오버라이딩하여 사용한다. 

  init(data) {
    this.spawnPosX = data.spawnPosX || 400;
    this.spawnPosY = data.spawnPosY || 300;
  }

 

Scene 장면 전환 처리 영상

 

참고 자료

BaseScene과 그 외 Scene에 대한 컨셉을 이해하기에 좋다

https://github.com/mwilber/the-legend-of-zeta/blob/master/src/GameScene.js#L104

'프로그래밍 > Game Dev' 카테고리의 다른 글

[Phaser] 미니맵  (2) 2023.10.04
[Phaser] Toast 메시지  (0) 2023.10.04
[Phaser] Pixel bleeding 이슈  (0) 2023.10.02
[Phaser] Animation, TileMap  (0) 2023.09.28
[Node.js] 간단한 멀티 슈팅게임 소스 분석  (0) 2023.09.26

댓글