因爲單獨使用BFS路徑規劃出現AI全部排隊在最優路徑上的窘境,後來發現,其他人在設計SLG游戲時用的并不是最優路徑解,而是流體場概念,簡單說就是一群兵要通過一個狹隘的關口,如何表現這樣的過程
public static void BFSDistCalc(MyPoint p, int[,] data, float[,] flow, Vector2[,] vector,
int[] xrange, int[] yrange, bool canfly = false,
bool demoShow = false, ECamp camp = ECamp.Any)
{
Dictionary<MyPoint, bool> beenOp = new Dictionary<MyPoint, bool>();
float sqrt2 = 1.414f;
Queue qpoints = new Queue();
data[p.X, p.Y] = -1;
flow[p.X, p.Y] = 0;
vector[p.X, p.Y] = Vector2.zero;
qpoints.Enqueue(p);
while (qpoints.Count > 0)
{
MyPoint qp = (MyPoint)qpoints.Dequeue();
if(beenOp.ContainsKey(qp)) continue;
beenOp.Add(qp, true);
for (int i = 0; i < 8; i++)
{
var nextQP = new MyPoint(qp.X + dirMove[i][0], qp.Y + dirMove[i][1]);
if (beenOp.ContainsKey(nextQP)) continue;
if (nextQP.X == 0 && nextQP.Y == 0) continue;
//檢查能不能通行
if (!IsCanWalkPot(new int[2] { nextQP.X, nextQP.Y }, data[nextQP.X, nextQP.Y], canfly, camp, demoShow,
chkEntExist: true))
{
flow[nextQP.X, nextQP.Y] = 1999.999f;
continue;
}
//使否越界, 只跑上下左右
if ((nextQP.X >= yrange[0]) && (nextQP.X < yrange[1]) &&
(nextQP.Y >= xrange[0]) && (nextQP.Y < xrange[1]) )
{
float diff = i % 2 == 0 ? 1f : sqrt2;
flow[nextQP.X, nextQP.Y] = flow[qp.X, qp.Y] + diff;
qpoints.Enqueue(nextQP);
}
}
}
beenOp.Clear();
qpoints.Clear();
qpoints.Enqueue(p);
while (qpoints.Count > 0)
{
MyPoint qp = (MyPoint)qpoints.Dequeue();
if (beenOp.ContainsKey(qp)) continue;
beenOp.Add(qp, true);
float minDist = flow[qp.X, qp.Y];
Vector2 minDir = new Vector2(qp.X, qp.Y);
for (int i = 0; i < 8; i++)
{
var nextQP = new MyPoint(qp.X + dirMove[i][0], qp.Y + dirMove[i][1]);
//使否越界, 只跑上下左右
if ((nextQP.X >= yrange[0]) && (nextQP.X < yrange[1]) &&
(nextQP.Y >= xrange[0]) && (nextQP.Y < xrange[1]))
{
var near = flow[nextQP.X, nextQP.Y];
if (near > 1999.0f) continue;
if (near >= 0 && near < 1999.0f)
{
if (near < minDist)
{
minDist = near;
minDir = new Vector2(nextQP.X, nextQP.Y);
}
}
if (!beenOp.ContainsKey(nextQP))
{
qpoints.Enqueue(nextQP);
}
}
}
var dir = (Vector2)(minDir - new Vector2(qp.X, qp.Y));
dir.Normalize();
vector[qp.X, qp.Y] = new Vector2(dir.x, dir.y);
}
}
int[] xrange, int[] yrange, bool canfly = false,
bool demoShow = false, ECamp camp = ECamp.Any)
{
Dictionary<MyPoint, bool> beenOp = new Dictionary<MyPoint, bool>();
float sqrt2 = 1.414f;
Queue qpoints = new Queue();
data[p.X, p.Y] = -1;
flow[p.X, p.Y] = 0;
vector[p.X, p.Y] = Vector2.zero;
qpoints.Enqueue(p);
while (qpoints.Count > 0)
{
MyPoint qp = (MyPoint)qpoints.Dequeue();
if(beenOp.ContainsKey(qp)) continue;
beenOp.Add(qp, true);
for (int i = 0; i < 8; i++)
{
var nextQP = new MyPoint(qp.X + dirMove[i][0], qp.Y + dirMove[i][1]);
if (beenOp.ContainsKey(nextQP)) continue;
if (nextQP.X == 0 && nextQP.Y == 0) continue;
//檢查能不能通行
if (!IsCanWalkPot(new int[2] { nextQP.X, nextQP.Y }, data[nextQP.X, nextQP.Y], canfly, camp, demoShow,
chkEntExist: true))
{
flow[nextQP.X, nextQP.Y] = 1999.999f;
continue;
}
//使否越界, 只跑上下左右
if ((nextQP.X >= yrange[0]) && (nextQP.X < yrange[1]) &&
(nextQP.Y >= xrange[0]) && (nextQP.Y < xrange[1]) )
{
float diff = i % 2 == 0 ? 1f : sqrt2;
flow[nextQP.X, nextQP.Y] = flow[qp.X, qp.Y] + diff;
qpoints.Enqueue(nextQP);
}
}
}
beenOp.Clear();
qpoints.Clear();
qpoints.Enqueue(p);
while (qpoints.Count > 0)
{
MyPoint qp = (MyPoint)qpoints.Dequeue();
if (beenOp.ContainsKey(qp)) continue;
beenOp.Add(qp, true);
float minDist = flow[qp.X, qp.Y];
Vector2 minDir = new Vector2(qp.X, qp.Y);
for (int i = 0; i < 8; i++)
{
var nextQP = new MyPoint(qp.X + dirMove[i][0], qp.Y + dirMove[i][1]);
//使否越界, 只跑上下左右
if ((nextQP.X >= yrange[0]) && (nextQP.X < yrange[1]) &&
(nextQP.Y >= xrange[0]) && (nextQP.Y < xrange[1]))
{
var near = flow[nextQP.X, nextQP.Y];
if (near > 1999.0f) continue;
if (near >= 0 && near < 1999.0f)
{
if (near < minDist)
{
minDist = near;
minDir = new Vector2(nextQP.X, nextQP.Y);
}
}
if (!beenOp.ContainsKey(nextQP))
{
qpoints.Enqueue(nextQP);
}
}
}
var dir = (Vector2)(minDir - new Vector2(qp.X, qp.Y));
dir.Normalize();
vector[qp.X, qp.Y] = new Vector2(dir.x, dir.y);
}
}
红色標記的是向量場的起點
留言
張貼留言