JavaScriptでコマンド入力式の戦闘のプログラミングについて考察してみる。
まず、JavaScriptの特徴としてシングルスレッドでイベントドリブン型だということ。なので次のような実装(InqueryUserInput()
の部分)をすることが出来ない(基本的に)。
while(終了?) { var command = InqueryUserInput(); //ユーザーからのコマンド入力を待つ battle(command); //ユーザーのコマンドを元に対決 }
代わりにUIの入力完了イベントから戦闘をキックする方法が考えられる
function onClick(e) { //コマンド入力完了を示すイベントとします。
//
var command = generateCommand(); //入力情報からコマンドを生成
var result = battle(command);
if(result) { //終了?
//コマンドの入力画面の再表示
} else {
//戦闘の完了処理
}
}
そのほかにJavaScriptが苦手なのが20msそのまま待機みたいな同期 wait処理です。
よって、インターバルタイマーを使って擬似的なエージェント指向のモデルを採用した方が楽かもしれない。
下図は簡略化したシーケンス図です。:Timerから:Engine、current:Creatureへとupdate()を伝搬させ、それぞれの中で戦闘可能(【myTurn】)ならコマンドの実行を検討します。
この時、自動戦闘ならAIからコマンドを決定し、手動ならユーザーから入力されたコマンドを使用します。
また、ユーザーからのコマンドは非同期でUIから入力されるので、update()が呼び出された時点でコマンドが存在しなければ、処理をスルーします。
ここまで書くとRTSのようなシステムの方が作りやすいことに気づきます。・・・が、あくまでもターン制にこだわるので、状態遷移を導入することになります。
戦術(コマンド入力)と戦闘に状態を分け、戦術状態中はcurrent:Creatureへのupdate()の実行をブロックすることにします。
とりあえず、デモをつくりました。