コンテンツにスキップ

enchant.js応用編

クラスを使う

JavaScriptでは長い間,クラスを使うことができませんでした.最近になって,ようやく(ES2015から)正式にクラスもサポートされるようになりましたが,enchant.jsでは,ES2015よりも以前から,独自の実装によってクラス的な書き方を可能としていました.

ここでは,具体例によってクラス的な書き方を学びましょう.

Ballプロジェクト

オブジェクト指向プログラムの具体例として「Ballプロジェクト」を取り上げます. Ballプロジェクトは,代々引き継がれているプロジェクトです(鈴木先生 → 木村先生 → 山中). まぁ,まずは動かしてみましょう.

READMEやhtmlまで含めたプロジェクト全体のプログラムは

に置いてあります.各自,クローンして試してみてください.下記のコマンドは,コースの計算機で実行することを想定しています.ブラウザとして chromium-browser を使っていますが,自分の好きなブラウザに置き換えてください.

$ cd ~/csd
$ git clone https://gitlab.cis.iwate-u.ac.jp/yamanaka/ball.git
$ cd ball
$ chromium-browser index.html

以下のように動作します.

参考に,ものと操作の洗い出しを記載します.

参考

か弱い人間キャラ

  • (クマと出会って)消える
    • 自身のenterframeイベントリスナに「クマとの衝突判定」を入れます(スプライトのintersectwithinメソッドを使うと簡単).enterframeイベントは,毎フレーム(1秒間にgame.fpsで指定した回数)発生するので,フレーム毎に衝突判定が行われ,もしクマに衝突していたらフィールドから消すようプログラミングします
  • 時間とともに動く
    • 同じく自身のenterframeイベントリスナ内で(スプライトのmoveToメソッドを使って)「移動」させます.つまり,1秒間にgame.fpsで指定した回数だけ(少しずつ)移動が行われることになります.ついでに,スプライトのageプロパティを使って,フレームごとに画像を切り替えて(frameプロパティを更新して)アニメーションしているように見せます
  • 壁にぶつかると跳ね返る
    • 同じく自身のenterframeイベントリスナ内で「壁との衝突」(移動させたことでゲーム画面からはみ出るかどうか)を判定し,ぶつかっていればはね返らせます
  • 目覚める
    • フィールド側でマウスクリックイベントが発生したら,新たにスプライトを作り,(適切に画像等を設定して)そこにキャラを表示します

クマ

  • 生まれる
    • ゲーム開始時にスプライトを作り,(画像等を設定して)ランダムな位置に表示します
  • 時間とともに動く
    • 人間キャラと同様です.enterframeイベントリスナの内部に移動用の処理を加えます.アニメーション的要素(画像切り替え)も入れます
  • 壁にぶつかると跳ね返る
    • これも人間キャラと同様に,enterframeイベントリスナ内部に実装します
  • 衝突すると,人間キャラを消す
    • 人間キャラ側で衝突判定処理を行っていますので,クマ側ではこの実装は不要になります

背景(フィールド)及び色の切り替え

  • 行進は続く
    • フィールド(Game.rootScene)のenterframeイベントリスナで,背景色切り替えを実装します.シーンのageプロパティと,game.fpsプロパティを使って,1秒おきに切り替えます
  • クリックされると人間キャラを生む
    • フィールドに対してtouchstartイベントリスナを作り,クリックイベントが発生したら人間キャラを生むようにプログラミングします.
  • キーボード入力でクマをよろめかせる
    • フィールドのenterframeイベントリスナ内に,キー入力検知処理を追加します(1秒間にgame.fps回,検知を試みることになります).キー入力があったら,クマをよろめかせます(クマの位置と向きをランダムに変更)

  • クマや人間キャラがぶつかる
    • クマ,人間キャラ,それぞれで衝突判定をしますので,ここでの実装は不要ですが,概念的には存在するので「もの」として記載しました.

以下は,プログラムに関する簡単なコメントです.

  • まずは至るところに乱数を発生させている部分がありますので,これを関数化しました.(function rand(num)
  • enchant.Class.createを用いて,Spriteオブジェクトを継承したBearクラス(37〜68行)とHumanクラス(71〜106行)を定義し,
  • クラスの中では,任意にプロパティを追加したり(.gamecore, .degree, .vx, .vyなど),メソッドを追加したりします.
  • 実際のオブジェクト(インスタンス)は,124行目や150行目のように,newを用いて作ります.プロパティやメソッドの定義がクラス宣言部に書かれています.
  • イベントリスナは,59行目以降のthis.on('enterframe', function() {...});と書く書き方と,94行目以降のように(クラスの)メソッド定義としてonenterframe: function() {...}と書く書き方があります.どちらも違いはありませんが,論理的には後者の方が分かりやすいかもしれません.
  • Bear, Humanどちらのクラスでも共通して「壁との衝突判定」が必要ですので,関数化しています.(function reboundWall(unit)

もともとの ball プロジェクト

もともとのBallプロジェクト(by 鈴木先生)は以下を参照してください.

プロジェクトの説明および,ものと操作の洗い出しについてはココを参照してください.ちなみに当時のプロジェクトはGTK2で書かれており,古いソースはこちらのGitLabリポジトリから参照できるようになっています.

もともとの ball プロジェクトでは,ものが以下のように対応しています.

  • 人間キャラではなくて,泡
  • クマではなくて,無敵ボール
  • 複数の背景色切り替えではなくて,見守るペンギン達の行進

サンプルゲーム

enchant.jsを使った簡単なゲームを紹介します(作:木村先生).コードの詳細は解説しませんが,一式GitLabに置いてありますので,各自,動かしてみてください.

$ cd ~/csd
$ git clone https://gitlab.cis.iwate-u.ac.jp/kimura/tank.git
$ cd tank
$ chromium-browser index.html

ソースコードが短い割には,それなりのゲームになっていることが確認できるでしょうか? これがenchant.jsを使う利点の一つです.