むりこのーと

創作活動の記録や、日々思ったことをゆるく書いています。

【Phaser入門】見下ろし2Dレトロアクションゲームを作るPart3 キャラ表示編

どうも。

前回はPhaserでシーンの作り方について解説しました。まだ見ていない方はこちらもご覧ください。

www.murinote.com

今回はPhaserでキャラクターなどを配置し、動かす方法を説明していきます!

今回の記事は以下の内容になっています。

では早速見ていきましょう!

1. ゲームシーンの作成

前回はゲームを起動したらタイトルシーンが始まるところまでを実装しました。ただこれだとタイトルを表示しただけなので当然ゲームをするも何もありません。

そこでタイトル画面の次に表示される、いわゆるゲームシーンを作成し、タイトルシーンから遷移するように設定していきます。

ゲームシーンの定義

前回と同じように、まずはゲームシーンのソースコードを作りましょう。名前はGameSceneとしておきましょう。

タイトルシーンの場合は画面の中央に文字列を表示するだけでしたが、一旦ゲームシーンでもまずは文字列表示されるように実装してみましょう。ガワだけ作っておくというのもゲーム開発においては重要な工程になります。

/* GameScene.js */
export class GameScene extends Phaser.Scene {
    constructor() {
        super('GameScene');
    }

    init() {
        // Initialize scene
    }

    preload() {
        // Load assets
    }

    create() {
        this.cameras.main.setBackgroundColor("#404040");
        this.textTitle = this.add.text(
            this.scale.width / 2,
            this.scale.height / 2,
            "This is GameScene !",
            {
                fontFamily: "Arial Brack",
                fontSize: 42,
                color: "#ffffff",
                stroke: "#000000",
                strokeThickness: 8,
            }
        );
        this.textTitle.setOrigin(0.5, 0.5);
    }
}

シーンの遷移

次はこのゲームシーンを実際に動かしてみましょう。

まずはこのゲームシーンを使用できるようにするため、タイトルシーンの時と同じようにmain.jsに記載しておきましょう。

// ここでゲームに必要なシーンをインポートする
import { Start } from './scenes/Start.js';
import { TitleScene } from './scenes/TitleScene.js';
// 追加
import { GameScene } from './scenes/GameScene.js';

const config = {
    type: Phaser.AUTO,
    title: 'Overlord Rising',
    description: '',
    parent: 'game-container',
    width: 1280,
    height: 720,
    backgroundColor: '#000000',
    pixelArt: false,
    // ここで使用するシーンを並べる。一番初めに定義したものが最初に起動される
    scene: [
        TitleScene,
        // 追加
        GameScene,
        Start,
    ],
    scale: {
        mode: Phaser.Scale.FIT,
        autoCenter: Phaser.Scale.CENTER_BOTH
    },
}

new Phaser.Game(config);

次に、タイトルシーンからこのシーンに遷移するための設定をします。タイトルシーンのテキストをクリックしたらゲームシーンに遷移するようにしてみましょう。

    create() {
        // 背景色を灰色にセット
        this.cameras.main.setBackgroundColor("#808080");
        // タイトルの文字列を画面中央に表示
        this.textTitle = this.add.text(
            this.scale.width / 2,
            this.scale.height / 2,
            "Game Start",
            {
                fontFamily: "Arial Brack",
                fontSize: 42,
                color: "#ffffff",
                stroke: "#000000",
                strokeThickness: 8,
            }
        );
        // 指定した座標を、その要素のどの部分を起点にするか決める。
        // 左上を起点にするなら(0, 0)、中央なら(0.5, 0.5)、右下なら(1, 1)
        this.textTitle.setOrigin(0.5, 0.5);
        // クリックを有効にする
        this.textTitle.setInteractive();
        // クリック時の処理を定義
        this.textTitle.on('pointerdown', () => {
            // シーンを遷移
            this.scene.start('GameScene');
        });
    }

setInteractive()で、そのオブジェクトはマウスのクリックに対して反応することが可能になります。そしてon('pointerdown', () => {})で実際にクリックがされたときの挙動を定義し、最後にthis.scene.start()を行うことで、任意のシーンに遷移することができます。

これでシーン遷移の設定ができました。では実際に動かしてみましょう。

2. キャラの表示

ゲームシーンで文字列を表示することができました。ただ、これではとてもとてもゲームとは言えません。そこでこんなものを用意しました。

スライムが左右上下に動くアニメーション用のスプライトシート(複数の画像を一つにまとめたものを一般的にこう呼びます)sです。サイズは32ピクセル×24ピクセルで、これが4×2で並んでいます。これを実際に表示してみましょう。

キャラを表示する

まずはこれをダウンロードし、適当な名前でいいですがとりあえずslimes.pngという名前でassetsフォルダに配置してください。

それではゲームシーンのpreload()にて読み込んでみましょう。

    preload() {
        // スプライトシートを読み込み、「slime」という名前で登録しておく
        this.load.spritesheet(
            "slime",
            "assets/slimes.png",
            {
                frameWidth: 32,
                frameHeight: 24,
            }
        );
    }

load.spritesheet()でスプライトシートをゲームに読み込みます。各引数では、読み込んだスプライトシートの名前、実際のスプライトシートのパス、プロパティを指定します。

このコードのframeWidthframeHeightでは、それぞれフレームあたりの幅と高さを指定しています。今回は幅と高さが32pxと24pxでしたのでこれを指定します。

読み込めたら実際にキャラを表示できるよう、スライムのスプライトを生成してみましょう。スプライトは、実体のある、画面上に表示されるもの(キャラやアイテムなど)と認識しておいてください。

    create() {
        this.cameras.main.setBackgroundColor("#404040");
        // テキストは邪魔なのでいったんコメントアウト
        /*
        this.textTitle = this.add.text(
            this.scale.width / 2,
            this.scale.height / 2,
            "This is GameScene !",
            {
                fontFamily: "Arial Brack",
                fontSize: 42,
                color: "#ffffff",
                stroke: "#000000",
                strokeThickness: 8,
            }
        );
        this.textTitle.setOrigin(0.5, 0.5);
        */

        // スライムのスプライトを作る
        this.slime = this.add.sprite(this.scale.width / 2, this.scale.height / 2, 'slime');
        // アニメーションを定義しておく
        // 下向き
        this.slime.anims.create({
            key: 'moveDown',
            frames: this.anims.generateFrameNumbers('slime', { start: 0, end: 1 }),
            frameRate: 10,
            repeat: -1
        });
        // 右向き
        this.slime.anims.create({
            key: 'moveRight',
            frames: this.anims.generateFrameNumbers('slime', { start: 2, end: 3 }),
            frameRate: 10,
            repeat: -1
        });
        // 上向き
        this.slime.anims.create({
            key: 'moveUp',
            frames: this.anims.generateFrameNumbers('slime', { start: 4, end: 5 }),
            frameRate: 10,
            repeat: -1
        });
        // 左向き
        this.slime.anims.create({
            key: 'moveLeft',
            frames: this.anims.generateFrameNumbers('slime', { start: 6, end: 7 }),
            frameRate: 10,
            repeat: -1
        });

        // デフォルトで下向きアニメーションを再生
        this.slime.anims.play('moveDown');
    }

キャラを表示するため、以前設定した文字列の表示はコメントアウト、もしくは削除しておいてください。それでは一気に解説していきます。

まずadd.sprite()で位置とそのスプライトに使用するイメージの名前をつけてスプライトを生成します。今回は先ほど読み込んだスライムを使用します。

次にスプライトに対して、アニメーションの設定を行います。せっかく何コマも作ったのに使わないのはもったいないので。

(スプライト).anims.create()で、アニメーションに名前をつけつつアニメーションの定義をします。各引数について解説します。

keyはアニメーションの名前、framesではどのフレームを使用するか指定します(下で詳細解説します)。frameRateは1秒間に何回フレームを切り替えるか、要するにアニメーションの速度です。そしてrepeatで何回繰り返すかを指定します。-1であればループし、3を指定すれば3回再生した時点でアニメーション終了となります。

this.anims.generateFrameNumbers()では、スプライトシートの名前と、フレーム番号の指定をしてアニメーションを生成できます。

フレーム番号はどう識別するかですが、今回のスライムの場合、一番左上が1で、その右が2、3、4となり、折り返しが発生して下の列の一番左が5、その右が6、、、というように番号が振られます。よって一番右下が最後の番号になります。横書きの文章のような進み方になると言えばイメージしやすいでしょうか。

では設定が終わったので早速ゲームを起動して、ゲームシーンを見てみましょう。

スライムが小さくなってしまったのが誤算でしたが、無事ふにふにアニメーションしていることがわかります。

最後に

次回はこのスライムを実際に動かしていきます。いよいよここからゲーム感が強く出てくるようになると思います。それではお楽しみに!