図5●戦闘処理のフロー
図5●戦闘処理のフロー
[画像のクリックで拡大表示]
表1●MyCharクラスのメンバー
表1●MyCharクラスのメンバー
[画像のクリックで拡大表示]
図6●<b>リスト3の(1)</b>で表示される画面
図6●<b>リスト3の(1)</b>で表示される画面
[画像のクリックで拡大表示]
図7●鎖状の配列を使って行動順を管理する。図の一番下では敵1~3の後ろのマス目にタダが移動するが,配列が鎖状になっているので一番前に移動する
図7●鎖状の配列を使って行動順を管理する。図の一番下では敵1~3の後ろのマス目にタダが移動するが,配列が鎖状になっているので一番前に移動する
[画像のクリックで拡大表示]
図8●リスト4でキャラの行動順を表示させたところ
図8●リスト4でキャラの行動順を表示させたところ
[画像のクリックで拡大表示]
リスト2●クラスMyCharのコード(基本的な枠組みのみ)
リスト2●クラスMyCharのコード(基本的な枠組みのみ)
[画像のクリックで拡大表示]
リスト3●クラスからインスタンスを作成するコード
リスト3●クラスからインスタンスを作成するコード
[画像のクリックで拡大表示]
リスト4●鎖状の配列を使って行動順を管理するコード
リスト4●鎖状の配列を使って行動順を管理するコード
[画像のクリックで拡大表示]

戦闘のルールを決める

 画面が用意でき,メッセージ・キューの仕組みが理解できたところで,ゲームのロジックの作成に取り掛かりましょう。まず,戦闘のルールを決めます。今回は,味方3対敵3で行う戦闘とします。まず,戦闘に参加する味方と敵のキャラクター(キャラ)を決めて,戦闘順を決めます。ここではキャラごとに「素早さ」というパラメータを設け,その値に応じて順番に対象を攻撃することにします。

 次に,攻撃処理です。攻撃は「攻撃力」「防御力」というパラメータを設け,その値の差分だけを相手にダメージを与えるものとします。ダメージを受けた対象は,「体力」というパラメータからダメージ分を減算し,体力が0になった時点で戦闘不能状態となります。この一連の処理を繰り返し,先に敵・味方のどちらかが全員戦闘不能状態となった時点で,戦闘終了とします。

 今回は,あらかじめ敵味方の行動を決めて全員の攻撃が終わった時点で「1ターン経過」としてターンを繰り返す「ターン制」ではなく,「素早さ」の値に応じて戦闘する順番を随時調整しながら攻撃を繰り返す「時間制」にしてみましょう。

 さらに,3人の味方キャラのうち,一人だけをユーザーが操作し,残りの二人はパソコン(PC)が自動的に操作をする形にします。この処理の流れを図にすると図5[拡大表示]のようなフローとなります。このフローに沿って,個々の処理を作っていきましょう。

クラスから
敵と味方のキャラを作成する

 まず,戦闘に参加するキャラを決定します。今回は3対3ですので,必ず6人のキャラが戦闘に参加する形となります。キャラは敵と味方を合わせて6インスタンス作成するわけですが,このキャラの“ひな型”をクラスとして定義しましょう。クラスが備えるメンバーは表1[拡大表示]の通りです。

 ActionScriptでクラスを作成するには,拡張子.asのテキスト・ファイルを作成します*6。表1の仕様に従ってリスト2[拡大表示]のようにコードを記述したテキスト・ファイルを,Flashドキュメントと同じフォルダにMyChar.asという名前で保存します。この時点では二つのメソッドは,returnステートメントを使ってメッセージを返すだけにしておきます。

 クラスを利用するには,

new クラス名(引数)

という命令でクラスのインスタンスを作成します。この際,クラス内にクラス名と同名の関数であるコンストラクタ関数を作成しておくと,最初にその関数を自動的に初期化処理として実行します。ここでは,引数として渡した値を利用して,インスタンスを初期化することにします。具体的には,クラスMyCharのコンストラクタ関数(リスト2の(1))で,名前・体力・攻撃力・防御力・素早さ・タイプの六つを引数として受け取り,それぞれのキャラのインスタンスのプロパティ値として設定します。

 クラスからインスタンスを作成するコードはリスト3[拡大表示]のようになります*7。味方のキャラを管理する配列myPartyと,敵のキャラを管理する配列enemiesをそれぞれ宣言します。それぞれの配列には,newステートメントを使用して生成したMyCharクラスのインスタンスを三つずつ格納します。その際,引数を使ってコンストラクタ関数に必要な情報を渡します。このようにして戦闘に参加する6人のキャラの準備を行います。このコードをbattleWindowのメインのタイムラインに記述します。

 (1)は,traceステートメントを使用して配列に格納したインスタンスがきちんと管理されているかをチェックするコードです。シーンプレビューを行ってみてください。個々のインスタンスに個別のプロパティ値が設定され,メソッドが機能していることを確認できますね(図6[拡大表示])。

鎖状の配列を利用して
戦闘の順番を管理する

 次に,戦闘を行う順序を配列を使って管理します。6個の要素を持つ時間軸をイメージした配列actionChainと,現在の時間位置を管理するインデックス用の変数actionIteratorを用意します。ちょうど6フレームのタイムラインと,カレントフレームを管理する_currentframeプロパティのようなイメージですね。

 この配列に,個々のキャラの「素早さ」(_sp)の値に応じて行動順を指定していきます。リスト2で設定した値を参考にすると図7[拡大表示]のようになります*8。戦闘を開始したら,actionIteratorを使って「現在位置」をチェックします。現在位置に行動できるキャラがいない場合には,位置を一つずつ後ろに進めてキャラが格納されている個所まで移動します。キャラが見つかったら,そのキャラの攻撃処理を行います。攻撃処理が済んだら,そのキャラを現在位置から「素早さ」の分だけ後ろへと移動し,次に攻撃するキャラの処理に移ります。この処理を戦闘が終わるまで繰り返していきます。

 現在位置が時間軸を管理する配列の末尾に達したら,次は先頭へと戻します。配列の先頭と末尾を,インデックス用の変数を使って1本のつながった鎖のように扱うわけですね。同様に,攻撃を終えたキャラの移動先が時間軸の範囲を超えている場合は,超えた分を先頭から数えた位置に移動させます。

 この処理をコードにすると,リスト4[拡大表示]のようになります。配列を鎖状に扱いたい場合は,剰余演算子(%)を使用します。任意の値を配列の長さで除算した剰余を利用すれば,値に応じて配列内の任意の位置のインデックス番号となるわけですね。リスト3のコードにリスト4のコードを追加してシーンプレビューを行うと,行動(戦闘)する順番を確認できます(図8[拡大表示])*9

下記のURLから、サンプル・プログラムを無償ダウンロードできます。
http://software.nikkeibp.co.jp/software/download/down05c.html#200503