Newer
Older
PixelPaintWar / apps / client / src / scenes / game / entities / player / PlayerView.ts
/**
 * PlayerView
 * プレイヤーの描画責務を担うビュー
 * Pixi Spriteの生成と座標反映を行う
 */
import { Assets, Sprite, Texture } from "pixi.js";
import { config } from "@client/config";

const ENABLE_DEBUG_LOG = import.meta.env.DEV;

export class PlayerView {
  public readonly displayObject: Sprite;

  constructor(imageFileName: string, isLocal: boolean) {
    const { PLAYER_RADIUS_PX, PLAYER_RENDER_SCALE } = config.GAME_CONFIG;

    // 🌟 2. スプライト(画像)の生成(初期は1x1テクスチャ)
    this.displayObject = new Sprite(Texture.WHITE);

    // 🌟 3. 画像の基準点を「中心」にする(ズレ防止)
    this.displayObject.anchor.set(0.5, 0.5);

    // 🌟 4. 画像サイズを当たり判定(半径×2)に合わせる
    this.displayObject.width = PLAYER_RADIUS_PX * 2 * PLAYER_RENDER_SCALE;
    this.displayObject.height = PLAYER_RADIUS_PX * 2 * PLAYER_RENDER_SCALE;

    // ローカルプレイヤーだけ少し視認性を上げる(未使用引数対策を兼ねる)
    this.displayObject.alpha = isLocal ? 1 : 0.95;

    // 非同期で画像テクスチャを読み込んで差し替える
    void this.applyTexture(imageFileName);
  }

  /** BASE_URL対応のURLで画像を読み込み、スプライトに反映する */
  private async applyTexture(imageFileName: string): Promise<void> {
    try {
      const imageUrl = `${import.meta.env.BASE_URL}${imageFileName}`;
      const texture = await Assets.load(imageUrl);
      this.displayObject.texture = texture;

      const { PLAYER_RADIUS_PX, PLAYER_RENDER_SCALE } = config.GAME_CONFIG;

      this.displayObject.width = PLAYER_RADIUS_PX * 2 * PLAYER_RENDER_SCALE;
      this.displayObject.height = PLAYER_RADIUS_PX * 2 * PLAYER_RENDER_SCALE;

      if (ENABLE_DEBUG_LOG) {
        console.log(
          `[PlayerView] 画像を ${PLAYER_RENDER_SCALE} 倍のサイズ(${this.displayObject.width})に拡大`,
        );
      }
    } catch (error) {
      console.error(
        `[PlayerView] 画像の読み込みに失敗: ${imageFileName}`,
        error,
      );
    }
  }
  /** グリッド座標を描画座標へ反映する */
  public syncPosition(gridX: number, gridY: number): void {
    const { GRID_CELL_SIZE } = config.GAME_CONFIG;
    this.displayObject.x = gridX * GRID_CELL_SIZE;
    this.displayObject.y = gridY * GRID_CELL_SIZE;
  }

  /** 描画リソースを破棄する */
  public destroy(): void {
    this.displayObject.destroy();
  }
}