ゲープロ講座セッション8:戦術SLGの移動アルゴリズム(6)
- 敵のルーチンの実装 |
みなさんこんにちは、鷹月ぐみなです。1ヵ月半のご無沙汰になりましたが、いかがお過ごしでしたでしょうか。私はいつものように業務をしながら帰宅後に創作活動といった感じでしたが、少しばかりハードだったように感じます。社員代表でスピーチしてみたり、仕事と全然関係ない所で日本音響学会に論文を発表してみたり。創作ではサークルで小さなACTゲームもリリースしました。こんな感じですから、講座の続きを書くことは実は容易ならざるものがあるのですが(^^;)、あまり間を開けすぎちゃいけないね、という事で強行しました。SLG編もあと3回、内容もやや高度になってきてますが気張っていきましょう。 |
それでは始めましょうか。前回とは密接に関わっているので、「あれ、前回何やったっけ?」という方は見直して復習しておいてくださいね。
S-1) 初期設定 S-2) [Player's Turn] ユニット選択(但し1キャラのみ) S-3) [Player's Turn] 移動先座標選択 S-4) [Player's Turn] プレイヤー最短移動 S-5) [Enemy's Turn] 最適探索 S-6) [Enemy's Turn] 敵さん側最短移動、そして S-2)に戻る
動かせる環境にある方は、さっそくDLして動かしてみてください。内容的にはセッション3のサンプルに敵の移動が付加されただけで、センセーショナルな違いというのはないのですが、それなりに相手がプレイヤー目指してちょこちょこ動いてくる所なんか、「おおっ」と思ってしまうかもしれません。ソースは完全にセッション6で決めた流れに沿って実装しています。
敵さんB:通常型(PCとの単純距離差が10以内なら近づいてくる) 敵さんC:守備型(PCとの単純距離差が3以内になった所で近づき、以後は距離に関係なく常にプレイヤーを追いかけるA型になる) 敵さんD:ピボット型(ある地点から単純距離半径6以上の地点へは何があっても進めない。その範囲の中でプレイヤーに近づこうとする) 敵さんE:アーチャー(単純距離差が10以内で近づくのだが、主人公からの単純距離差が3になる地点を確保しようとする)
|
以下、Delphiソースの解説です。HSPなど他の言語を常用している方には、「なんだかよく分からんムー」とか拒絶感を持ってしまうかも知れませんが、見た目の体裁が違うだけで、アルゴリズムは大体似たようなものになるはずです。コメント解説もそれなりに多く入れましたので、ゆっくり見ていけば、これがどんな働きをしているのか、分かる事と思います。
|
S-1) 初期処理
S-1) というのは流れ一覧で示したラベルですね。ここでやっている処理はほとんど初期変数の代入です。マップやカーソル、主人公に敵さんの表示位置を入れているくらいですか。このプロシージャの最後にマップを読み込み、そこで初期処理は終わります。細かい変数の意味は……そうですね、一応しておきましょう。
stat:ゲームの流れを制御するフラグです。S-1) 〜 S-6) といった単位だと思ってください。この後解説するメインループ処理でどのように制御しているのか分かるはずです。
|
メインループ
S-1) 初期設定が終わったら、早速プログラムはメインループに入ります。このシステムはフレームで制御していまして、fps値(1秒間にループを周る数)は20です。その数だけこのプロシージャ MainJob()を呼び出すわけですが……やっている事は非常に単純、現在のstat値を調べ、対応する1つのサブルーチンを呼んでいるだけです。このstatは1〜6において、S-1) 〜 S-6) と対応しています。サブルーチンの中のどこかでstat値が書き換えられた場合、次のループから違う処理が発生するわけですね。
|
S-2) ユニット選択
コメントにも書いていますが、今回はプレイヤーは1キャラしかいないのにも関わらずキャラ選択させられます。このフェイズでの主な処理は、スペースキーを押すとちょっとした関数を呼んでS-3) に移動する事、それからキーを離していた場合はトグルをリセットする事、それから共通処理であるFourstick(カーソル移動処理)→StatusPrint(状態表示)→MapPrint(キャラやカーソルを画面に表示する)、これで全てです。
ソースだけベタ貼りしてみましたが、セッション3の関数と比べると、微妙にコードが増えているだけで、あとはまるきし同じです。あ、移動歩数値……セッション6で決めたポリシーによると、3の床作らないつもりだったけど、直してなかったです。ごめんね〜。
これは正直、見たまんまです。注目すべきは、MapPrint() の中にある「100+zy」という記述。これがウワサのZレイアです。y座標が高いキャラにZレイアを高く設定しておけば、
|
S-3) 移動先座標選択
探索手続きが終わった後はこのS-3) の処理を行います。なんとなくS-2) と同じようなコードになっていますね。違うのは、移動範囲を教えてくれるフィルタを表示する命令が付け加わっているくらいでしょうか。もっともフィルタの正体は1枚のマップであり、具体的なフィルタの配置は先のArch() で行っているので、ここでは単に表示しているだけです。
|
S-4) プレイヤー最短移動
S-4) は、mvrec[移動したい場所]に入っている経路情報(Arch() の時に書き込みましたね)を取り出し、その通りに主人公を動かすという処理を行っています。ここのロジックは、Arch() の部分と合わせて見ないと分かりにくいかもしれません。例えば「23443」と格納されていたら、プレイヤーは右下左左下と動くわけです。 そして動ききってしまった場合、次はS-5) で、いよいよ敵さんの処理に入ります。enum:=1 という部分で、敵1番を次の行動キャラクターと指定しています。
|
ページが長くなったので分割しています→ ∇ 続き(6−2)へ
|