前回はラリーXでつかわれる青い車とコースの作成をしました。矢印キーをおすことで移動させることができるようになりました。では次に敵の車(レッドカー)をつくり、マイカーを追尾させます。

追尾のアルゴリズムはどうするかは後で考えます。まずはレッドカーが移動できるようにしましょう。

レッドカーは1台だけではないので、リストに格納して管理します。

レッドカーも移動方向をもっています。移動しようとしている方向に壁があって動けない場合は移動できる方向を求めてその方向に移動します。

これはレッドカーのクラスです。そしてこのインスタンスを単数または複数生成してフォームクラス内にあるリスト List<RedCar> RedCars で管理します。

レッドカーにも位置情報があります。そして現在の位置情報を調べて現在の進行方向のままで進行できるかどうか調べます。進行できない場合は方向転換です。また交差点やT字路では曲がることもできます。レッドカーは基本的にUターンはしません。

Form1クラス内

RedCarクラス

まずレッドカーも道路の上のみを移動するので、マイカーと同様にRoadBlocksプロパティが必要です。そこでコンストラクタ内で渡すようにします。その他にもレッドカーの初期位置、初期の方向を渡しています。また曲がり角では直進するのか方向転換をするのかを決める乱数の初期化もしています。

マイカーと同じようにレッドカーも道路の上だけを移動します。そこでCanNorth(double x1, double y1)、CanSouth(double x1, double y1)、CanEast(double x1, double y1)、CanWest(double x1, double y1)の各メソッドを用意します(赤であっても青であっても同じ車なのだからCarクラスをつくって継承すればよかったな …… 今更)。

次にレッドカーを動かします。進行方向に移動させて、そのあと方向転換をさせることができるのであれば、IfCanChengeDirect()メソッドで方向転換をします。

IfCanChengeDirect()メソッドは変更することができる方向を取得して、そのなかからランダムに新しい進行方向を設定するメソッドです。

GetCanChengeDirects()メソッドは前述のCanNorth(double x1, double y1)、CanSouth(double x1, double y1)、CanEast(double x1, double y1)、CanWest(double x1, double y1)の各メソッドを利用して進行可能な方向を取得するメソッドです。ただし元来た道を引き返すことは原則としてできないこととします。

あとはForm1クラスにレッドカーを表示するための記述を追加します。

Timer.Tickのイベントハンドラに直接マイカーをどう動作させるかを記述していましたが、あれこれ書き加えることが増えるかもしれないので、マイカーの移動とレッドカーの移動を処理するメソッドを作成しました。

実際に描画する処理です。レッドカーも進行方向で車体の向きを変える必要があります。これで一応、動くことは動くのですが、レッドカーの動きは乱数で適当に決めているだけなので、なかなか捕まることがありません。あまり最適化された追尾アルゴリズムを採用するとすぐにゲームオーバーになってしまうし、なかなか難しい。追尾に関するアルゴリズムは後日ということで・・・。