enchant.jsを使った3Dブラウザゲームの制作
2016年 08月 24日

ゲーム推進プロジェクトは今年度から新設された部署で、現在は主にブラウザゲームの開発を行っています。
部署も立ち上がったばかりで、私自身もゲームプログラミング初心者のため、まだ手探り状態で毎日業務を進めています。そんな中、勉強がてらサンプルのブラウザゲームを制作しましたので、今回はそちらのご紹介やゲーム中で実際に使用したゲームエンジンの機能のご紹介をしたいと思います。
制作したゲーム
早速ですが、今回はブラウザ上で動作するパ○クマンのようなゲームを作成しました。
このゲームでは、ゲームエンジンとしてenchant.jsというJavaScript(HTML5)でゲーム開発ができるゲームフレームワークを使っています。enchant.jsはテキストエディタとウェブブラウザがあれば簡単にゲーム制作ができるので、今回のようなサンプルゲームを制作するのに向いていると思います。
ゲームエンジンには他にもUnityやCocos2d-xやUnreal Engine4など、それぞれ特色の異なるソフトウェアが数多く存在しているので興味がある人は調べてみてください。
ちなみに、ゲーム推進プロジェクトの実業務ではCocos2d-jsを採用していたりします。
また、画像を見ていただければわかるのですが、パッ○マンを普通に作成しても味気なかったので、こちらのページを参考にthree.jsを使った3D描画を組み込んでいます。
enchant.jsについて
今回のゲームでは、3D表現をthree.jsに任せており、ゲーム本体となるロジック部分はenchant.jsが担当しています。丁度、ゲーム画像左上の2Dマップが見た目上それにあたります。マップ機能
では、その2Dマップの具体的な作り方ですが、enchant.jsのマップ機能で簡単に作成することができます。マップ機能は、タイルセットとマップデータを用いることで、使うことができます。タイルセットは、一つの画像ファイル中に、実際にゲーム画面に表示するマップタイルが均一なサイズで描かれているものです。

マップデータというのは、マップ1マス毎にタイルセットの画像をどのように敷き詰めるのかを表したデータで、JavaScriptの配列として用意します。
var baseMap = [
[1, 1, 1, 1],
[1, 0, 0, 1],
[1, 0, 2, 4]
];
このマップデータを基にタイルセットのマップタイルを敷き詰めていきます。
Mapオブジェクトを作成するさいには16 x 16 pxなどサイズを指定し、それに合わせてタイルセット内のマップタイルが左上から番号付けされて、マップデータと紐付けがされます。例として以下のようなタイルセットの場合、左上の緑色の草原のマップタイルが0番、そこから右側へ順番に番号付けがされ右下の木が描かれているマップタイルが7番となります。

上記タイルセットを基にMapオブジェクトを作成した場合、以下のようなマップが作成されます。
/* マップタイル一つ当たり16 x 16 pxであるように設定 */
var map = new Map(16, 16),
baseMap = [
[1, 1, 1, 1],
[1, 0, 0, 1],
[1, 0, 2, 7]
];
map.image = game.assets['map0.png'];
map.loadData(baseMap);
scene.addChild(map);

マップの衝突判定について
これでマップを作成する方法はわかりましたが、今のままだとマップとの衝突判定がなく全てすり抜けてしまいます。ゲーム制作において、衝突判定は欠かすことができないものですが、enchant.jsのMapオブジェクトにはcollisionDataプロパティというものに障害物のマップデータ(0、1のニ値)をセットしておくと、hitTest メソッドが使え、簡単にマップとの衝突判定が可能になります。var colMap = [
[1, 1, 1, 1],
[1, 0, 0, 1],
[1, 0, 0, 0]
];
map.collisionData = colMap;
if (map.hitTest(10,10) === true) {
/* 衝突時処理 */
}
画像同士の衝突判定
衝突判定として似たような機能なのですが、画像同士の衝突判定は別のenchant.jsの機能を使わなければなりません。画像はSpriteオブジェクトを使うことでゲーム上に表示でき、intersect, within メソッドを使って衝突判定を行えます。今回のゲーム中でも、敵と衝突したかどうか判定する時や、アイテム回収時にアイテムに接触したかどうかの判定にこれらの機能を使っています。
var sprite1 = new Sprite(64, 64),
sprite2 = new Sprite(64, 64);
sprite1.image = game.assets['chara1.gif'];
sprite2.image = game.assets['chara2.gif'];
scene.addChild(sprite1);
scene.addChild(sprite2);
/* spriteの領域が衝突しているかの判定 */
if (sprite1.intersect(sprite2)) {
/* 衝突時処理 */
}
/* spriteの中心同士の距離がどれくらい近いかで判定 */
if (sprite1.within(sprite2, 40)) {
/* 衝突時処理 */
}
デモ
まだ今回制作したゲーム中で使用したenchant.jsの機能で、紹介したい機能もあるのですがページが長くなりそうなので、またの機会にしたいと思います。では、最後に作成したゲームのデモを載せておきますので良かったら遊んでみてください。
操作方法はカーソルキーの上下で前後の移動、左右で方向転換です。
https://excitejapanpub.github.io/enchantjs-pacman/
※ WebGL対応のPCブラウザでご覧ください。
実は、ゲームクリアまでちゃんと実装をしていないのでゲームとしては片手落ちなのですが、それらしいものはできているのではないでしょうか。今回enchant.jsを使うことで記述したコード量も数100行程度で済み、初心者の私でも簡単にゲーム制作ができました。
エンジニア募集
詳しくは、こちらの採用情報ページをご覧ください。