最短路径

将地图存成二维数组,通过行列查找;

每一步都查找周围四个方向,或者八方向的所有点,放入开表;

  • 是否边缘
  • 是否障碍
  • 是否已经在确定的路线中

计算每个方向上路径消耗,一般斜着走消耗小,收益大;

开表排序,筛选出最小消耗的点放入闭表,并将该点设置为新的起点,从开表中去除该点;

重复上面操作,直到起点=终点退出;

中间查找八个方向可移动点位时,需要将这些可移动点的父节点设置为起点,这样可通过最后筛选出的点,一层层找出最短路径;

x步内可移动所有点位

将所有方向上可以移动的节点放入开表,同时放入闭表;

遍历闭表,将每个节点周围可移动的节点放入开表,同时放入新表;

清空闭表,新表赋值给闭表(实际代码不这么写);

重复上面操作,可移动几步,就循环几次;

最终返回开表;

代码实现:

public enum ObsType
{
None,
Wall,
Water,
Cliff
} public class AStarNode
{
public ObsType type;
public int x;
public int y;
public float g;
public float h;
public float f;
public AStarNode father;
public AStarNode(int _x,int _y,ObsType _type)
{
type = _type;
x = _x;
y = _y;
}
} [Serializable]
public class GridPos
{
public GridPos(int col, int row)
{
Col = col;
Row = row;
}
public int Col;
public int Row;
} public class AStarMgr
{
//地图的宽高
private int mapRow;
private int mapCol;
//地图相关的所有的格子容器
public AStarNode[,] nodes;
//开启列表
private List<AStarNode> openList = new List<AStarNode>();
//关闭列表
private List<AStarNode> closeList = new List<AStarNode>(); //初始化地图信息
public void InItMapInfo(int col, int row)
{
this.mapCol = col;
this.mapRow = row; nodes = new AStarNode[col, row];
for (int i = 0; i < col; i++)
{
for (int j = 0; j < row; j++)
{
AStarNode node = new AStarNode(i, j,
Random.Range(0, 100) < 20 ? ObsType.Wall : Ob
nodes[i, j] = node;
}
}
} //寻路的方法
public List<AStarNode> FindPath(GridPos startPos, GridPos end
{
//判断起始点是不是在地图的范围内
if (startPos.Col < 0 || startPos.Col >= mapCol
|| startPos.Row < 0 || startPos.Row
|| endPos.Col < 0 || endPos.Col >= m
|| endPos.Row < 0 || endPos.Row >= m
)
return null;
//判断起始点是不是不能通行的点
AStarNode start = nodes[startPos.Col, startPos.Row];
AStarNode end = nodes[endPos.Col, endPos.Row];
if (start.type != ObsType.None || end.type != ObsType.Non
return null;
closeList.Clear();
openList.Clear();
//开始点放入关闭列表中
start.father = null;
start.f = 0;
start.g = 0;
start.h = 0;
closeList.Add(start);
while (true)
{
//周围的点
//FindNearlyToOpenList(start.x - 1, start.y - 1, 1.4f
FindNearlyToOpenList(start.x, start.y - 1, 1.4f, star
//FindNearlyToOpenList(start.x + 1, start.y - 1, 1.4f
FindNearlyToOpenList(start.x - 1, start.y, 1.4f, star
FindNearlyToOpenList(start.x + 1, start.y, 1.4f, star
//FindNearlyToOpenList(start.x - 1, start.y + 1, 1.4f
FindNearlyToOpenList(start.x, start.y + 1, 1.4f, star
//FindNearlyToOpenList(start.x + 1, start.y + 1, 1.4f
if (openList.Count == 0)
return null;
//排序选出最小的点
openList.Sort(SortOpenList);
//放入关闭列表,然后从开启列表中移除
closeList.Add(openList[0]);
//找到这个点,进行下一次寻路
start = openList[0];
openList.RemoveAt(0);
if (start == end)
{
//结束
List<AStarNode> path = new List<AStarNode>();
path.Add(end);
while (end.father != null)
{
path.Add(end.father);
end = end.father;
}
path.Reverse();
return path;
}
}
}
//找出周围几步之内可到达的格子
public List<AStarNode> FindRange(GridPos startPos, int step)
{
if (startPos.Col < 0 || startPos.Col >= mapCol
|| startPos.Row < 0 || startPos.Row
return null;
AStarNode start = nodes[startPos.Col, startPos.Row];
if (start.type != ObsType.None)
return null;
closeList.Clear();
openList.Clear();
closeList.Add(start);
while (step-- > 0)
{
AddNearOneStep(closeList.ToArray());
}
return openList;
} //排序函数
private int SortOpenList(AStarNode a, AStarNode b)
{
if (a.f > b.f)
return 1;
else if (a.f == b.f)
return 1;
else
return -1;
} //临近的点放入开启列表
private void FindNearlyToOpenList(int x, int y, float g, ASta
{
if (x < 0 || x >= mapCol || y < 0 || y >= mapRow)
return;
AStarNode node = nodes[x, y];
if (node == null || node.type != ObsType.None
|| closeList.Contains(node)
|| openList.Contains(node)
)
return;
//计算f值 f=g+h;
node.father = father;
node.g = father.g + g;
node.h = Mathf.Abs(end.x - node.x) + Mathf.Abs(end.y - no
node.f = node.g + node.h;
openList.Add(node);
}
//当前步数的所有Node放入open
private void AddNearOneStep(AStarNode[] curStepNodes)
{
closeList.Clear();
foreach (var it in curStepNodes)
{
AddNearNode(it.x - 1, it.y);
AddNearNode(it.x, it.y - 1);
AddNearNode(it.x + 1, it.y);
AddNearNode(it.x, it.y + 1);
}
} //单个格子周围的点加入open
private void AddNearNode(int x, int y)
{
if (x < 0 || x >= mapCol || y < 0 || y >= mapRow)
return;
AStarNode node = nodes[x, y];
if (node == null || node.type != ObsType.None)
return;
openList.Add(node);
closeList.Add(node);
}
}

Unity-A-Star寻路算法的更多相关文章

  1. Unity实现A*寻路算法学习1.0

    一.A*寻路算法的原理 如果现在地图上存在两点A.B,这里设A为起点,B为目标点(终点) 这里为每一个地图节点定义了三个值 gCost:距离起点的Cost(距离) hCost:距离目标点的Cost(距 ...

  2. Unity实现A*寻路算法学习2.0

    二叉树存储路径节点 1.0中虽然实现了寻路的算法,但是使用List<>来保存节点性能并不够强 寻路算法学习1.0在这里:https://www.cnblogs.com/AlphaIcaru ...

  3. A星寻路算法入门(Unity实现)

    最近简单学习了一下A星寻路算法,来记录一下.还是个萌新,如果写的不好,请谅解.Unity版本:2018.3.2f1 A星寻路算法是什么 游戏开发中往往有这样的需求,让玩家控制的角色自动寻路到目标地点, ...

  4. 基于Unity的A星寻路算法(绝对简单完整版本)

    前言 在上一篇文章,介绍了网格地图的实现方式,基于该文章,我们来实现一个A星寻路的算法,最终实现的效果为: 项目源码已上传Github:AStarNavigate 在阅读本篇文章,如果你对于里面提到的 ...

  5. A*(也叫A star, A星)寻路算法Java版

    寻路算法有非常多种,A*寻路算法被公觉得最好的寻路算法. 首先要理解什么是A*寻路算法,能够參考这三篇文章: http://www.gamedev.net/page/resources/_/techn ...

  6. 算法:Astar寻路算法改进

    早前写了一篇<RCP:gef智能寻路算法(A star)> 出现了一点问题. 在AStar算法中,默认寻路起点和终点都是N x N的方格,但如果用在路由上,就会出现问题. 如果,需要连线的 ...

  7. 无递归 A星寻路算法

    整理硬盘的时候,发现我早些年写的A星寻路算法.特放上来,待有缘人拿去,无递归噢,性能那是杠杠的. 码上伺候 public class Node { public int X { get; set; } ...

  8. JS算法之A*(A星)寻路算法

    今天写一个连连看的游戏的时候,接触到了一些寻路算法,我就大概讲讲其中的A*算法. 这个是我学习后的一点个人理解,有错误欢迎各位看官指正. 寻路模式主要有三种:广度游戏搜索.深度优先搜索和启发式搜索. ...

  9. 一种高效的寻路算法 - B*寻路算法

    在此把这个算法称作B* 寻路算法(Branch Star 分支寻路算法,且与A*对应),本算法适用于游戏中怪物的自动寻路,其效率远远超过A*算法,经过测试,效率是普通A*算法的几十上百倍. 通过引入该 ...

  10. 数据结构和算法总结(三):A* 寻路算法

    前言 复习下寻路相关的东西,而且A star寻路在游戏开发中应用挺多的,故记录下. 正文 迪杰斯特拉算法 说起A*得先谈谈Dijkstra算法,它是在BFS基础上的一种带权值的两点最短寻路贪心算法. ...

随机推荐

  1. Java实现平滑加权轮询算法--降权和提权

    上一篇讲了普通轮询.加权轮询的两种实现方式,重点讲了平滑加权轮询算法,并在文末留下了悬念:节点出现分配失败时降低有效权重值:成功时提高有效权重值(但不能大于weight值). 本文在平滑加权轮询算法的 ...

  2. python相关知识理解

    Python3 基础了解 编码  Python 3 源码文件以 UTF-8 编码,所有字符串都是 unicode 字符串   # -*- coding: cp-1252 -*- 标识符 · 第一个字符 ...

  3. CentOS8 AnolisOS8 yum安装 No match for argument: htop Error: Unable to find a match: htop

    这里写自定义目录标题 CentOS8 AnolisOS8 yum安装失败 安装失败原因 阿里云官方镜像主页 正确的操作步骤 学习交流 My Blog 技术交流 CentOS8 AnolisOS8 yu ...

  4. 动态SQL常用标签

    动态 SQL 目的:为了摆脱在不同条件拼接 SQL 语句的痛苦 在不同条件在生成不同的SQL语句 本质上仍然是SQL语句,不过是多了逻辑代码去拼接SQL,只要保证SQL的正确性按照格式去排列组合 可以 ...

  5. 网络协议OSI模型-TCP/IP-三次握手

    OSI模型 在制定计算机网络标准方面,起着重大作用的两大国际组织是:国际电信联盟电信标准化部门,与国际 标准组织(ISO),虽然它们工作领域不同,但随着科学技术的发展,通信与信息处理之间的界限开始 变 ...

  6. Apache Kafka 集群部署指南

    公众号关注 「开源Linux」 回复「学习」,有我为您特别筛选的学习资料~ Kafka基础 消息系统的作用 应该大部分小伙伴都清楚,用机油装箱举个例子. 所以消息系统就是如上图我们所说的仓库,能在中间 ...

  7. vue - Vue组件化编程

    今天是对vue组件化的一个理解,最主要的单文件组件,然后就可以脚手架的学习了,本来昨晚就该上传的,但是用的那个上传博客园的Python脚本不行了,换了一个新的. 组件化让我越来越感觉到框架的力量了 一 ...

  8. mapboxgl 中插值表达式的应用场景

    目录 一.前言 二.语法 三.对地图颜色进行拉伸渲染 1. 热力图 2. 轨迹图 2. 模型网格渲染 四.随着地图缩放对图形属性进行插值 五.interpolate的高阶用法 六.总结 一.前言 in ...

  9. URL 是什么?

    URL 是什么? 本文写于 2020 年 5 月 16 日 URL 是什么?天天听到人家说到这个名词,那它到底是什么? URL 是统一资源定位符,Uniform Resource Locator. 俗 ...

  10. 羽夏 Bash 简明教程(下)

    写在前面   该文章根据 the unix workbench 中的 Bash Programming 进行汉化处理并作出自己的整理,并参考 Bash 脚本教程 和 BashPitfalls 相关内容 ...