Chapter 02(基本編)

PhaserJS入門
最初のゲーム(基本編) 🎮

1匹のモグラを使ったシンプルなモグラたたきゲームを作成します

📚 この章で学ぶこと(基本編)

基本的なPhaserJS概念

  • • 変数の使い方
  • • 画像の読み込みと表示
  • • クリックイベントの処理
  • • タイマーの基本的な使い方

作成するゲーム

  • • 1つの穴から1匹のモグラが出現
  • • クリックでモグラを倒す
  • • シンプルで理解しやすい構造
  • • プログラミングの基礎を学習

プログラミング基礎概念

  • • 複合オブジェクト(座標、設定値)
  • • 型安全なコードの書き方

実践的なスキル

  • • nullチェックによるエラー防止
  • • 適切な変数の命名と管理
  • • TypeScriptの型システム活用
  • • 安全で読みやすいコード作成

✨ 初心者におすすめ

この基本編では1匹のモグラだけを扱い、配列などの複雑な概念は使いません。 プログラミング基礎を踏まえて実践的なコード作成を行い、 プログラミングが初めての方でも安心して次のステップに進める土台を築きます。

📚 前提知識の確認

このチュートリアルでは、以下の基礎概念を使用します。まだ学習していない場合は、先に該当チャプターを確認することをお勧めします。

Step 1: ゲーム用画像の準備

まず、ゲームで使用する画像ファイルを準備します。src/assetsフォルダに以下の画像を配置してください。

🖼️ 必要な画像ファイル:

  • hole.png - モグラの穴(64x64px推奨)
  • mole.png - 通常のモグラ(64x64px推奨)
  • mole_hit.png - やられたモグラ(64x64px推奨)

💡 画像について:

画像は自分で用意するか、フリー素材サイトからダウンロードしてください。 シンプルな図形でも構いません。重要なのはPhaserJSの使い方を学ぶことです!

Step 2: メインシーンファイルの作成

src/scenesフォルダにGameScene.tsを作成します。

// src/scenes/GameScene.ts
import * as Phaser from 'phaser';

export class GameScene extends Phaser.Scene {
    // モグラの穴の位置(画面の中央)
    private holeX: number = 400;
    private holeY: number = 300;
    
    // ゲームで使用するオブジェクトを格納する変数
    private hole: Phaser.GameObjects.Image | null = null;
    private mole: Phaser.GameObjects.Image | null = null;
    
    // モグラの状態を管理する変数
    private moleVisible: boolean = false;
    
    // タイマー関連の変数(deltaTime使用)
    private moleTimer: number = 0; // モグラ表示時間のカウンタ
    private spawnTimer: number = 0; // モグラ出現間隔のカウンタ
    private moleShowDuration: number = 3000; // モグラ表示時間(ミリ秒)
    private moleSpawnInterval: number = 2000; // モグラ出現間隔(ミリ秒)
    private hitShowDuration: number = 500; // やられ状態表示時間(ミリ秒)
    private moleHit: boolean = false; // モグラがやられた状態かどうか

    constructor() {
        super({ key: 'GameScene' });
    }

    // ゲーム開始前にアセットを読み込む
    preload(): void {
        // 画像ファイルを読み込み
        this.load.image('hole', 'assets/hole.png');
        this.load.image('mole', 'assets/mole.png');
        this.load.image('mole_hit', 'assets/mole_hit.png');
    }

    // シーンが開始されたときに実行
    create(): void {
        // 背景色を設定
        this.cameras.main.setBackgroundColor('#4ade80');

        // 穴を画面に配置
        this.hole = this.add.image(this.holeX, this.holeY, 'hole');
    }

    // フレーム毎に実行される処理
    update(time: number, delta: number): void {
        // モグラが表示されていない場合の出現タイマー
        if (!this.moleVisible) {
            this.spawnTimer += delta;
            if (this.spawnTimer >= this.moleSpawnInterval) {
                this.showMole();
                this.spawnTimer = 0;
            }
        } else {
            // モグラが表示されている場合の非表示タイマー
            this.moleTimer += delta;
            const duration = this.moleHit ? this.hitShowDuration : this.moleShowDuration;
            
            if (this.moleTimer >= duration) {
                this.hideMole();
                this.moleTimer = 0;
            }
        }
    }
}

🔍 重要な変数とその役割:

