へっぽこ社会人4年生がプログラミングを頑張る

へっぽこ社会人4年目がプログラミング系統を中心に書きたいことをつらつらと書きます

enchant.jsを使ってバカゲーを作ってみた

クリスマスということで、ちょっとしたネタとしてバカゲーを作りたいなぁと思い立ち、JavaScriptでゲームを作ることにしました。 当初、JavaScriptの標準ライブラリとjQueryだけを使って、DOM操作で作ろうとしたのですが、早々に折れました。 JavaScriptでゲームを作るのに便利なライブラリはないかと探していたら、enchant.jsに出会いました。 結構簡単にゲームが作れたので、備忘録も兼ねて、ブログの記事にしようと思います。

導入方法

公式ページからダウンロードする方法と、GitHubからリポジトリcloneし、ソースコードからビルドする方法があります。 自分はソースコードからビルドしたので、そちらの方法を書いていきます。 なお、以降はnodenpmは導入済みであることを前提とします。

まずは、gitコマンドでenchant.jsのリポジトリをローカルにcloneし、移動します。

$ git clone https://github.com/wise9/enchant.js.git
$ cd enchant.js

ソースコードからビルドするためには、gruntcoffee-scriptがインストールされている必要があります。 以下のコマンドを実行すると、それぞれインストールされていなければグローバルインストールを実行します。

$ which grunt > /dev/null 2>&1 || npm install grunt-cli -g
$ which coffee > /dev/null 2>&1 || npm install coffee-script -g

gruntcoffee-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プロパティには、CSSfontプロパティと同様の設定が可能です。 テキストの文字色を変更するには、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の基礎知識をつける必要がありそうなので、まだ道のりは長そうです。 この記事では、紹介ということで、ほとんどの機能の紹介は省略しましたので、実際にゲームを作る際には、公式ドキュメントを参照することを推奨します。 そんな感じで、今回はここまで。

参考文献