Node.js + webpack+ TypeScript 超ざっくりブラウザゲーム制作入門

ブラウザゲームを快適に作りたいよおお!!!

対象者

・大学の授業などで、なんとなくプログラムに触ったことがある人

・htmlとかjavascriptがなんとなくわかる人

・ブラウザゲーム作りたいけど、今の人はどうやって作ってるのか気になる人

最近のWeb界隈は覚えることが多すぎる!

一昔前は、ホームページ作ってゲームとか公開したい!と思ったら、まずFLASHの作り方を学べば問題ありませんでした。

が、脆弱性がとても多いことで有名だったFLASHは次第に各ブラウザから見放され、ついに使われなくなってしまいました。

今日ブラウザゲームを作ろうと思い立った時、unityを使う方が大半かと思われます。

もう一つの方法「HTML+javascript」でガリガリ作る方法を覚えるためには、たくさんの言語やフレームワーク・ライブラリを学ぶ必要が出てくるからです。

ただ、シンプルなゲームを作るならば軽量で軽いjavascript製ゲームに軍配があがります。

今回は、ブラウザゲームを快適に制作するための最短ロードマップをザックリ解説で進めていきたいと思います。

今回、ものすごくたくさんのプラットフォーム・フレームワーク・ライブラリを説明していきますが、「そういうものもあるのか」と思いつつ進めていきましょう。とりあえず使ってみて、後で興味のある所を各自勉強していってください。

他のページではありえないほどにザックリ説明でいきます。多分その方が理解しやすいと思うので!

今回は上のざっくり博士に全部ザックリと説明してもらいましょう。これを読んだあなたが「わかった気になって制作モチベーションがグーンと上がる」ことを目的にこの記事を書きました。

基本的にこの記事に書いてあることを順に進めていけば何とかなるでしょう。

わからないことがあれば、twitter @hothukurou かコメント欄に書いてください。

今回導入するおしながき

visual studio code

軽量・高性能なエディタです。
快適なのでプログラム書くならこれを入れましょう。

Node.js

便利なプラットフォームです。
元々はサーバーサイドで使用するプラットフォームでしたが、パッケージ管理があまりに便利なので、フロント開発からアプリ制作まで幅広く使われるようになりました。

typescript

jsに型を付けた言語です。(jsの代わりに使います)
型を付けることで、入力補完により爆速でコードを書けるようになります。

webpack

複数のjsファイルを一つにまとめられます。

通常、jsファイルから他のjsファイルを読み込むことはできないので、jsファイルをファイル分割する時はhtmlから複数のjsファイルをお互いの依存性を考慮した徐運版で読み込む必要があります。

webpackを使うと複数のjs一つにまとめてくれるので、jsファイルから別のjsファイルを読み込むimport 文が使えるようになります。
今回は別ファイルにモジュール化するために使います。

enchant.js

ゲーム描画ライブラリとして利用。2009年のライブラリなので、枯れている感があるのだけれど、便利なので今回もこれを使います。

もっと最新のライブラリを使いたい人は環境設定後にenchant.jspixi.jsに置き換えてみてください。)

「なんでこんなにライブラリ使うんや!それぞれどんな意味があるんだ!」と思った方が多いと思いますが、

今回は使い方だけを最初にお伝えします。

そのあとで「なんでこの環境は快適なのか」という説明を行います。実際に使ってみたらわかると思うので!

visual studio codeを導入しよう

(既にvscode導入済みの方は飛ばしてください)

プログラミングを始める前に、コードを書くためのエディタをインストールしましょう。

エディタは「プログラムを書きやすいメモ帳の超進化版」だとお考えください。visual studio codeは2015年位から流行りだしたものすごく使いやすいプログラミングエディタです。

同じMicrosoftからリリースされているvisual studioとは似てるようで別物です。

個人的にはこちらの方が軽量で拡張性も高いので、今からプログラミングを始めるならばエディタはこれ一択だと思います。

以下サイトからインストールしてください。

 

visual studio code (vscode と呼びます)

https://code.visualstudio.com/

インストール方法に躓いたら、各自検索して解決しましょう!

インストールが完了したら、vscodeを実際に開いてみましょう。

windowsなら適当なフォルダを右クリックして、「Open With Code」 を選択すると、上記のような画面が開きます。

macであれば、vscodeを開いた後、ファイルから「フォルダを開く」を選択して、プログラムが置いてあるフォルダを選択してください。

この画像には alt 属性が指定されておらず、ファイル名は image-7.png です

