クリスマスということで、ちょっとしたネタとしてバカゲーを作りたいなぁと思い立ち、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の基礎知識をつける必要がありそうなので、まだ道のりは長そうです。 この記事では、紹介ということで、ほとんどの機能の紹介は省略しましたので、実際にゲームを作る際には、公式ドキュメントを参照することを推奨します。 そんな感じで、今回はここまで。