holeX, holeY: number
• モグラの穴の表示位置を指定
hole, mole: Phaser.GameObjects.Image | null
• 画面に表示される画像オブジェクト(nullチェックが重要)
moleVisible: boolean
• モグラの表示状態を管理

💡 基礎的な変数の概念やnullの詳細は 変数とは何かnullの概念 をご覧ください

� 前提知識へのリンク

このコードで使用している概念の詳細は基礎チャプターで学習できます。

� 詳しいデータ型の解説は Chapter 01b: データ型について をご覧ください

💡 デルタタイムベースのタイマーシステム

今回のゲームでは、デルタタイムを使用してタイマーを管理します。これにより、フレームレートに関係なく一定の時間で動作するゲームを作成できます。

従来の方法 vs デルタタイム

  • 従来: this.time.delayedCall() - コールバック関数での時間管理
  • デルタタイム: update()メソッドで毎フレーム時間を累積して管理
  • メリット: より細かい制御が可能で、パフォーマンスが向上

デルタタイムの仕組み

update(time, delta)メソッドのdeltaパラメータには、 前回のフレームからの経過時間(ミリ秒)が渡されます。これを累積することで正確な時間管理ができます。

Step 3: モグラ表示機能の実装

GameScene.tsに以下のメソッドを追加します。

// GameScene.tsのcreate()メソッドの後に追加

// モグラを表示する
private showMole(): void {
    // すでにモグラが表示されている場合は何もしない
    if (this.moleVisible) {
        return;
    }

    // モグラを作成して画面に表示
    this.mole = this.add.image(this.holeX, this.holeY, 'mole');
    
    // モグラをクリック可能にする
    this.mole.setInteractive();
    
    // クリックされたときの処理を設定
    this.mole.on('pointerdown', () => {
        this.hitMole();
    });

    // モグラが表示されている状態にする
    this.moleVisible = true;
    this.moleHit = false;
    this.moleTimer = 0; // タイマーをリセット
}

// モグラがクリックされたときの処理
private hitMole(): void {
    // モグラが表示されていない場合は何もしない
    if (!this.moleVisible || !this.mole) {
        return;
    }

    // 画像をやられた状態に変更
    this.mole.setTexture('mole_hit');
    
    // クリックを無効にする
    this.mole.disableInteractive();
    
    // やられた状態にしてタイマーをリセット
    this.moleHit = true;
    this.moleTimer = 0;
}

// モグラを隠す
private hideMole(): void {
    // モグラが存在する場合は削除
    if (this.mole) {
        this.mole.destroy();
        this.mole = null;
    }
    
    // モグラが隠れている状態にする
    this.moleVisible = false;
    this.moleHit = false;
}

🎯 変数の活用ポイント:

moleVisible変数の活用
• モグラが表示中かどうかを判断
• 二重表示や不正なクリックを防ぐ
if (this.moleVisible)で状態をチェック
mole変数の値の変化
• 最初:null(何もない)
• 表示時:Image オブジェクト(画像)
• 削除後:null(リセット)
holeX, holeY変数の活用
• モグラの表示位置を決定
• 一箇所で変更すれば全体に反映
this.add.image(this.holeX, this.holeY, 'mole')

🔄 変数の値が変わる流れ:

1. 初期状態: moleVisible = false, mole = null
2. モグラ表示: moleVisible = true, mole = 画像オブジェクト
3. クリック時: mole.setTexture('mole_hit') で画像変更
4. 削除時: moleVisible = false, mole = null にリセット

Step 4: ゲーム設定ファイルの更新

src/main.tsを以下のように更新します。

// src/main.ts
import './style.css';
import * as Phaser from 'phaser';
import { GameScene } from './scenes/GameScene';

// ゲーム設定用の変数
const gameWidth: number = 800;
const gameHeight: number = 600;
const backgroundColor: string = '#4ade80';

// ゲーム設定
const config: Phaser.Types.Core.GameConfig = {
    type: Phaser.AUTO,
    width: gameWidth,
    height: gameHeight,
    parent: 'app',
    backgroundColor: backgroundColor,
    scene: [GameScene]
};

// ゲームを開始
new Phaser.Game(config);

⚙️ 設定用変数の活用:

