enchant.js応用編
クラスを使う
JavaScriptでは長い間,クラスを使うことができませんでした.最近になって,ようやく(ES2015から)正式にクラスもサポートされるようになりましたが,enchant.jsでは,ES2015よりも以前から,独自の実装によってクラス的な書き方を可能としていました.
ここでは,具体例によってクラス的な書き方を学びましょう.
Ballプロジェクト
オブジェクト指向プログラムの具体例として「Ballプロジェクト」を取り上げます. Ballプロジェクトは,代々引き継がれているプロジェクトです(鈴木先生 → 木村先生 → 山中). まぁ,まずは動かしてみましょう.
READMEやhtmlまで含めたプロジェクト全体のプログラムは
に置いてあります.各自,クローンして試してみてください.
$ 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を使う利点の一つです.
なお,この講義では,次回以降に解説予定のWebSocketを使ってこのtankゲームをネットワーク対戦型に拡張してみます.
enchant.jsで作った作品をデスクトップアプリにしてみる
Electronを利用すると,JavaScript(とHTML5とCSS3)でデスクトップアプリケーションを作成できます.MITライセンスなので,無料で使えるだけでなく,商用で利用することも可能です.特長は
- WEB技術(JavaScript+HTML5+CSS3)だけでアプリまで作成できる,つまり,普段と変わらぬ開発環境が使える
- マルチプラットフォーム(Linux, Windows, Mac向けが可能)
- 扱いが(比較的)簡単
といったところです.Electron製アプリは,ChromiumとNode.jsがベースになっています.
以下では,サンプルゲームとして紹介した
を,デスクトップアプリにしてみます.
Electronを使うための環境設定
Node.jsの設定が済んでいれば,npmを使ってElectronをインストールするだけです.
$ npm -g install electron
-g
オプションはグローバル環境にインストールすることを意味し,どこ(のディレクトリ)でもElectronが使える形になります.
アプリケーションの作成
まずは元となるtankゲームのソースを展開します.(すでに手元に作業コピーがあるならこの手順は不要です)
$ cd ~/csd
$ git clone https://gitlab.cis.iwate-u.ac.jp/kimura/tank.git
このtank
ディレクトリがアプリケーションの元となりますので,まずはnpm init
します.
$ cd tank
$ npm init -y
以下のようなpackage.json
ファイルが(自動で)作られます.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | {
"name": "tank",
"version": "1.0.0",
"description": "## 遊び方",
"main": "tank.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"repository": {
"type": "git",
"url": "https://gitlab.cis.iwate-u.ac.jp/kimura/tank.git"
},
"keywords": [],
"author": "",
"license": "ISC"
}
|
このファイルの5行目を,以下のように修正してください.(tank.js
をindex.js
に)
1 | "main": "index.js",
|
さらに,index.js
ファイルを新たに作ります.
var electron = require('electron'); var app = electron.app; var BrowserWindow = electron.BrowserWindow; var mainWindow = null; app.on('ready', function() { // Chromiumブラウザの起動とindex.htmlのロード mainWindow = new BrowserWindow({width: 360, height: 360}); mainWindow.loadURL('file://' + __dirname + '/index.html'); mainWindow.on('closed', function() { mainWindow = null; }); });
これだけでデスクトップアプリとして起動できるはずです.次のように実行してみましょう.
$ cd ~/csd
$ electron tank/
ウィンドウが表示されて,ゲームが実行できたでしょうか?
アプリケーションのアーカイブ
次に,作ったデスクトップアプリをアーカイブします.asar
というツールを使うので,まずはインストールします.
$ npm -g install asar
アーカイブするには以下のようにします.
$ cd ~/csd
$ asar pack ./tank ./tank.asar
成功すると(カレントディレクトリに)tank.asar
という名前でアーカイブファイルが作られます.これはelectronで実行できます.
$ electron tank.asar
先ほどと同様にウィンドウが表示されて,ゲームが実行できるはずです.
配布用のアプリケーションにする
asarファイルは,electronをインストールして利用環境を整えているユーザにしか実行できません.そこで,Electronの実行環境まで(アプリケーションと)一緒にパッケージングして,誰でも実行可能なファイルを作ってみます.
まずはelectron-packager
というツールをインストールします.
$ npm -g install electron-packager
これを使ってパッケージングします.例えば,Linux(Ubuntu)向けなら
$ electron-packager ./tank tank --platform=linux --arch=x64 --electronVersion=1.8.4
とします.各オプションについては以下を参考にしてください.
platform
・・・linux
,win32
(Windows),darwin
(Mac)のいずれか,または,
(カンマ)で区切って複数指定します.all
とすると三つとも作成を試みますarch
・・・アーキテクチャの指定です.ia32
(32bit)またはx64
(64bit)electronVersion
・・・パッケージングするelectronのバージョンを指定します.使用中のelectronバージョンはelectron --version
とすれば調べられます
少し待つと,カレントディレクトリに「tank-linux-x64」というディレクトリが作成され,その下に実行に必要なファイル群一式が配置されているはずです.実行形式ファイルtank
でアプリを実行できます.
$ cd tank-linux-x64
$ ./tank
なお,WindowsやMac用にパッケージングした場合は,ダブルクリックでそのまま実行できるファイルがちゃんと作られます.
プラグインを使う場合
enchant.jsには,機能拡張のためのさまざまなプラグインが用意されていますが,利用にあたってはいくつか注意が必要です.
HTMLへの追加
src
属性にプラグインパスを指定したscript
タグを記述する必要があります.
1 2 3 4 5 6 7 8 9 10 11 12 13 | <!DOCTYPE html> <html> <head> <title>プラグインを使う!</title> <meta charset="utf-8" /> <script src="http://wiki.cis.iwate-u.ac.jp/~wiki/csd/js/enchant.js" type="text/javascript"></script> <!-- プラグインも使う場合は必要なscriptタグを下記に追加 --> <script src="http://wiki.cis.iwate-u.ac.jp/~wiki/csd/js/plugins/tl.enchant.js" type="text/javascript"></script> </head> <body> ・・・ </body> </html> |
各プラグインを使う場合,プラグイン自身が利用を前提としている画像などを適切に配置しなければなりません.一例を以下に記述しておきます.
ui.enchant.jsプラグイン
バーチャルパッド(十字キーパッド,アナログパッド)の機能や,グラフィックスフォントを使用したラベル(スコア,ライフ,タイム)などの機能を提供してくれますが,これを使う場合には
- pad.png
- apad.png
- icon0.png
- font0.png
を,適切に配置する必要があります.(HTMLファイルと同じ階層に置いておくのが一番手っ取り早いです)
memory.enchant.js
HTML5からサポートされているブラウザのlocalStorage
機能を使って,セーブ機能を提供してくれます.これを使う場合は
- indicator.png
が必要になるとともに,「nineleap.enchant.jsプラグインと合わせて」組み込む必要があります.(memory.enchant.js単独では使えません)
nineleap.enchant.js
上記のmemory.enchant.jsで必要となるほか,ゲームスタート/ゲームオーバー画面を表示しれくれる機能が追加されます.
- start.png
- end.png
が必要です.
他にも多くのプラグインが利用できますが,細かい使い方などについては各自で調べてください.
enchantMapEditor
特にRPG作成を予定している班は,以下のマップエディタを使うと便利かもしれません.
使い方は解説しませんので,上記ページのREADMEをよく読んでください.