画面左が「フォルダ内のファイル一覧」

ファイルを選択すると右側にテキストが表示される

基本機能はこれだけなので、プログラミング以外でも、なんならメモ帳変わりでも使えるぞ

上記画面はVSCodeの拡張機能で自分好みにカスタマイズしているため、ものすごくカラフルになっています。視認性が上がるとうっかりミスが減るので、色々真似してみよう!

以下URLを参考に、自分好みにカスタマイズしてみよう!

・VSCodeのオススメ拡張機能 24 選 (とTipsをいくつか) qiita

https://qiita.com/sensuikan1973/items/74cf5383c02dbcd82234

また、設定をいじれば標準機能でコードの自動整形を行ってくれます。コードを綺麗にそろえると非常に見やすくなるので、ぜひ設定しておきましょう。

・Visual Studio Codeで保存時自動整形の設定方法

https://qiita.com/mitashun/items/e2f118a9ca7b96b97840

 

 

Node.jsを導入しよう

さて、近年のWeb制作ではNode.jsというプラットフォームを利用することが一般的になってきました。

https://nodejs.org/ja/

Node.jsの詳しい説明を見たい方は、公式ページを見るか、各自調べてみてください。

難しいことが書いてあるので、普通は理解できないでしょう!

ざっくり博士に説明してもらいましょう!

Node.jsは、便利な拡張機能が色々使える便利なプラットフォーム。

特にnpmという「拡張機能を簡単に追加できるシステム」がめっちゃ便利!

Node.jsは元々「サーバーサイドのプログラムをjavascriptで記述できるプラットフォーム」として開発されました。

元々サーバー構築したい人がサーバーにインストールするアプリみたいなものだったのですが、サーバーの面倒な設定を簡単に行えるnpmという機能があまりに便利なので、広く普及することになったのです。

npmとは「node package manager」の略で、これを使うと、さまざまなライブラリを簡単にインストールして、更には管理することもできるのです。

で、この便利なnpmでインストールできるアプリのうち「webpack」と「typescript」を使うことが今回の目的です。

この2つを使うことができるだけで、原始人がライターを使い始めるほどの進化を遂げることができます。

もしvisual studio codeをインストールしていない方がいましたら、インストールをお願いします。

とりあえず、進化の第一歩、node.jsをインストールしましょう。

node.js

https://nodejs.org/ja/

プロジェクトファイルをダウンロードしよう

node.jsのインストールが無事に成功したら、今回作成しましたゲームのプロジェクトファイルをお送りするので、以下のURLからgithubに飛んでください。

githubってなんだ!聞いたことあるけどわからん!」という方向けに説明すると、githubは「ネット上にデータを保管できるWebアプリ」です。

git というプログラムの履歴を管理できるソフトを使ってネット上にアップロードできます。

プログラマーの世界ではプログラムを共有するときにはgithubを使うことがナウいと言われているので今回はここに公開することにしました。

・今回使用するテンプレート

https://github.com/hothukurou/typescript_enchant_js

git 導入済みのプログラミング熟練者は適当なフォルダにcloneしてください。適当にフォークして使っていただいてもかまいません。

gitってなんやねん!」という方は下の画面を参考に、「Clone or Download」ボタンを押して「Download ZIP」というボタンが出てくるので、それを押してダウンロードしてください。

 

zipを解凍の上、フォルダ内のファイルをvscodeを用いて確認しましょう。

ここから、ブラウザゲームの環境構築を行います。

npm で簡単に環境構築

vscode を開いたら、上タブにある「ターミナル」をクリックして、新しいターミナルを開いてください。

画面下に文字を打つターミナルが現れました。

ここからは一昔前のPCのように、文字をターミナルに文字を打って作業を行います。

「プログラマーっぽいことしてる!」と胸をときめかせながら、以下の命令を打ってください。

npm install

nodeがきちんとインストールできていれば、このコマンドを打つだけで自動で環境構築に必要なパッケージのインストールが始まります。

これがnodeのが愛される点「nodeパッケージを自動でインストールしてくれる機能」です。この手軽さがnpmのメリットです。

私があらかじめ、package.jsonという設定ファイルに必要なパッケージをリスト化して記入しているので、上記の1コマンドを投げるだけで勝手にインストールをしてくれるのです。

これで今回使いたかったパッケージの「typescript」「webpack」をインストールすることができました。簡単ですね!

npmによる「外部ライブラリを自動インストール」はとても便利

