-
using System;
-
using
System.Collections.Generic;
-
using System.Linq;
-
-
namespace
Jls.Lib.AStar
-
{
-
publicclass
AStarClassic
-
{
-
publicconstint OBLIQUE = 14;
-
publicconstint STEP = 10;
-
publicint[][]
MapData { get; privateset; }
-
public List<AStarNode> CloseList;
-
public List<AStarNode> OpenList;
-
-
private List<List<AStarNode>> _nodes =
new List<List<AStarNode>>();
-
-
privateint
maxMapX;
-
privateint
maxMapY;
-
-
publicint
CurrentSerialNumber = 0;
-
-
public AStarClassic(int[][] mapData)
-
{
-
MapData
= mapData;
-
maxMapX
= mapData[0].Length - 1;
-
maxMapY
= mapData.Length - 1;
-
var
length = mapData.Length * mapData[0].Length;
-
OpenList
= new List<AStarNode>(length);
-
CloseList
= new List<AStarNode>(length);
-
for (var i = 0; i < mapData.Length; i++)
-
{
-
var
row = new List<AStarNode>();
-
for (var j = 0; j < mapData[0].Length; j++)
-
{
-
var
node = new AStarNode(j, i);
-
node.Walkable
= mapData[i][j] == 1;
-
row.Add(node);
-
}
-
_nodes.Add(row);
-
}
-
-
}
-
-
/// <summary>
-
/// 寻路
-
/// </summary>
-
/// <param
name="startNode"></param>
-
/// <param
name="endNode"></param>
-
/// <param
name="isIgnoreCorner"></param>
-
///
<returns></returns>
-
public AStarNode FindPath(AStarNode startNode,
AStarNode endNode, bool isIgnoreCorner)
-
{
-
startNode
= GetPoint(startNode.X, startNode.Y);
-
endNode
= GetPoint(endNode.X, endNode.Y);
-
//if (!endNode.Walkable)
-
//{
-
// endNode = GetWalkableEndNode(startNode,
endNode);
-
//}
-
OpenList.Add(startNode);
-
startNode.IsClose
= true;
-
while (OpenList.Count != 0)
-
{
-
var
currentPoint = GetLowestFScore();
-
-
AddCloseList(currentPoint);
-
currentPoint.IsClose
= true;
-
RemoveOpenList(currentPoint);
-
-
if (endNode.IsClose )
-
{
-
break;
-
}
-
-
var
adjacentPoints = getArounds(currentPoint, isIgnoreCorner);
-
-
foreach (AStarNode aPoint in
adjacentPoints)
-
{
-
if (aPoint.IsClose )
-
{
-
continue;
-
}
-
if (! aPoint.IsOpen )
-
{
-
aPoint.CalcG(currentPoint);
-
aPoint.CalcH(endNode);
-
aPoint.CalcF();
-
aPoint.Parent
= currentPoint;
-
aPoint.IsOpen
= true;
-
AddOpenList(aPoint);
-
}
-
else
-
{
-
//var aPointInOpen =
OpenList.GetNode(aPoint);
-
var
aPointInOpen = aPoint;
-
aPointInOpen.Count++;//
-
-
var
newG = aPointInOpen.CalcNewG(currentPoint);
-
-
if (newG < aPointInOpen.G)
-
{
-
aPointInOpen.G
= newG;
-
aPointInOpen.CalcF();
-
aPointInOpen.Parent
= currentPoint;
-
}
-
}
-
}
-
}
-
-
return GetEndPointInCloseList(endNode);
-
-
}
-
-
/// <summary>
-
/// 如果结束结点不可用,查找结束节点离开始节点最近的可用节点
-
/// </summary>
-
/// <param name="startNode">
</param>
-
/// <param
name="endNode"></param>
-
///
<returns></returns>
-
private AStarNode GetWalkableEndNode(AStarNode
startNode, AStarNode endNode)
-
{
-
if (endNode.Walkable) return endNode;
-
-
//1.找出周围有可用点的方形圈
-
var
aroundCount = 1;
-
var
foudedNodes = new List<AStarNode>();
-
while (true)
-
{
-
//上下两行
-
for (var i = -aroundCount; i <= aroundCount;
i++)
-
{
-
var
node = GetPoint(endNode.X + i, endNode.Y - aroundCount);
-
if (node != null
&& node.Walkable)
-
{
-
foudedNodes.Add(node);
-
}
-
node
= GetPoint(endNode.X + i, endNode.Y + aroundCount);
-
if (node != null
&& node.Walkable)
-
{
-
foudedNodes.Add(node);
-
}
-
}
-
-
//左右两列
-
for (var i = -aroundCount + 1; i < aroundCount;
i++)
-
{
-
var
node = GetPoint(endNode.X - aroundCount, endNode.Y + i);
-
if (node != null
&& node.Walkable)
-
{
-
foudedNodes.Add(node);
-
}
-
node
= GetPoint(endNode.X + aroundCount, endNode.Y + i);
-
if (node != null
&& node.Walkable)
-
{
-
foudedNodes.Add(node);
-
}
-
}
-
-
if (foudedNodes.Count > 0)
-
{
-
break;
-
}
-
else
-
{
-
aroundCount
+= 1;
-
-
}
-
}
-
//2.没找到,说明没有可用点
-
if (foudedNodes.Count == 0) returnnull;
-
-
//找出该圈中离开始点最近的点
-
var
foundIncex = 0;
-
var
shortDistance = GetDistance(startNode, foudedNodes[0]);
-
for (var i = 0; i < foudedNodes.Count; i++)
-
{
-
var
node = foudedNodes[i];
-
var
distance = GetDistance(startNode, node);
-
if (distance < shortDistance)
-
{
-
shortDistance
= distance;
-
foundIncex
= i;
-
}
-
-
}
-
return foudedNodes[foundIncex];
-
}
-
-
/// <summary>
-
/// 计算两点直线距离
-
/// </summary>
-
/// <param
name="startNode"></param>
-
/// <param
name="endNode"></param>
-
///
<returns></returns>
-
privatedouble
GetDistance(AStarNode startNode, AStarNode endNode)
-
{
-
return Math.Sqrt((endNode.X - startNode.X) *
(endNode.X - startNode.X) +
-
(endNode.Y
- startNode.Y) * (endNode.Y - startNode.Y));
-
}
-
-
private AStarNode GetPoint(int
x, int y)
-
{
-
return !ValidPoint(x, y) ? null
: _nodes[y][x];
-
}
-
-
/// <summary>
-
/// 查找开放节点中最低H值的节点
-
/// </summary>
-
///
<returns></returns>
-
private AStarNode GetLowestFScore()
-
{
-
return OpenList.OrderBy(t =>
t.F).FirstOrDefault();
-
}
-
-
/// <summary>
-
/// 节点加入关闭列表
-
/// </summary>
-
/// <param
name="aNode"></param>
-
privatevoid
AddCloseList(AStarNode aNode)
-
{
-
CloseList.Add(aNode);
-
}
-
-
/// <summary>
-
/// 从开放节点中移去节点
-
/// </summary>
-
/// <param
name="aNode"></param>
-
privatevoid
RemoveOpenList(AStarNode aNode)
-
{
-
OpenList.Remove(aNode);
-
}
-
-
/// <summary>
-
/// 结束点在关闭结点,说明已找到,完成
-
/// </summary>
-
/// <param
name="endNode"></param>
-
///
<returns></returns>
-
privatebool
IsEndInCloseList(AStarNode endNode)
-
{
-
//return
CloseList.Exists(endNode);
-
return CloseList.Contains(endNode);
-
-
}
-
-
/// <summary>
-
/// 获取当前点的周边有效点
-
/// </summary>
-
/// <param
name="currentNode"></param>
-
/// <param
name="isIgnoreCorner">能否穿墙角</param>
-
///
<returns></returns>
-
private List<AStarNode> getArounds(AStarNode
currentNode, bool isIgnoreCorner)
-
{
-
var
arounds = new List<AStarNode>();
-
-
for (int x =
currentNode.X - 1; x <= currentNode.X + 1; x++)
-
for (int y =
currentNode.Y - 1; y <= currentNode.Y + 1; y++)
-
{
-
if (!(x == currentNode.X && y ==
currentNode.Y))
-
{
-
if (x < 0 || x > maxMapX || y < 0 || y
> maxMapY) continue;
-
var
aPoint = _nodes[y][x];
-
if (CanReachTo(currentNode, aPoint,
isIgnoreCorner))
-
{
-
arounds.Add(aPoint);
-
}
-
}
-
}
-
return arounds;
-
-
}
-
-
/// <summary>
-
/// 判断斜线方向能否到达
-
/// </summary>
-
/// <param
name="currentNode"></param>
-
/// <param
name="aNode"></param>
-
/// <param
name="isIgnoreCorner">是否允许穿墙</param>
-
///
<returns></returns>
-
privatebool
CanReachTo(AStarNode currentNode, AStarNode aNode, bool isIgnoreCorner)
-
{
-
if (!ValidPoint(aNode.X, aNode.Y)) returnfalse;
-
if (!aNode.Walkable) returnfalse;
-
if (Math.Abs(aNode.X - currentNode.X) +
Math.Abs(aNode.Y - currentNode.Y) == 1) returntrue;
//横竖方向
-
//如果是斜方向移动, 判断是否 "拌脚"
-
var
leftPoint = GetPoint(currentNode.X, aNode.Y);
-
var
rightPoint = GetPoint(aNode.X, currentNode.Y);
-
if (leftPoint.Walkable &&
rightPoint.Walkable) //无墙角
-
{
-
returntrue;
-
}
-
elseif
(leftPoint.Walkable || leftPoint.Walkable) //有一个
-
{
-
return isIgnoreCorner; //有墙角
-
}
-
else
-
{
-
returnfalse;
-
}
-
-
}
-
-
/// <summary>
-
/// 是不是有效的点
-
/// </summary>
-
/// <param
name="node"></param>
-
///
<returns></returns>
-
privatebool
ValidPoint(int x, int y)
-
{
-
if (x < 0 || x > maxMapX || y < 0 || y
> maxMapY) returnfalse;
-
returntrue;
-
}
-
-
/// <summary>
-
/// 关闭列表中是否存在该点
-
/// </summary>
-
/// <param
name="aNode"></param>
-
///
<returns></returns>
-
privatebool
IsInCloseList(AStarNode aNode)
-
{
-
//return
CloseList.Exists(aNode);
-
//return
CloseList.Contains(aNode);
-
return CloseList.IndexOf(aNode) != -1;
-
-
}
-
-
/// <summary>
-
/// 开放列表中是否存在该点
-
/// </summary>
-
/// <param
name="aNode"></param>
-
///
<returns></returns>
-
privatebool
IsInOpenList(AStarNode aNode)
-
{
-
//return
OpenList.Exists(aNode);
-
return OpenList.Contains(aNode);
-
}
-
-
/// <summary>
-
/// 加入开放列表
-
/// </summary>
-
/// <param
name="aNode"></param>
-
privatevoid
AddOpenList(AStarNode aNode)
-
{
-
aNode.SerialNumber
= CurrentSerialNumber++;
-
-
OpenList.Add(aNode);
-
}
-
-
/// <summary>
-
///
如果endPoint在关闭列表中,则返回它,否则返回null
-
/// </summary>
-
/// <param
name="endNode"></param>
-
///
<returns></returns>
-
private AStarNode GetEndPointInCloseList(AStarNode
endNode)
-
{
-
if (CloseList.IndexOf(endNode) != -1)
-
{
-
return CloseList[CloseList.IndexOf(endNode)];
-
}
-
else
-
{
-
returnnull;
-
}
-
}
-
}
-
-
-
-
-
}
1.https://sites.google.com/a/chromium.org/dev/developers/how-tos/install-depot-tools
5.下载安装SDK7.1 win7_GRMSDKX_EN_DVD,带X的是64位的。报错,把原来已经安装的visual studio 2010
Redistributable x86/x64都卸载了,就可以安装了,再安装补丁VC-Compiler-KB2519277.exe
6.安装Directx SDK 安装DirectXSDK时提示Error Code s1023,Microsoft Visual C++ 2010
x86/x64 Redistributable 的版本大于10.0.30319
就会提示失败!将这个卸载掉就可以安装成功!!(中间有可能需重启),安装完后,再装VC-Compiler-KB2519277.exe
gclient sync --force 运行最后, 会去下载win8 SDK.