node.jsでTypeScript+Phaserなブラウザゲーム開発環境を作る

JavaScript

こんにちは、ECF Tech
ブログ担当 Michiharu.Tです。

てんこもりなタイトルのとおり、JavaScriptベースのゲームフレームワーク「Phaser」を使ったゲーム開発環境の構築までをまとめてみました。

今回はTypeScript環境で開発したいということもあり、node.jsでの環境構築となりました。私自身もNodeの学習しながらということで、なるべく初学者向けに基本的な用語を解説しながら、細かくお伝えできればと思っています。

対象読者

  • HTML,JavaScriptなどのWeb基礎知識のある方
  • node.jsについては初心者でもOK

今回用いた技術要素について

Phaser

JavaScriptをベースにしたゲーム開発用のフレームワークです。Phaser自体の基本的な使い方については、下の記事で紹介させて頂いています。よろしければご参考ください。

JavaScriptゲームライブラリPhaserを使ってみた。
こんにちは ECF Techブログ 担当 Michiharu.Tです。 ブラウザで遊べるゲーム開発を志し、いいライブラリないかなと思って探していたところ、Phaserという2Dゲームライブラリがなかなか素晴らしかったので、簡単なハンズオン形...

TypeScript

JavaScriptの拡張プログラミング言語です。JavaScriptに厳密な型定義を持ち込むことで、大規模な開発にも対応できるように設計されています。こちらにつきましても、基本的な内容を過去の記事でご紹介しております。よろしければご参考ください。

TypeScriptの超基本ポイントをまとめてみました!
こんにちは、ECF Techブログ 担当 Michiharu.Tです。 今回は個人的にTypeScriptを学ぶ需要があったこともあり、TypeScriptの超基本ポイントをまとめてみることにしました。 対象読者 プログラミングの基本的な...

node.js

JavaScriptでサーバーサイドのアプリケーションを構築できる実行環境です。

Node.jsの基本

Node.jsのインストールは下記のサイトから行うことができます。本記事ではインストール済みを前提に進めさせていただきます。

Node.js — Run JavaScript Everywhere
Node.js® is a JavaScript runtime built on Chrome's V8 JavaScript engine.

下記にnode.jsの基本を少しだけまとめておきます。不要な方は飛ばして、次の開発環境の構築からご覧ください。

モジュール

Node.jsでは、アプリ開発環境を構築するにあたってモジュールと呼ばれるプログラム部品を使用します。Node.jsにあらかじめ用意されている便利なモジュール(コアモジュール)をはじめ、第三者により提供されているモジュールまで数多くのものが提供されています。

npm

モジュールを自身のアプリ開発環境で利用する際は、パッケージをインストールします。パッケージとはモジュールを利用しやすいようにまとめたものです。npmは、このパッケージのインストールを簡単に行うことができるコマンドベースのツールです。

開発環境の構築

本記事はこちらのphaser3-typescriptというgithubサンプルをベースに説明をしています。

初期設定

では、Windows10環境で作成した手順です。まずは適当なフォルダを作成し、該当フォルダへ移動します。

C:\Users\Any>mkdir phasergame

C:\Users\Any>cd phasergame

次にnodeの開発環境として初期化するため、npm initコマンドを実行します。

C:\Users\Any\phasergame>npm init -y
Wrote to C:\Users\Any\phasergame\package.json:

{
  "name": "phasergame",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC"
}

npm initコマンドの目的はpackage.jsonという設定ファイルを生成することです。そのまま実行すると、各項目を1つ1つ聞いてくるので、それを省略し全部デフォルトで生成する場合は-yオプションをつけます。

パッケージのインストール

必要なパッケージをインストールしていきます。

Phaserのインストール

まずはPhaserです。パッケージが用意されていますので、次のコマンドで実行します。

npm install phaser --save

npm install パッケージ名で、パッケージのローカルインストールを行ないます。ローカルインストールは、このアプリケーション内だけで利用可能なインストール方法です。

--savepackage.jsonファイルに依存関係を書き出すオプションです。

TypeScriptのインストール

次はTypeScriptのインストールです。

npm install typescript --save-dev

--save-devオプションもpackage.jsonファイルに依存関係を書き出すオプションですが、こちらは開発時の依存関係として書き出しが行われます。

webpackのインストール

webpackとは

webpackは簡単にいうと、ファイルをひとまとめにしてくれる(バンドルという)ツールです。開発する上で作成される沢山のJavaScriptファイルなどを1つのファイルに変換したりすることができます。

Phaser+TypeScriptでオブジェクト指向的にゲーム開発を行なうと、多くのJavaScriptファイルが作成されます。これらの依存関係を解消し、1つのファイルにまとめてくれます。

webpackのインストール

ではインストールです。

npm install webpack webpack-cli --save-dev

webpackwebpack-cliという2つのパッケージをインストールしています。webpack-cliはwebpackの操作に便利なコマンドラインツールです。

ts-loaderのインストール

webpackがTypeScriptのファイルをバンドルする際に使うパッケージです。

npm install ts-loader --save-dev

expose-loaderのインストール

こちらもwebpackがバンドル時に使うパッケージです。モジュールをグローバル領域に展開するために使います。

npm install expose-loader --save-dev

webpack-dev-serverのインストール

webpackソリューションの1つとして提供されている簡易Webサーバです。

npm install webpack-dev-server --save-dev

長くなりましたが、これで一通りのインストール作業が完了しました。

ディレクトリ構成

プロジェクトフォルダ配下は次のようにします。index.html game.ts title-scene.ts webpack.config.js tsconfig.jsonを新規に追加しています。

C:\Users\Any\phasergame
│-index.html
│-package-lock.json
│-package.json
│-webpack.config.js
│-tsconfig.json
└─src
    │-game.ts
    └─scenes
       └─title-scene.ts