外部ライブラリを勝手にインストールしてくれるから、管理するプロジェクトファイルはとても軽くなる

ところで、ターミナルにコマンド打ってPCに命令することをCUIといいます。

文字(Character)でコマンド打つUI(User Interface)ってことです。

逆に普段親しんでいる「画像(Graphical)を使ったUI」をGUIといいます。

node.jsCUIを使用した命令をいくつか使用する必要が出てきます。

慣れないうちはコマンドを覚えることに苦労すると思いますが、「コマンドを教えるだけで、だれでも同じことができる」という意思疎通の簡単さが最大の魅力なので、プログラマーの世界では非常に親しまれています。

一番わかりやすい例が上記で体験したgithubでしょう。

「今回お渡ししたプログラムをダウンロードすること」をGUI上で説明すると

「画面右に緑の「clone or download」ってボタンがあるから、これを押して、DOWNLOAD ZIPってボタン押して!」

と面倒な説明を文章に書かなければいけません。しかもこの文章を書くために、githubのページを何度もにらめっこしなければいけないという煩雑さがあります。

しかし、これをCUIで説明すると

git clone https://github.com/hothukurou/typescript_enchant_js.git

とこのコマンドを送信するだけ同じ動作を説明できるようになります。

文章でやりとりするならこっちの方が正確かつ楽に説明ができます。

・・・という理由がいまだにCUIが使われる主な理由です。

今回をきっかけに、CUIによる操作に慣れてみるとよいと思います。

typescriptを使ってみる

ここからは、typescriptの使い方を説明します。

typescript は「javascriptに型を追加して使いやすくなった独自言語」です。

typescriptの文法で書いたコードをjavascriptのコードにトランスパイルして使用します。

(C言語を習ったことがある方であれば、コンパイラによってマシン語にコンパイルするようなイメージです。コンパイルは機械語に変換することを指すのですが、javascriptは機械語ではないので、翻訳(トランス)という意味でトランスパイルと呼ぶそうです)

実際に動作させるときにはjavascriptとして使用するので、いままでjavascriptを使用してWebアプリを作成していた方も簡単に置き換えることができます。

今回、typescriptディレクトリ内にtypescriptで作成したファイル(〇〇.ts)があります。これを常時監視して、自動でトランスパイルしてみましょう。

(以下、typescripttsjavascriptjsを表記します。)

具体的には以下のコマンドをターミナルに記入してください。

# typescript を javascriptにトランスパイルする(常時監視)
npm run tsc

npm run 〇〇と打つと、私の方であらかじめ予約しておいたコマンドが実行されます。今回npm run tscと打つとtypescriptのトランスパイルコマンドである「tsc -w」というコマンドが実行され、これはtypescriptのトランスパイルを常時実行し続けるというコマンドです。

typescriptフォルダ内に大量のjsファイルとjs.mapファイルが生成されていれば成功です。

jsファイルはtsファイルをトランスパイルした結果生成されたファイルです。

js.mapファイルはtsファイルとjsファイルをマッピングしているファイルです。これがあるとエラー時のコード誤りをtsファイルを元に教えてくれます。

tsc ウォッチを使用すると、プログラム内にあるtsconfig.jsonという設定ファイルを元に監視対象のファイルの更新時に自動でコンパイルをかけてjsファイルを生成してくれます。

typescript フォルダ内に js ファイルと js.mapファイルが大量生成されたかと思います。

今回使用するような「自動で同じ動作を続けてくれる機能」をタスクランナーと呼びます。

このtsc ウォッチで起動したターミナルは消さずにそのままにしてください。

このタスクランナーが起動する限り、tsファイルを更新すると自動でjsファイルが生成され続けます。

 

このコンパイラによって生成したjsと js.mapファイルは自動生成されるファイルなので、私たちが編集することがありません。vscode上からリスト非表示にしてしまいましょう。

vscode上部タブのファイル->基本設定から以下gif動画のように操作して設定画面を開いてください。

そして、以下のコードを追加しましょう。json形式になっているので、問題が起きないようにコードを追加すればよいのですが、わからない方は2行目にこれを貼り付けてください。

    "files.exclude": {
        "**/*.js": {
            "when": "$(basename)"
        },
        "**/*.map": {
            "when": "$(basename)"
        }
    },

失敗しても、赤い波線で怒られるだけなので、それを見て適切な位置に設定してください。

成功すればtypescriptフォルダ内は〇〇.tsファイルしか見えなくなっていると思います。

さて、ここでいったんtypescript入門を行います。