gameWidth, gameHeight: number
• ゲーム画面のサイズを記憶
• 変数に入れることで後から変更しやすい
• 他の場所でも同じ値を使える
backgroundColor: string
• 背景色を文字列で保存
• カラーコード(#4ade80)を使用
• 一箇所変更すれば全体の色が変わる
config: GameConfig
• ゲーム全体の設定をまとめて管理
• 複数の設定値を1つのオブジェクトにまとめる
• PhaserJSに渡すための設定集

Step 5: ゲームの実行

すべてのコードを保存したら、ターミナルで開発サーバーを起動します。

npm run dev

🎮 ゲームの動作確認:

  • ブラウザでゲームが表示される
  • 緑色の背景に1つの穴が配置される
  • 2秒ごとにモグラが1匹出現
  • モグラをクリックするとやられた画像に変わる
  • 3秒経つか、クリックされると自動で消える

🐛 うまく動かない場合:

ブラウザのデベロッパーツール(F12)でエラーメッセージを確認してください。 よくある問題は画像ファイルのパスが間違っていることです。

⚡ 変数を使った簡単な改良例

変数の値を変更するだけで、ゲームの動作を簡単にカスタマイズできます。

// GameScene.tsで変数の値を変更してみよう
export class GameScene extends Phaser.Scene {
    // モグラの出現位置を変更
    private holeX: number = 200; // 左に移動
    private holeY: number = 150; // 上に移動
    
    // タイミングを調整する変数(デルタタイム使用)
    private moleTimer: number = 0; // モグラ表示タイマー
    private spawnTimer: number = 0; // モグラ出現タイマー
    private moleShowDuration: number = 2500; // 2.5秒で自動で隠す
    private moleSpawnInterval: number = 1500; // 1.5秒ごとに出現
    private hitShowDuration: number = 800; // 0.8秒でやられ画像を表示
    private moleHit: boolean = false; // やられ状態フラグ

    create(): void {
        this.cameras.main.setBackgroundColor('#4ade80');
        this.hole = this.add.image(this.holeX, this.holeY, 'hole');
    }

    // デルタタイムを使った時間管理
    update(time: number, delta: number): void {
        if (!this.moleVisible) {
            // モグラが隠れている時:出現タイマーを進める
            this.spawnTimer += delta;
            if (this.spawnTimer >= this.moleSpawnInterval) {
                this.showMole();
                this.spawnTimer = 0;
            }
        } else {
            // モグラが表示中:表示時間タイマーを進める
            this.moleTimer += delta;
            const duration = this.moleHit ? this.hitShowDuration : this.moleShowDuration;
            if (this.moleTimer >= duration) {
                this.hideMole();
                this.moleTimer = 0;
            }
        }
    }

    private showMole(): void {
        if (this.moleVisible) return;
        
        this.mole = this.add.image(this.holeX, this.holeY, 'mole');
        this.mole.setInteractive();
        this.mole.on('pointerdown', () => this.hitMole());
        this.moleVisible = true;
        this.moleHit = false;
        this.moleTimer = 0; // タイマーリセット
    }

    private hitMole(): void {
    private hitMole(): void {
        if (!this.moleVisible || !this.mole || this.moleHit) return;
        
        this.mole.setTexture('mole_hit');
        this.mole.disableInteractive();
        this.moleHit = true;
        this.moleTimer = 0; // やられ状態タイマーリセット
    }

    private hideMole(): void {
        if (this.mole) {
            this.mole.destroy();
            this.mole = null;
        }
        this.moleVisible = false;
        this.moleHit = false;
            
  • holeX, holeY - モグラの出現位置を変更
  • moleSpawnInterval - モグラの出現間隔を変更(早くしたり遅くしたり)
  • moleShowDuration - モグラが自動で消えるまでの時間
  • hitShowDuration - やられた画像の表示時間
strong>spawnDelay - モグラの出現間隔を変更(早くしたり遅くしたり)
  • hideDelay - モグラが自動で消えるまでの時間
  • hitDelay - やられた画像の表示時間
  • 🎉 お疲れ様でした!

    この基本編では、変数の基本的な概念とPhaserJSの基礎を学習しました。 1匹のモグラを使ったシンプルなゲームを通じて、プログラミングの基本を身につけることができたはずです。

    今回学んだ基本概念:

    • 変数の基本(const、let、型の概念)
    • PhaserJSのシーンライフサイクル(preload、create)
    • 画像の読み込みと表示
    • クリックイベントの処理
    • タイマーを使った時間制御

    📈 次のステップ:

    基本編をマスターしたら、発展編に挑戦しましょう! 配列を使った複数のモグラ管理や、より高度なプログラミング手法を学習できます。

    🎯 次のステップ

    基本的なゲームの作成ができるようになったら、次の章に進みましょう: