概要
- Phaser 3を使ってHTML5ゲームを開発するための環境構築
- Typescriptで処理を書き,Webpackでトランスパイル
- ESLint + Prettier によるコード整形の導入
各種ツールの導入
フレームワークやパッケージなど,環境構築に必要なものを導入していきます.
Node.jsの導入
Node.jsというサーバサイドのJavaScirpt実行環境をインストールします.
Node.jsのホームページからインストーラーをダウンロードするか,MacならHomebrewでもインストールできます.
brew install node
Node.jsのバージョンを簡単に管理したい方はNodebrewからインストールするのもおすすめ.(bash_profile等は適宜変えてください)
brew install nodebrew
nodebrew setup
echo "export PATH=\$HOME/.nodebrew/current/bin:\$PATH" >> ~/.bash_profile
nodebrew install-binary v14.15.3
nodebrew use v14.15.3
node -v
Node.jsのパッケージ管理ツールはnpmとyarnが主に使われてますが,ここではyarnを使います.npm派の方は適宜読み替えてください.
npm install -g yarn
yarn -v
プロジェクトの初期化
プロジェクトのルートディレクトリでプロジェクトを初期化します.
yarn init
色々聞かれますが,特に理由がなければEnterを押していれば大丈夫だと思います.初期化が終わると,ルートディレクトリにpackage.jsonが生成されます.
Phaserの導入
Phaserを導入します.PhaserはHTML5用ブラウザゲームのフレームワークです.
yarn add phaser
Typescriptの導入
TypeScriptという言語を導入します.ざっくり言うと,静的型付けのJavaScriptです.
yarn add -D typescript
TypeScriptをインストールしたら,ルートディレクトリにtsconfig.jsonというファイルを作成してください.
{
  "compilerOptions": {
    "target": "ES6",
    "module": "commonjs",
    "sourceMap": true,
    "noImplicitAny": false,
    "strict": false
  }
}
Webpackの導入
Webpackというモジュールバンドラを導入します.JavaScriptやCSS,TypeScriptなどのファイルを1つのJavaScriptファイルにまとめてくれます.
yarn add -D webpack webpack-cli@3.3.12 webpack-dev-server ts-loader expose-loader
webpack-cliのv4をインストールするとエラーが発生するので,バージョン指定をしています.
上記のインストールができたら,ルートディレクトリにwebpack.config.jsというファイルを作成してください.
// eslint-disable-next-line @typescript-eslint/no-var-requires
const path = require('path');
const pathToPhaser = path.join(__dirname, '/node_modules/phaser/');
const phaser = path.join(pathToPhaser, 'dist/phaser.js');
module.exports = {
  entry: './index.ts',
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'bundle.js',
  },
  module: {
    rules: [
      { test: /\.ts$/, loader: 'ts-loader', exclude: '/node_modules/' },
      {
        test: /phaser\.js$/,
        loader: 'expose-loader',
        options: {
          exposes: { globalName: 'Phaser', override: true },
        },
      },
    ],
  },
  devServer: {
    contentBase: path.resolve(__dirname, './'),
    publicPath: '/dist/',
    host: '127.0.0.1',
    port: 8080,
    open: true,
  },
  resolve: {
    extensions: ['.ts', '.js'],
    alias: {
      phaser: phaser,
    },
  },
};
ESLintとPrettierの導入
ESLintとPrettierを導入します.どちらもコード整形してくれるツールで,ESLintは構文チェックとコード整形を,PrettierはESLintで整形できないコードを整形してくれます.
yarn add -D prettier 
yarn add -D eslint eslint-config-prettier eslint-plugin-prettier
yarn add -D @typescript-eslint/eslint-plugin @typescript-eslint/parser 
ESLintをインストールしたら.eslintrc.jsonを,Prettierをインストールしたら.prettierrcをルートディレクトリに作成してください.
{
  "parser": "@typescript-eslint/parser",
  "parserOptions": {
    "project": "./tsconfig.json"
  },
  "plugins": ["@typescript-eslint", "prettier"],
  "extends": [
    "plugin:@typescript-eslint/recommended",
    "prettier/@typescript-eslint",
    "plugin:prettier/recommended"
  ],
  "env": {
    "browser": true,
    "node": true,
    "es6": true
  },
  "rules": {
    "prettier/prettier": "error",
    "no-return-assign": ["off"]
  }
}
{
 "trailingComma": "all",
 "tabWidth": 2,
 "semi": true,
 "singleQuote": true
}
上記2つのファイルはコード整形のルールなので,コードが書きやすいように適宜ルールを書き換えてください.
動作確認
Phaser 3のチュートリアルを使って動作確認します.
今回は,チュートリアルのPart2 - Loading Assetsまで(公式HPで配布されているチュートリアルのサンプルコードのpart3.htmlまで)の内容を動作させてみます.
公式HPにあるチュートリアルのPart1 - IntroductionのRequirementsの節にあるサンプルコードのzipファイルをダウンロードしてください.
ダウンロードしたらzipファイルを解凍し,中にあるassetsディレクトリを,プロジェクトのルートディレクトリの下に置いてください.また,ルートディレクトリにscenesディレクトリを作成しておいてください.
HTMLの用意
プロジェクトのルートディレクトリに,index.htmlを作成してください.
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <title>TutorialMaking your first Phaser 3 Game - Part 1</title>
    <style type="text/css">
      body {
        margin: 0;
      }
    </style>
    <script src="dist/bundle.js" ></script>
  </head>
  <body>
    <div id="game"></div>
  </body>
</html>
中身はサンプルコードのhtmlファイルとほほ同じです.ただし,scriptタグのsrcはdist/bundle.jsに指定しています.
エントリーポイントの用意
Phaserではゲームの1画面を1つのSceneというオブジェクトで管理しています.なので,先程作成したscenesディレクトリにScene毎のTypeScriptファイルを置き,Webpackのエントリーポイントであるindex.tsファイルでSceneを読み込んであげます.
ルートディレクトリにindex.tsを作成してください.
import 'phaser';
import Main from './scenes/main';
const config: Phaser.Types.Core.GameConfig = {
  width: 800,
  height: 600,
  type: Phaser.AUTO,
  parent: 'game',
  scale: {
    mode: Phaser.Scale.FIT,
    autoCenter: Phaser.Scale.CENTER_BOTH,
    parent: 'game',
  },
  scene: Main,
};
export class Game extends Phaser.Game {
  constructor(config: Phaser.Types.Core.GameConfig) {
    super(config);
  }
}
window.addEventListener('load', () => {
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
  const game = new Game(config);
});
index.tsでPhaserを読み込み,GameConfigオブジェクトを作成して,Gameインスタンスを作成します.使うSceneをConfigで宣言することで,実際に読み込んで描画することができます.
Sceneの用意
今回は,画面は1つしかないので,Sceneは1つになります.
scenesディレクトリにmain.tsを作成し,描画するオブジェクトや処理を書いていきます.
export default class Main extends Phaser.Scene {
  constructor() {
    super({
      key: 'Main',
      physics: {
        arcade: {
          gravity: { y: 300 },
          debug: false,
        },
      },
    });
  }
  preload(): void {
    this.load.image('sky', 'assets/sky.png');
    this.load.image('ground', 'assets/platform.png');
    this.load.image('star', 'assets/star.png');
    this.load.image('bomb', 'assets/bomb.png');
    this.load.spritesheet('dude', 'assets/dude.png', {
      frameWidth: 32,
      frameHeight: 48
    });
  }
  create(): void {
    this.add.image(400, 300, 'sky');
  }
  update(): void {
  }
}
サーバの起動
以下のコマンドで開発用サーバを起動し,表示されたURLへ飛ぶと動作しているかと思います(デフォルトのURLは http://127.0.0.1:8080/ になっているかと思います).
npx webpack-dev-server
チュートリアルのpart2までなので,空の背景を読み込んで描画させているだけですが,とりあえず動作はしているのではないでしょうか.
最後に
1画面1ファイルだと,ちょっとゲームの規模が大きくなると1ファイルのステップ数がスゴイことになりそうなので,部品毎に分けるなど,うまいことスクリプトを細分化して綺麗な設計になるように考えたい