敵の追跡アルゴリズムを改良します。
広いフィールドを敵(レッドカー)はランダムに動きます。これではなかなか捕まりません。かといって最適化された追跡アルゴリズムを実装してしまうと敵が複数台いてはすぐに挟み撃ちにあってしまうでしょう。敵の動きが見当外れなのでもう少し追跡アルゴリズムを改善します。
レッドカーはマイカーに可能であれば接近するような動き方をするように改良します。マイカーが自分よりも左下にいるのであれば左または下方向に動きます。その方向に移動できない場合はランダムに移動方向を決めます。
まずマイカーの位置はForm1クラス内で管理しているのですが、これにアクセスできるようにプロパティを作成します。
これでForm1.MyCarX、Form1.MyCarYとすればマイカーの位置を取得することができます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
public partial class Form1 : Form { // 既存のフィールド変数に static をつけた static double _eyeX = 12; static double _eyeY = 3; static public double MyCarX { get { return _eyeX; } } static public double MyCarY { get { return _eyeY; } } } |
既存のメソッド IfCanChengeDirect()を修正します。
GetCanChengeDirects()メソッドはレッドカーの移動可能な方向を返しますが、このなかにマイカーを効率よく追うことができる方向があるかどうか(マイカーが北東に見えるときにそのレッドカーは北か東に移動できるかどうか)を調べます。
もし効率よく追うことができる方向に移動可能であれば、それを優先的に選択します。複数ある場合(例えばマイカーの位置は北東でそのレッドカーは北へも東にも移動可能な場合など)は乱数で決めます。もし効率よく追うことができる方向に移動できないのであれば従来どおりの方法で取得します。
これだとレッドカーがマイカーがある位置に集まりやすくなり、ゲームの難度を上げることができます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 |
public class RedCar { void IfCanChengeDirect() { List<Direct> directs = GetCanChengeDirects(); if(directs.Count > 0) { bool north = false; bool south = false; bool east = false; bool west = false; // 効率よく追うことができる方向を取得する if(X < Form1.MyCarX) east = true; if(X > Form1.MyCarX) west = true; if(Y < Form1.MyCarY) north = true; if(Y > Form1.MyCarY) south = true; // 効率よく追うことができる方向に進路変換は可能か? List<Direct> directs2 = new List<Direct>(); if(directs.Any(x => x == Direct.North) && north == true) directs2.Add(Direct.North); if(directs.Any(x => x == Direct.South) && south == true) directs2.Add(Direct.South); if(directs.Any(x => x == Direct.West) && west == true) directs2.Add(Direct.West); if(directs.Any(x => x == Direct.East) && east == true) directs2.Add(Direct.East); if(directs2.Count == 1) { // 効率よく追うことができる方向がひとつだけならそれを選ぶ CurDirect = directs2[0]; } else if(directs2.Count > 1) { // 効率よく追うことができる方向が複数あるなら乱数で決める int i = random.Next(0, directs2.Count); CurDirect = directs2[i]; } else { // 効率よく追うことができる方向に移動できない場合はこれまでどおりの方法で選ぶ int i = random.Next(0, directs.Count); CurDirect = directs[i]; } } else { // 袋小路にはまった場合はバックする if(CurDirect == Direct.North) CurDirect = Direct.South; else if(CurDirect == Direct.South) CurDirect = Direct.North; else if(CurDirect == Direct.East) CurDirect = Direct.West; else if(CurDirect == Direct.West) CurDirect = Direct.East; } } } |
また、参考にさせていただきました。ラリーXもどきの敵カー追跡ロジックを丸パクリで実装してみました。結構それっぽく追跡されています。C#DxLibで作成中です。