まずはゲームの根幹となるTypeScript(.ts)ファイルからです。

game.ts

//必要なimport
import "phaser";
import { BootScene } from "./scenes/boot-scene";

//ゲームの基本設定
const config: Phaser.Types.Core.GameConfig = {
    title: "botMonster",    //タイトル
    version: "0.0.1",       //バージョン
    width: 640,             //画面幅
    height: 480,            //画面高さ
    parent:"game",          //DOM上の親
    type: Phaser.AUTO,      //canvasかwebGLかを自動選択
    scene: [BootScene]      //利用するSceneクラス
};

//ゲームメインのクラス
export class Game extends Phaser.Game{
    constructor(config: Phaser.Types.Core.GameConfig) {
        super(config);
    }
}

//windowイベントで、ロードされたらゲーム開始
window.addEventListener("load", () => {
    var game = new Game(config);
});

今回はPhaserの利用方法がメインの話題ではないので、ソースに簡易的にコメントを割り振っています。ゲームのスタート地点となるクラスです。

title-scene.ts

タイトル画面のクラスです。Phaserでは、Sceneクラスの継承クラスは画面クラスとなります。タイトル画面、ゲーム画面などはこのSceneの継承クラス単位になります。

export class TitleScene extends Phaser.Scene {
    constructor() {
        //識別ID設定のみ
        super({
            key: "TitleScene"
        });
    }

    //本来はこのメソッドで、画像ファイルなどのロード
    preload(): void {
        //今回はコンソール表示だけ
        console.log("Hello Phaser");
    }
}

webpack.config.js

こちらは、webpackがバンドルの際に用いる設定ファイルです。設定項目はコメントで概要を示しています。

//パス名の生成
var path = require("path");
var pathToPhaser = path.join(__dirname, "/node_modules/phaser/");
var phaser = path.join(pathToPhaser, "dist/phaser.js");

//webpackの出力設定
module.exports = {
    //実行開始地点となるファイル
    entry: './src/game.ts',
    //出力先
    output: {
        //カレントパス/dist
        path: path.resolve(__dirname, "dist"),
        //出力ファイル名
    filename: "bundle.js"
    },
    //依存関係解決の対象とするモジュール
  module: {
        rules: [
            //*.ts なファイルはts-loaderに処理を依頼。但し/node_modules/内は除く
            { test: /\.ts$/, loader: "ts-loader", exclude: "/node_modules/" },
            //phaser.jsなファイルはexposer-loaderに処理を依頼。phaserをグローバルオブジェクトとして出力
      {
        test: /phaser\.js$/,
        loader: "expose-loader",
        options: {
          exposes:['phaser']
        }
      }
    ]
    },
    //webpack-dev-serverの起動設定
  devServer: {
    contentBase: path.resolve(__dirname, "./"),
    publicPath: "/dist/",
    host: "127.0.0.1",
    port: 9000,
    open: true
  },
  resolve: {
    extensions: [".ts", ".js"],
    alias: {
      phaser: phaser
    }
  }
};

tsconfig.jsonの追加

TypeScriptのコンパイル設定ファイルです。とりあえずこのとおり作成します。

{
  "compilerOptions": {
    "target": "ES6",
    "module": "commonjs",
    "sourceMap": true,
    "noImplicitAny": false,
    "strict": false
  }
}
  • target:対象のECMAScriptバージョン
  • module:生成するモジュールコードを指定
  • sourceMap:ソースマップを作成するかどうか
  • noImplicitAny:any型をエラーとして扱うかどうか
  • strict:厳密な型チェックをするかどうか

package.jsonの修正

scriptsプロパティを変更します。scriptプロパティは独自コマンドを記述できる部分です。npm run コマンド名のような形で実行できます。scriptsプロパティは次のようになります。

"scripts": {
  "dev": "webpack --mode development && webpack-dev-server --mode development"
},

npm run devで実行すると、webpackによるバンドル作業が開始され、その後Webサーバが起動します。

修正後の全文を掲示します。

{
  "name": "phasergame",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "dev": "webpack --mode development && webpack-dev-server --mode development"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "phaser": "^3.24.1"
  },
  "devDependencies": {
    "expose-loader": "^1.0.0",
    "ts-loader": "^8.0.1",
    "typescript": "^3.9.6",
    "webpack": "^4.43.0",
    "webpack-cli": "^3.3.12",
    "webpack-dev-server": "^3.11.0"
  }
}

index.html

最後にHTMLファイルです。バンドルされたjsファイル(./dist/bundle.js)をロードします。

<!doctype html>
<html>
  <head>
    <meta charset="UTF-8" />
    <title>HelloPhaser</title>
    <script src="dist/bundle.js"></script>
  </head>
  <body>
    <div class="container">
      <h1>phaser3-typescript</h1>
      <div id="game"></div>
    </div>
  </body>
</html>

ビルドと実行

これで準備が完了しました。次のコマンドを実行してみましょう。

npm run dev

ブラウザが起動し、次のような画面が出れば成功です。

ブラウザの開発ツールなどでコンソールログを見ると、Hello Phaserが表示されていることがわかります。

おわりに

本日は以上となります。最後までご覧くださりありがとうございます。Phaser + TypeScriptは、個人的にはブラウザゲーム制作には最強の組み合わせかなと思っています。最近は構築の環境も整いやすくなり、開発を色々と楽しめるようになってきました。もし興味ありましたら、ぜひチャレンジしてみてください。


合同会社イー・シー・エフでは、子ども向けプログラミングなどの教育講座を実施しています。プログラミング教室の案内や教育教材の情報、また関連するご相談・問い合わせにつきましては下記よりご確認ください。

ECFエデュケーション
タイトルとURLをコピーしました