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
イベントリスナに「クマとの衝突判定」を入れます(スプライトのintersect
やwithin
メソッドを使うと簡単).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を使う利点の一つです.