動作確認はこちらからどうぞ。

これまで作成したパックマンではモンスターはランダムに移動するだけなので、なかなかパックマンを捕まえることができませんでした。そこで追跡アルゴリズムを考えます。

では追跡をするときはどうやって追跡させればよいのでしょうか?

パックマンの位置をしらべて、モンスターはそこへ接近するように動かします。壁があってその方向に動けない場合は動ける方向に移動させます。迷路の形状やお互いの位置関係から単純に両者を接近させようとすると逆に遠回りになることもありますが、迷路はそんなに複雑な形状をしていないので、まあいいでしょう。モンスターを誘導してうまく逃げるという遊び方もあるでしょう。

モンスターはUターンは原則としてしないので(本物のパックマンではパワー餌を食べたわけではないのに一斉に方向転換することがある)、方向転換可能地点で適切な方向に転換させます。

X座標を調べてモンスターの座標のほうが大きい場合は左へ、小さい場合は右、Y座標を調べてモンスターの座標のほうが大きい場合は上へ、小さい場合は下へ移動させます。左右の移動と上下の移動をズレが大きいほうを優先的に採用します。

MonsterクラスのMove関数を少し変えます。

そしてモンスターの移動方向を考えさせるThinkDirect関数を以下のようにしてみます。

GetMonsterDirect関数にパックマンの座標を与えればパックマンを追いかけるようになりますが、問題点もあります。

このアルゴリズムの問題点はモンスターが1箇所に集中してしまうことです。パックマンを先頭にしたモンスターの大名行列ができてしまいます。

ところでモンスターにはそれぞれ名前があり、個性もあります。

赤 オイカケ アカベエ
パックマンの後ろをひたすら追いかける

ピンク マチブセ ピンキー
頭脳タイプで先回りをする。パックマンのいる地点の少し前を目指して動く。

青 キマグレ アオスケ
気まぐれタイプ。パックマンを中心にして、赤の点対称の位置を最短距離で目指して行動する。

オレンジ オトボケ グズタ
好き勝手タイプ。何も考えず自由に行動する。パックマンより遠いところにいるときは追いかけ、近いところにいるときは逃げる。

実際には必ずこのとおりに動くわけではないのですが、ここでは上記にあわせてつくります。

ThinkDirectの引数でGetMonsterDirectに与える座標を変えればいいですね。

一応、これでそれっぽい動きになりました。