ここ数日の有給休暇を使いJavascriptタワーディフェンスゲームを制作したので、その感想など。Javascriptはページに動作を付与する程度の使い方しかしてこなかったので、とても新鮮な体験となりました。
「Javascriptでゲーム」は現実的
作るだけなら他の言語と遜色なく使えます。特にダックタイピングは高速なコーディングに役立ちました。
課題は性能面と保守性でしょう。性能ではprototypeをきちんと使わないとメモリが無駄になるとかまとめて描画しないと遅いとか、「ならでは」の問題が面倒です。Javascriptの保守性は各方面で問題になっていますが、Googleが先鞭をつけていろいろやっているので次回は参考にしたいところです。
すべての処理を1ファイルに書くには、処理どう構成すべきだったか
従来書いていたような簡単な処理ならば問題になりにくかったのですが、ゲーム1本となるとより細かなコード構成の指針が必要だと感じました。具体的には、コードの巨大化に伴う無名関数内グローバル変数の増大が目立ってしまいました。
ゲームを構成する要素を予め想定し、役割ごとにインスタンスを作っておくべきだったでしょう。今回は途中からユニットの描画を担うDrawerが登場したこともあり、無駄にややこしいコードとなってしまいました。
今考えると「ユニットや武器の状態管理」「描画処理」に専念するインスタンスを作成し、これらを協調動作させるゲームエンジンインスタンスから呼び出す形を明確にしておくべきだったかもしれません。経路情報や2D contextを各インスタンスに隠蔽することができ、若干ですが読みやすくなります。
(function() { /* ユニットの定義(何度もnewするのでprototypeを利用) */ function Unit(x, y) { this.x = x; this.y = y; } Unit.prototype.move = function unitMove(){ /* ...*/ }; // ... /* 描画担当インスタンス */ var drawer = { /* ... */ }; /* ユニット管理インスタンス */ var unitController = { /* ... */ }; /* ゲームエンジン */ var gameEngine = { init: function init() { drawer.init(); unitController.init(); }, scheduled: function scheduled() { this.calc(); this.draw(); }, calc: function calc() { unitController.move(units, weapons); unitController.checkHit(units, weapons); }; draw: function draw() { drawer.draw(units, weapons); }, frame: 0, score: 0, gold: 0, life: 10, units: [], weapons: [] }; // ゲームの初期化 window.onload = function(){ gameEngine.init(); setInterval(gameEngine.scheduled, 200); }; })();
jsdo.itでは1ファイルしか扱えませんが、本来ならユニット定義を別ファイルに切り出したいところです。しかし通信回数が増えることを考えるとベストとは言えません。開発段階では別ファイルとして扱い、配信段階でこれを結合するようなフローを考えるのが適切なのでしょう。
マルチブラウザ対応の難しさ
それこそ大昔から言われていることですが、APIが規定されているHTML5ですらマルチブラウザ対応の難しさは変わらないようです。書いたコードがOperaでのみ正常動作せず再現コードを書くなどの工程が必要になりました。Operaの不具合というわけではなく、引数省略時の動作が規定されていないことが原因です。
一応MacBookでOpera・Chrome・Safari・Firefoxをひと通り試せていますが、IE+ExplorerCanvasはまだ試せていません。IEはOS縛りや複数バージョンでの確認が難しい点など、個人開発でサポートするには辛い面が多すぎる印象です。
jsdo.it面白い
今回の開発で初めてjsdo.itに触れました。立ち読んだ雑誌で紹介されていたので少し覗いてみた、くらいのノリでしたが、実際使い始めると
- 頻繁に書込/更新されている
- 多くのユーザが更新を確認している
- forkされる/すると楽しいし勉強になる
など開発者向けサイトとして興味深い特徴を持っています。知的好奇心を満たすだけでなく、スキルの蓄積や新たな発見につながるところが素晴らしいです。JavascriptやHTML5、CSSに興味をお持ちの方はぜひ。