0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Vite + TypeScriptでドンジャラ風ゲームを作ってGitHub Pagesで公開する(BGM付き)

0
Posted at

はじめに

title.png

これは何?

Vite + TypeScript で、ドンジャラ風(同じ絵柄を3枚集める“トリプル”を3セット作ったら勝ち)のブラウザゲームを作りました。
UIは「夜桜」テーマで、BGM(MP3)の再生/ミュート切替も付けています。

この記事では ゲーム実装の要点GitHub Pagesでの公開でハマりやすい点(Viteのbase) を中心にまとめます。

ざっくり機能

  • 人間 vs CPU
  • 牌の山からツモって捨てる
  • 上がり条件: 「トリプル×3(合計9枚)」を満たしたら勝ち
  • BGM: 開始ボタン押下で再生(自動再生制限を回避) + ON/OFF
  • GitHub Actionsでビルドして GitHub Pages へデプロイ
    start.png

ディレクトリ構成(重要なところだけ)

.
├─ index.html
├─ public/
│  └─ audio/
│     └─ bgm.mp3
├─ src/
│  ├─ game.ts        # 進行(start / draw / discard / CPUターン)
│  ├─ player.ts      # 手牌管理 + 上がり判定
│  ├─ ui.ts          # DOM描画 + BGM制御
│  └─ ...
├─ vite.config.ts    # base調整(Pages向け)
└─ .github/workflows/deploy-pages.yml

ゲームロジックの要点

1) 「状態」を中心にしてUIは描画するだけにする

GameGameState を持ち、状態が変わるたびにUIへ通知します。
UIはその状態を見てDOMを再描画するだけにすると、ロジックが読みやすくなります。

2) ゲーム開始〜ツモまでの流れ(最小)

開始時に牌を作ってシャッフルし、9枚ずつ配って、プレイヤーがツモからスタートします。

// src/game.ts(抜粋)
start(): void {
  const { player, cpu } = this.state;

  player.reset();
  cpu.reset();

  const deck = shuffleTiles(createAllTiles());
  for (let i = 0; i < 9; i++) {
    player.addToHand(deck.pop()!);
    cpu.addToHand(deck.pop()!);
  }

  this.updateState({
    phase: 'playerTurn',
    deck,
    discardPile: [],
    winner: null,
    message: ''
  });

  this.drawTile(player);
}

3) 上がり判定は「10枚になったら1枚抜いて9枚で成立するか」を全探索する

ドンジャラ系は「捨て牌の選択」があるので、手元に10枚になる瞬間があります。
そこで 1枚ずつ抜いて9枚が“トリプル×3”になるか を見ると、実装がシンプルになります。

// src/player.ts(抜粋)
isWinning(): boolean {
  const allTiles = this.getAllTiles();

  // 10枚の場合、1枚を除いて9枚で上がれるかチェック
  if (allTiles.length === 10) {
    for (let i = 0; i < allTiles.length; i++) {
      const tilesWithoutOne = [...allTiles.slice(0, i), ...allTiles.slice(i + 1)];
      if (this.checkWinningHand(tilesWithoutOne)) {
        return true;
      }
    }
    return false;
  }

  // 9枚の場合はそのままチェック
  return this.checkWinningHand(allTiles);
}

private checkWinningHand(tiles: Tile[]): boolean {
  const counts = new Map<TileType, number>();
  for (const tile of tiles) {
    counts.set(tile.type, (counts.get(tile.type) || 0) + 1);
  }

  let tripleCount = 0;
  for (const count of counts.values()) {
    if (count % 3 !== 0) return false;
    tripleCount += count / 3;
  }
  return tripleCount === 3;
}

BGM(MP3)を入れる

1) MP3は public/ 配下に置く

Viteなら public/ 配下に置いたファイルは、そのまま静的配信されます。

  • 置き場所: public/audio/bgm.mp3

2) 自動再生制限に引っかからないよう「クリック」をトリガーに play() する

ブラウザは、ユーザー操作なしの音声再生をブロックします。
そこで「始める」ボタン押下(=ユーザー操作)で再生開始します。

また GitHub Pages のサブパス配信(https://<user>.github.io/<repo>/)でも壊れないよう、import.meta.env.BASE_URL 経由で参照します。

// src/ui.ts(抜粋)
private initBgm(): void {
  const src = `${import.meta.env.BASE_URL}audio/bgm.mp3`;
  const audio = new Audio(src);
  audio.loop = true;
  audio.preload = 'auto';
  audio.volume = 0.35;
  this.bgm = audio;
}

private setupEventListeners(): void {
  this.elements.startBtn.addEventListener('click', () => {
    this.tryStartBgm(); // ユーザー操作のタイミングで再生
    this.game.start();
  });
}

private tryStartBgm(): void {
  if (!this.bgm) return;
  if (!this.bgm.paused) return;
  void this.bgm.play().catch(() => {});
}

GitHub Pages(GitHub Actions)で公開する

1) Viteの base を調整する(ここがハマりポイント)

GitHub Pages のURLが https://<user>.github.io/<repo>/ の場合、アセット参照パスがズレて白画面になりがちです。
手軽な対策は、base: './' にして相対パスで出力することです。

// vite.config.ts
export default defineConfig({
  base: './',
  build: { outDir: 'dist' }
})

2) Actionsでビルド→Pagesへデプロイする

dist/ を artifact としてアップロードして、actions/deploy-pages でデプロイします。

# .github/workflows/deploy-pages.yml(抜粋)
permissions:
  contents: read
  pages: write
  id-token: write

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 20
          cache: npm
      - run: npm ci
      - run: npm run build
      - uses: actions/upload-pages-artifact@v3
        with:
          path: dist

  deploy:
    needs: build
    runs-on: ubuntu-latest
    steps:
      - uses: actions/deploy-pages@v4

GitHub側で Settings → Pages → Build and deployment → GitHub Actions を選ぶと動きます。

まとめ

  • 状態管理(GameState) を中心にして、UIは描画だけにすると実装が整理しやすい
  • BGMは ユーザー操作をトリガーに play()(自動再生制限対策)
  • GitHub Pagesでは Viteの base が地雷になりやすいので、base: './' がラク

次にやりたい改善案

  • SE(捨てる音/ツモ音)や音量スライダー
  • スマホでの操作性(誤タップ防止、UI最適化)
  • CPUロジック強化(期待値で捨て牌を選ぶ、役や点数の導入)

質問・フィードバック

質問や感想はコメント欄でお気軽にどうぞ。より詳しい相談は プロフィール からどうぞ。

最後まで読んでいただき、ありがとうございました。ぜひ、このゲームを遊んでみてください!

参考リンク


技術スタック: Vite, TypeScript, HTML/CSS, GitHub Actions, GitHub Pages

0
0
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?