- //定义格子的枚举类型
- public enum GridType
- {
- Normal, Obstacle, Start, End
- }
- 定义格子类
- public class Grid : IComparable
- {
- public int x;
- public int y;
- public int f;//总消耗 G+H
- public int g;//到起点消耗
- public int h;//到终点消耗
- public GridType type;
- public Grid fatherNode;
- //重写CompareTo 方法,用于取出F值最小的格子
- public int CompareTo(object obj)
- {
- Grid grid = (Grid)obj;
- if (this.f < grid.f)
- {
- return -1;
- }
- if (this.f > grid.f)
- {
- return 1;
- }
- return 0;
- }
- }
- public class AStar : MonoBehaviour
- {
- //设置行列数和格子大小
- public int row = 5;
- public int col = 10;
- public int size = 70;
- public Grid[,] grids;
- //开数组,闭数组,和寻路路径
- public ArrayList openList;
- public ArrayList closeList;
- public ArrayList lujing;
- //假定起点和终点X,Y值
- private int xStart = 2;
- private int yStart = 1;
- private int xEnd = 2;
- private int yEnd = 5;
- //初始化寻路格子
- void Init()
- {
- grids = new Grid[row, col];
- for (int i = 0; i < row; i++)
- {
- for (int j = 0; j < col; j++)
- {
- grids[i, j] = new Grid();
- grids[i, j].x = i;
- grids[i, j].y = j;
- }
- }
- //起始点
- grids[xStart, yStart].type = GridType.Start;
- grids[xStart, yStart].h = Manhattan(xStart, yStart);
- //结束点
- grids[xEnd, yEnd].type = GridType.End;
- //设置障碍物
- for (int i = 1; i <= 3; i++)
- {
- grids[i, 3].type = GridType.Obstacle;
- }
- closeList = new ArrayList();
- lujing = new ArrayList();
- openList = new ArrayList();
- openList.Add(grids[xStart, yStart]);
- }
- int Manhattan(int x, int y) //用于计算到终点的H
- {
- return (int)(Mathf.Abs(xEnd - x) + Mathf.Abs(yEnd - y)) * 10;
- }
- void Start()
- {
- Init();
- }
- void Update()
- {
- }
- //绘制格子便于观察
- void DrawGrid()
- {
- for (int i = 0; i < row; i++)
- {
- for (int j = 0; j < col; j++)
- {
- Color color;
- if (grids[i, j].type == GridType.Start)
- {
- color = Color.green;
- }
- else if (grids[i, j].type == GridType.End)
- {
- color = Color.red;
- }
- else if (grids[i, j].type == GridType.Obstacle)
- {
- color = Color.blue;
- }
- else if (closeList.Contains(grids[i, j]))
- {
- color = Color.yellow;
- }
- else
- {
- color = Color.gray;
- }
- GUI.backgroundColor = color;
- GUI.Button(new Rect(j * size, i * size, size, size), FGH(grids[i, j]));
- }
- }
- }
- //显示F G H值
- string FGH(Grid grid)
- {
- string str = "F" + " " + grid.f + "\n";
- str += "G" + " " + grid.g + "\n";
- str += "H" + " " + grid.h + "\n";
- str += "(" + grid.x + "," + grid.y + ")";
- return str;
- }
- void OnGUI()
- {
- DrawGrid();
- //显示出开数组,闭数组和行走路径
- for (int i = 0; i < openList.Count; i++)
- {
- GUI.Button(new Rect(i * size, (row + 1) * size, size, size),FGH((Grid)openList[i]));
- }
- for (int i = 0; i < closeList.Count; i++)
- {
- GUI.Button(new Rect(i * size, (row + 2) * size, size, size),FGH((Grid)closeList[i]));
- }
- for (int i = 0; i < lujing.Count; i++)
- {
- GUI.Button(new Rect(i * size, (row + 3) * size, size, size),FGH((Grid)lujing[i]));
- }
- if (GUI.Button(new Rect(col * size, size, size, size), "NEXT"))
- {
- NextStep();//一步一步走
- }
- }
- //获取每个格子的父节点,用于从终点往回查询路径
- void getFatherNode(Grid grid)
- {
- if (grid.fatherNode != null)
- {
- lujing.Add(grid.fatherNode);
- getFatherNode(grid.fatherNode);
- // return getFatherNode(grid.fatherNode);
- }
- //else
- //lujing.Add(grid);
- //return grid;
- }
- void NextStep()
- {
- //当开数组为空时,寻路结束
- if (openList.Count == 0)
- {
- print("Over!");
- return;
- }
- //把F值最小的grid取出来
- Grid grid = (Grid)openList[0];
- //当寻到终点的时候
- if (grid.type == GridType.End)
- {
- print("Over");
- lujing.Add(grid);
- //打印路线
- getFatherNode(grid);
- //因为路径是从后往前查找父节点,所以需要reverse则为正确路径
- lujing.Reverse();
- return;
- }
- //遍历处自己外的周围8个格子
- for (int i = -1; i <= 1; i++)
- {
- for (int j = -1; j <= 1; j++)
- {
- //如果只想遍历上下左右4个格子可加个条件 (i==0||j==0)
- if (!(i == 0 && j == 0))
- {
- int x = grid.x + i;
- int y = grid.y + j;
- //不超过边界,不是障碍物,不在closeList数组里
- if (x >= 0 && x < row && y >= 0 && y < col && grids[x, y].type != GridType.Obstacle && !closeList.Contains(grids[x, y]))
- {
- //计算G
- int g = grid.g + (int)(Mathf.Sqrt(Mathf.Abs(i) + Mathf.Abs(j)) * 10);
- if (grids[x, y].g == 0 || grids[x, y].g > g)
- {
- grids[x, y].g = g;
- grids[x, y].fatherNode = grid;
- }
- grids[x, y].h = Manhattan(x, y);
- grids[x, y].f = grids[x, y].g + grids[x, y].h;
- if (!openList.Contains(grids[x, y]))
- {
- openList.Add(grids[x, y]);
- }
- //重新从小到大排序;
- openList.Sort();
- }
- }
- }
- }
- //走过的点关闭
- closeList.Add(grid);
- //关闭的点从OPEN里移除
- openList.Remove(grid);
- }