A*(A星)寻路算法

首先非常感谢唐老师的课程,讲的非常好
添加链接描述

  • 三个变量:

    G值 = 父节点的G值 + 父节点到当前点的移动代价
    (父节点的G是0,如果斜着走就是根号2,直着走就是1)

    H值 = 当前点到结束点的曼哈顿距离

    寻路消耗公式 F:=G+H

  • 还有两个列表
    开放列表: 吧当前所有可以走的节点都放进开放列表
    关闭列表:每一次走过一个节点之后都把这个节点放到关闭列表里面

  • 具体步骤
    a、将开始点记录为当前点P
    b、将当前点P放入关闭列表
    c、搜寻点P所有邻近点,假如某邻近点既没有在开放列表或关闭列表里面,则计算出该邻近点的F值,并设父节点为P,然后将其放入开放列表
    d、判断开放列表是否已经空了,如果没有说明在达到结束点前已经找完了所有可能的路径点,寻路失败,算法结束;否则继续。
    e、从开放列表拿出一个F值最小的点,作为寻路路径的下一步。
    f、判断该点是否为结束点,如果是,则寻路成功,算法结束;否则继续。
    g、将该点设为当前点P,跳回步骤c。

  • 找出路径
    从终点节点开始,找其父节点,顺藤摸瓜,一直找到起始节点,这便是一条路径

总结:

  • A*并不是最短路,他是以最快的速度找到通往目标的路径
  • A*在死路情况下会找遍所有点

一下跟着写的代码,一个小demon:、

优化的地方:

  • 本demon是用的list存储,list很多操作个比较耗,可以用红黑树(堆)来优化排序过程
  • 判断是不是在开放或者关闭列表中,list会遍历所有,我们可以在节点里加一个属性做标记

格子类:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class AStarNode
{
   
    //格子对象坐标
    public int x;
    public int y;

    //寻路消耗
    public float f;
    //距离起点距离
    public float g;
    //距离终点的距离
    public float h;
    //父对象
    public AStarNode fataher;
    //格子类型
    public ENodeType type;

    //构造函数,传入格子坐标和格子类型
    public AStarNode(int x,int y,ENodeType type)
    {
   
        this.x = x;
        this.y = y;
        this.type = type;
    }
}

/// <summary>
/// 格子类型
/// </summary>
public enum ENodeType
{
   
    Walk,
    Stop,
}

管理类:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class AStartMgr
{
   
    #region 构造单例模式
    private AStartMgr() {
    }
    public static AStartMgr Instance
    {
   
        get
        {
   
            return Nested._instance;
        }
    }
    private class Nested
    {
   
        internal static readonly AStartMgr _instance = new AStartMgr();
    }
    #endregion

    //地图相关所有格子的对象容器
    private AStarNode[,] nodes;
    public AStarNode[,] Nodes
    {
   
        get {
    return nodes; }
    }
    //开启列表
    private List<AStarNode> openList=new List<AStarNode>();
    //关闭列表
    private List<AStarNode> closeList = new List<AStarNode>();
    //地图的宽高
    private int mapW;
    private int mapH;

    /// <summary>
    /// 初始化地图信息
    /// </summary>
    /// <param name="w"></param>
    /// <param name="h"></param>
    public void InitMapInfo(int w,int h)
    {
   
        this.mapW = w;
        this.mapH = h;
        nodes = new AStarNode[w, h];
        for(int i = 0; i < w; i++
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值