難しいことは各自調べてもらえればよいのですが、ここではとりあえずザックリ覚えてほしいことが二つ。

(1)typescript では全てのオブジェクト・変数は型を持つ

型というのは「中に入っているものを定義する」という意味です。

これを定義して、「型に合わないものを代入しようとした時にエラーを示す」ことができる点がバグ発見に非常に役立つことになります。

 

どういうこっちゃ!という方のために動画を作りました。

下の図ではscoreという数字を入れる変数に誤って文字列を入れてしまった例です。typescriptが型と値を比較して、代入した値がおかしいことを突き止めます。

そして、赤線でエラーを表示してくれます。

バグ原因が秒速でわかるため、つまらないバグから卒業することができるのです!

 具体的には以下のようにコードを書いていきます。

詳しい部分は各自調べてください。

// typescript ではオブジェクト・変数

let num = 1;  // num はnumber型という型
let str = "a"; // str は string型という型
num="string"; //  number型に文字(string型)を入れてしまったのでtypescriptのコンパイラがエラーと表示する

// 以下は数値a,bを引数にとって、その和を返す関数
// 間違えて文字列を入れたときにきちんとエラーで教えてくれる
const calcNum = function(a:nmber,b:number):number{
return a+b;
}

// error!
const calcedNum=calcNum(1,"a");

// 

細かい部分は以下のページを参考にしてください。

難しい内容に見えますが、丁寧にTypeScriptの書き方やメリットについて書かれています。

・TypeScriptの型システム ~TypeScript Deep Dive 日本語版~

https://typescript-jp.gitbook.io/deep-dive/type-system

 

typescriptはバグ発見の効率化だけでなく、「入力補完を充実させる」ことにも寄与します。

これも参考例としてgif動画で説明します。

今回お渡ししたプログラムは「enchant.js」というゲーム制作ライブラリを使用しており、このライブラリは画像を表示するSpriteクラスを頻繁に使用します。

しかし、enchant.js初学者では「Spriteクラスが何を持っているのか」「このクラスのコンストラクタには何を入力すればよいのか」を覚えておらず、以下のバグを起こしがちです。

・スペルミスで呼び出す関数名/インスタンス名を間違える

・関数の引数におかしな値をいれてしまう

typescriptは型定義によって「そのクラスのメソッド、インスタンス一覧」と「メソッドがどんな引数を持つのか」を全て示してくれます。

そして、vscodeを用いれば「何を書きたいか先行して表示してくれる」入力補完機能により、スペルミスなく爆速で書きたいコードを書くことができるのです。

関数名を途中まで書けば、勝手に補完して書きたいメソッドやインスタンスを表示してくれます。もしスペルミスしても即座に赤線で指摘してくれます。

これがものすごく便利なんです。

想像してみてください。

typescriptを導入すればあなたのそばにツンデレ女教師が常時付き添ってあなたのコードを監視してくれるのです。

この女教師は型定義にはとてもうるさいので、今までjsで問題なく通っていたアヤシイコードも全部叱られます。

でも、きちんと怒られたことを受け止めて改善していけば、とてもきれいでバグのないコードを書いていくことができるのです。これがtypescriptのメリットです。

ちなみに型定義がどうしてもめんどうになった場合はany型という「型関連で一切怒らない型」を指定することも可能です。どうしてもの時は使いましょう。

さて、次はwebpackの使い方を説明します。webpackまで動作を完了すれば、いよいよこのプログラムに書かれたゲームで遊ぶことができます。

webpackの導入

tsc ウォッチしているターミナルはそのままにして、新しくターミナルを開いて、以下のコマンドをターミナルに打ってください。

npm run webpack

何かターミナルに表示されると同時に、dist フォルダが出現したと思います。

中にはmain.jsというファイルができているはずです。これが今回生成したかったjsファイルです。

webpackは、複数のjsファイルを統合して一つのjsファイルを生成することができるアプリケーションです。

これでwebpackの起動が完了しました。

これで、typescriptフォルダ内のjsファイルが全て一つに結合し、distフォルダにscript.jsというファイルが生成されました。

webpackの設定はwebpack.config.jsで設定することができます。が、見ても難しいと思うので、今回は「設定が必要な時はここを見ればいいんだな」位に覚えておいてください。

実際に動作を確認してみましょう。 プロジェクトフォルダのindex.htmlをクリックしてください。

画面に上記が表示されていれば、正常に動作しています。

 

