クリスマスということで、ちょっとしたネタとしてバカゲーを作りたいなぁと思い立ち、JavaScriptでゲームを作ることにしました。 当初、JavaScriptの標準ライブラリとjQueryだけを使って、DOM操作で作ろうとしたのですが、早々に折れました。 JavaScriptでゲームを作るのに便利なライブラリはないかと探していたら、enchant.jsに出会いました。 結構簡単にゲームが作れたので、備忘録も兼ねて、ブログの記事にしようと思います。
公式ページからダウンロードする方法と、GitHubからリポジトリをcloneし、ソースコードからビルドする方法があります。 自分はソースコードからビルドしたので、そちらの方法を書いていきます。 なお、以降はnodeとnpmは導入済みであることを前提とします。
まずは、gitコマンドでenchant.jsのリポジトリをローカルにcloneし、移動します。
$ git clone https://github.com/wise9/enchant.js.git
$ cd enchant.js
ソースコードからビルドするためには、gruntとcoffee-scriptがインストールされている必要があります。 以下のコマンドを実行すると、それぞれインストールされていなければグローバルインストールを実行します。
$ which grunt > /dev/null 2>&1 || npm install grunt-cli -g
$ which coffee > /dev/null 2>&1 || npm install coffee-script -g
gruntとcoffee-scriptをインストールしたら、npm installを実行します。
$ npm install
これでビルドに必要なツールのインストールが終わったので、ビルドをします。 以下のコマンドを実行し、cloneしたローカルリポジトリ内にenchant.min.jsというファイルが生成されていれば成功です。
$ grunt concat
$ grunt uglify
必須ではありませんが、ビルドしたenchant.min.jsを親ディレクトリからも参照できるように、ハードリンクを作成します。
$ ln enchant.min.js ../
公式のチュートリアル(日本語)が存在するので、そちらを参考にしてください...というのもアレなので、大雑把なチュートリアルを書こうと思います。以降の説明では、JavaScriptについて、基礎的な知識はある程度あることを前提に話を進めます。
まず、enchant.jsを利用するにあたってのテンプレートのようなものを以下に記します。
enchant();
window.onload = function() {
// 第1引数: 画面幅(px), 第2引数: 画面高さ(px)
var game = new Game(200, 200);
game.onload = function() {
/*
* ここにゲームの処理を記述
*/
}
game.start();
}
enchant()を実行することで、enchant.jsの機能が利用できるようになります。 おまじないだと思っておけば良いと思います。 (おまじないとかで説明を片付けてしまうの、あまり好きじゃないんですけどね...) enchant()を実行したら、documentの読み込みが終わった際の処理を記述します。 中心となるGameオブジェクトの初期化などは、window.onloadが参照する関数に記述します。 game.start()を実行することで、ゲームが開始します。 game.onloadには、gameオブジェクトが読み込まれた際の処理を記述します。
ゲームのシーンを表すオブジェクトとして、Sceneオブジェクトが用意されています。 画像やテキストなどのゲームのオブジェクトは基本的にSceneオブジェクトに配置します。 Sceneオブジェクトを生成しただけでは、ゲーム画面に反映されません。 ゲーム画面に反映させるためには、GameオブジェクトのpushScene()メソッドを利用します。 上で挙げたテンプレートに、Sceneオブジェクトを追加したコードを以下に示します。
enchant();
window.onload = function() {
// 第1引数: 画面幅(px), 第2引数: 画面高さ(px)
var game = new Game(200, 200);
game.onload = function() {
var scene = new Scene();
/*
* ここにゲームの処理を記述
*/
// Sceneオブジェクトを追加
game.pushScene(scene);
}
game.start();
}
ゲームのシーンを追加したので、その上にテキストや画像などを追加していきます。 テキストを追加するにはLabelオブジェクトを、画像を追加するはSpriteオブジェクトを利用します。 テキストのフォントのスタイルを変更するには、生成したLabelオブジェクトのfontプロパティを変更します。 fontプロパティには、CSSのfontプロパティと同様の設定が可能です。 テキストの文字色を変更するには、colorプロパティを設定します。 こちらもCSSで文字色を設定するときと同じように指定します。 テキストの文字列を変更するには、textプロパティを変更します。
画像を追加するには、imageプロパティを設定します。 設定値は、Gameオブジェクトのassetsプロパティを指定します。 また、画像を設定するためには、Gameオブジェクトのpreload()メソッドを利用して、画像の事前読み込みをしておく必要があります。
画像やテキストの配置場所を設定するためには、moveTo()メソッドを利用するか、xプロパティやyプロパティを設定します。 moveTo()メソッドの第1引数にはx座標、第2引数にはy座標を指定します。 LabelオブジェクトやSpriteオブジェクトは、生成するだけでは画面に反映されません。 SceneオブジェクトのaddChild()メソッドを利用することで、画面に反映させることができます。 上で示したテンプレートの例を使って、コード例を以下に示します。
enchant();
window.onload = function() {
// 第1引数: 画面幅(px), 第2引数: 画面高さ(px)
var game = new Game(200, 200);
game.onload = function() {
var scene = new Scene();
// 第1引数: 設定するテキスト
var label = new Label("Hello, World");
// フォントの設定
label.font = "bold 24pt monospace";
label.color = "#ff0000";
// 位置の設定
label.x = 10;
label.y = 10;
// 第1引数: 画像幅(px), 第2引数: 画像高さ(px)
var img = new Sprite(100, 100);
// 画像の設定
img.image = game.assets["image.png"];
// 位置の設定
img.moveTo(50, 80);
// LabelオブジェクトをSceneオブジェクトに追加
scene.addChild(label);
// SpriteオブジェクトをSceneオブジェクトに追加
scene.addChild(img);
// Sceneオブジェクトを追加
game.pushScene(scene);
}
// 素材の事前読み込み
game.preload("image.png");
game.start();
}
ゲームでは、プレイヤーからの入力などを受け付ける必要があります。 イベントを扱えば、画像がクリックされたり、キーボードが押下された際の処理を記述できます。 イベントハンドラを追加するには、addEventListener()メソッドを利用します。 引数はJavaScriptの標準ライブラリと同様に利用できます。 イベントの種類の一部を以下に列挙します。
enchant.Event.ENTER_FRAME: フレーム開始時に発生するイベントenchant.Event.UP_BUTTON_DOWN: 上ボタンが押された際に発生するイベントenchant.Event.UP_BUTTON_UP: 上ボタンが離された際に発生するイベントenchant.Event.DOWN_BUTTON_DOWN: 下ボタンが押された際に発生するイベントenchant.Event.DOWN_BUTTON_UP: 下ボタンが離された際に発生するイベントenchant.Event.LEFT_BUTTON_DOWN: 左ボタンが押された際に発生するイベントenchant.Event.LEFT_BUTTON_UP: 左ボタンが離された際に発生するイベントenchant.Event.RIGHT_BUTTON_DOWN: 右ボタンが押された際に発生するイベントenchant.Event.RIGHT_BUTTON_UP: 右ボタンが離された際に発生するイベントenchant.Event.TOUCH_START: タッチの開始時に発生するイベントenchant.Event.TOUCH_MOVE: タッチの移動時に発生するイベントenchant.Event.TOUCH_END: タッチの終了時に発生するイベント
他にも扱えるイベントはありますが、ここでは割愛します。 詳細は公式ドキュメントのAPIリファレンスを確認してください。
以下にイベントを使ったコード例を示します。 以下のコードは、左キーまたは右キーが押された際に画像を移動させるコード例です。
enchant();
window.onload = function() {
// 第1引数: 画面幅(px), 第2引数: 画面高さ(px)
var game = new Game(200, 200);
game.onload = function() {
var scene = new Scene();
// 第1引数: 設定するテキスト
var label = new Label("Hello, World");
// フォントの設定
label.font = "bold 24pt monospace";
label.color = "#ff0000";
// 位置の設定
label.x = 10;
label.y = 10;
// 第1引数: 画像幅(px), 第2引数: 画像高さ(px)
var img = new Sprite(100, 100);
// 画像の設定
img.image = game.assets["image.png"];
// 位置の設定
img.moveTo(50, 80);
// 左キーが押された際の処理
scene.addEventListener(enchant.Event.LEFT_BUTTON_DOWN, function() {
// 画像を5px左に移動
img.x -= 5;
// 画像が左端に到達した際の処理
if(img.x < 0) {
img.x = 0;
}
});
// 右キーが押された際の処理
scene.addEventListener(enchant.Event.RIGHT_BUTTON_DOWN, function() {
// 画像を5px右に移動
img.x += 5;
// 画像が右端に到達した際の処理
if(img.x > game.width - img.width) {
// game.width: ゲームの画面幅, img.width: 画像幅
img.x = game.width - img.width;
}
});
// LabelオブジェクトをSceneオブジェクトに追加
scene.addChild(label);
// SpriteオブジェクトをSceneオブジェクトに追加
scene.addChild(img);
// Sceneオブジェクトを追加
game.pushScene(scene);
}
// 素材の事前読み込み
game.preload("image.png");
game.start();
}
enchant.jsを使って、実際に簡単なゲームを作ってみました。 クリスマスに合わせて、ちょっとしたバカゲーを作りました。 こちらからアクセスできます。 (操作にキーボードが必要です) あ、くだらないとかの苦情は受け付けないので、予めご承知ください(笑)
enchant.jsを使えば、簡単なゲームであれば、割と楽に作成できそうだとわかったので、Electronと組み合わせて、作成したゲームをネイティブアプリケーションにも移植してみたいと考えていますが、 まずはElectronの基礎知識をつける必要がありそうなので、まだ道のりは長そうです。 この記事では、紹介ということで、ほとんどの機能の紹介は省略しましたので、実際にゲームを作る際には、公式ドキュメントを参照することを推奨します。 そんな感じで、今回はここまで。