private static void UF_ReleaseASGridData(ASGridData data) { if (data != null) { s_GridDataPool.Release(data); } }
private static ASGridData UF_AcquireASGridData() { ASGridData data = s_GridDataPool.Get(); if (data == null) { data = new ASGridData(); } return(data); }
static bool UF_Contains(List <ASGridData> list, ASGridData target) { int index = list.Count - 1; for (int k = index; k > -1; k--) { if (list [k] == target) { return(true); } } return(false); }
/// <summary> /// 获取两个节点之间的距离 /// </summary> static int UF_GetDistanceNodes(ASGridData a, ASGridData b) { /// 对角线估价法 int cntX = Math.Abs(a.X - b.X); int cntY = Math.Abs(a.Y - b.Y); return(cntX > cntY ? 14 * cntY + 10 * (cntX - cntY) : 14 * cntX + 10 * (cntY - cntX)); ////几何估价法 //int dx = a.X - b.X; //int dy = a.Y - b.Y; //return (int)(Math.Sqrt(dx * dx + dy * dy) * 10); //// 曼哈顿估价法 //return Math.Abs(a.X - b.X) * 10 + Math.Abs(a.Y + b.Y) * 10; }
/// <summary> /// 生成路径 /// </summary> static void UF_GeneratePath(ASGridData startNode, ASGridData endNode, List <ASGridData> outGrids) { outGrids.Clear(); if (endNode != null) { ASGridData temp = endNode; while (temp != startNode) { outGrids.Add(temp); temp = temp.parent; } outGrids.Add(startNode); // 反转路径 outGrids.Reverse(); } }
//检查邻居节点合法性 //*0 //0* //斜方向 static private bool UF_CheckNeibourhoodValid(ASGrid asGrid, ASGridData a, ASGridData b) { int minX = a.X < b.X ? a.X : b.X; int minY = a.Y < b.Y ? a.Y : b.Y; int vCount = 0; int width = asGrid.width - 1; int height = asGrid.height - 1; for (int k = 0; k < 2; k++) { for (int i = 0; i < 2; i++) { if (asGrid.UF_GetState(Math.Min(minX + i, width), Math.Min(minY + k, height)) == 0) { vCount++; } } } return(vCount >= 3); }
/// <summary> /// 查找线路 /// </summary> /// <returns>如果没有线路 则返回null </returns> static public void UF_FindingPath(ASGrid asGrid, int startX, int startY, int endX, int endY, List <ASGridData> outGrids) { int width = asGrid.width; int height = asGrid.height; m_LOpen.Clear(); m_LClose.Clear(); ASGridData startNode = asGrid.UF_GetData(startX, startY); ASGridData endNode = asGrid.UF_GetData(endX, endY); if (startNode == null || endNode == null) { return; } m_LOpen.Add(startNode); while (m_LOpen.Count > 0) { ASGridData curNode = m_LOpen[0]; for (int i = 0, max = m_LOpen.Count; i < max; i++) { if (m_LOpen[i].fCost <= curNode.fCost && m_LOpen[i].hCost < curNode.hCost) { curNode = m_LOpen[i]; } } m_LOpen.Remove(curNode); m_LClose.Add(curNode); // 找到的目标节点 if (curNode == endNode) { UF_GeneratePath(startNode, endNode, outGrids); return; } //未有邻近点,生产并记录 if (curNode.Neibourhood == null) { curNode.UF_GenNeibourhood(width, height); } // 判断周围节点,选择一个最优的节点GenNeibourhood for (int k = 0; k < curNode.Neibourhood.Length; k++) { ASGridData tempGrid = asGrid[curNode.Neibourhood [k]]; // 如果是墙或者已经在关闭列表中 if (!UF_CanPass(tempGrid.State) || m_LClose.Contains(tempGrid)) { continue; } //判断斜方向邻居点,共享点必须为可行走区域 if (!UF_CheckNeibourhoodValid(asGrid, curNode, tempGrid)) { continue; } // 计算当前相领节点现开始节点距离 int newCost = curNode.gCost + UF_GetDistanceNodes(curNode, tempGrid); // 如果距离更小,或者原来不在开始列表中 if (newCost < tempGrid.gCost || !UF_Contains(m_LOpen, tempGrid)) { // 更新与开始节点的距离 tempGrid.gCost = newCost; // 更新与终点的距离 tempGrid.hCost = UF_GetDistanceNodes(tempGrid, endNode); // 更新父节点为当前选定的节点 tempGrid.parent = curNode; // 如果节点是新加入的,将它加入打开列表中 if (!UF_Contains(m_LOpen, tempGrid)) { m_LOpen.Add(tempGrid); } } } } return; }