無事に動作しましたでしょうか。動作していない場合は、dist/main.jsが存在していることをご確認ください。

おめでとうございます!これにて、環境設定が完了しました!

このhtmlファイルはdist/main.js ファイルを実行しています。

index.htmliframe内で呼んでいるgame.html内ではdist/main.jsを呼び出しています。

さて、環境構築もようやく終了したので、ここからtypescript+webpackでのプログラミング入門に入りたいと思います。

次の記事から、typescriptの具体的な使い方について説明します。

【宣伝】ブラウザゲーム作りたいけど、何からやってよいかわからない!という方へ

有償で指導承りますので、興味ある方は以下メールアドレスにご連絡ください。

何事も最初は人に教えてもらった方が理解もはかどると思いますので、もし興味がありましたらご相談ください。

tukuchauojisan@gmail.com

おまけ 今回のプログラムの解説

typescript + webpackで楽々プログラミング入門

ここからいよいよゲーム制作の本番です!

とりあえず、tscのタスクランナーが動いていること、webpackが動作していることを確認したのち、typescript/script.tsフォルダを開いてみましょう!

実はゲーム部分のコードは27~59行目ですべてです。

まずは大まかにその他のコードの解説を行います。が、これだけ見ても理解は難しいかと思いますので、ページ下にある「typescript入門」の記事を読んで知識を深めてみましょう。

1行目

/// <reference path="./enchantjs.d.ts" />

javascriptで書かれたライブラリである enchant.jsを使用するために、型を与えるコードです。

参照しているenchant.d.tsファイルを見てみましょう。

enchant.jsで使用する各関数・クラスのメンバ関数・変数一覧

が書かれています。

これを型定義ファイルと呼びます。typescriptの世界では「宣言したオブジェクトは全て何が入っているか定義しなければいけない」というルールがあります。

しかしenchant.jsjavascriptで作られたライブラリなので、型定義は自分でしなければいけません。そこで、このファイルによってenchant.jsの型を全て定義しているのです。

2~3行目

import Loader from "./loader";
import parts from "./parts";

他のtsファイルを読み込んでいます。

このimport[ファイル名]で外部で定義したクラスを簡単に読み込める機能はwebpackを導入したからこそ得られる機能です。

従来、javascriptではファイル分割はとても面倒なものでした。jsコードから他のjsファイルを呼び出すことができなかったので、呼び出し元のhtmlファイルから src=”[**.js]”と呼び出す必要があったのです。この方法は順序による依存性があり、ファイル数が増えると非常に扱いにくいものになっていました。

webpackはこの「jsファイル分割めんどくさい問題」を解決するために生み出されたパッケージです。webpackを使うことで、jsファイルを気軽にモジュール化して別ファイルに定義することができます。

これによって、「よく使うモジュールを別ファイルに記入」することが可能になり、1ファイルの行数が減ったことで、可読性が格段に上がることになったのです。

今回、使用する画像・音声ファイルのプリロードを行うLoaderクラスと、enchant.jsで制作した演出オブジェクトを生成したPartクラスの二つを外部ファイルから読み込みました。

8行目

jsファイルはページ全部のhtml読み込み完了後に実行するのが望ましいので、window.onload イベント後に処理を書いています。これはよくやる戦法ですね。

11,12行目

loader.tsで定義したLoaderクラスを用いて使用する画像と音声をプリロードしています。

17~72行目

ゲーム内の各シーンごとにローカルスコープを設定したいので、setScene関数というものを作成して、関数内で各シーンを書いています。

ローカルスコープで囲っているので、各シーン間でオブジェクト名が衝突することがないのがメリットです。

今回はsetScene(0)でゲーム本編、setScene(1)で結果画面 に移行します。

27~61行目

ぞう山君が動いているシーンsetScene(0)で描画される中身です。

ここを自由にいじってもらえれば、ぞう山君の動きを自由に変化させることができます。

52~54行目

クリックで数字が飛び出すエフェクトをpartクラスから呼び出しています。

// MEMO: 作っちゃうおじさん謹製のテキストバウンドモジュールを使用する例
const label = parts.TextBound("+1", this.x, this.y, 32, "orange", 60);
scene.addChild(label);

よく使うエフェクトを外部クラスに書いておくことで、簡単に再利用することができます。partクラスはenchant.jsの機能で生成したクラスを生成して渡してくれる機能を持っています。

こんな形で、再利用性の高いモジュールを作りためておくことで、効率的なゲーム制作が可能になります。時間があればどんどん作っていきましょう。