A*算法

//把起点放到开启列表
/*while(打开列表>0)
{
 *得到当前位置周围f值最小的点,加入到开启列表;
 *把当前点加入到关闭列表
 *寻找出他周围可以走的位置,放到一个集合M里面
 while(M里面是否有存在在开启列表里面的)
  {
   *计算出新的路径值G;
   *if(新的路径更短)//新的路径就是经过当前位置的路径
      {
        把他的父亲设置为当前位置
      }
     else//什么也不做,哪怕是选中它了,那也无所谓,就忽略吊当前位置了
     {
 
     }
       
  }
  else //没有
   {
   * 让他的父亲是当前物体
   * 重新计算F,G、
   * 加入到开启列表
   }
}*/

方块信息类

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

public class Point {
    public Point Parent { get; set; }//地图信息
    public float F { get; set; }
    public float G { get; set; }
    public float H { get; set; }
    public int X { get; set; }
    public int Y { get; set; }
    public bool IsWall { get; set; }
    public Point(int x,int y,Point parent=null)
    {
        this.X = x;
        this.Y = y;
        this.Parent = parent;
        IsWall = false;
    }
    public void UpdateParent(Point parent,float g)
    {
        this.Parent = parent;
        this.G = g;
        F = G + H;
    }

}
主代码:

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

public class astart : MonoBehaviour {

    private Point[,] map = new Point[8, 6];
    private int mapWith = 8;//宽度
    private int mapHeight = 6;//地图高度

	void Start () {
        InitMap();//初始化地图
        Point start = map[2, 3];//开始位置
        Point end = map[6,3];//结束位置
        FindPath(start, end);//寻找路径
        ShowPath(start,end);
	}
	
	// Update is called once per frame
	void Update () {
		
	}
    private void InitMap()//构造地图
    {
        for(int x=0;x<mapWith;x++)
        {
            for(int y=0;y<mapHeight;y++)
            {
                map[x, y] = new Point(x, y);
            }
        }
        map[4, 2].IsWall = true;//是障碍物
        map[4, 3].IsWall = true;
        map[4, 4].IsWall = true;
    }
    private void ShowPath(Point start, Point end)
    {
        Point temp = end;
        while (true)
        {
            Debug.Log(temp.X + "," + temp.Y);
            Color c = Color.gray;
            if(temp==start)
            {
                c = Color.green;
            }else if(temp==end)
            {
                c = Color.red;
            }
            CreateCube(temp.X, temp.Y, c);

            if (temp.Parent == null)
            {
                break;
            }
            else
            {
                temp = temp.Parent;
            }
            for (int x = 0; x < mapWith; x++)
            {
                for (int y = 0; y < mapHeight; y++)
                {
                    if(map[x,y].IsWall)
                    {
                        CreateCube(x, y, Color.blue);
                    }
                }
            }
        }
    }
    private void FindPath(Point Start,Point End)
    {
        List<Point> openList = new List<Point>();//开启集合
        List<Point> closeList = new List<Point>();//关闭集合
        openList.Add(Start);//先把开始点加入开启集合
        while(openList.Count>0)//知道为空结束循环
        {
            Point point = FindMinfPoint(openList);//取得f最小的点了
            openList.Remove(point);//把这个点在开启集合移除
            closeList.Add(point);//增加到关闭集合
            List<Point> surround = GetSurroundPoints(point);//得到周围的集合
            PointsFlter(surround,closeList);//过滤集合
            foreach(Point surroundPoint in surround)
            {
                if(openList.IndexOf(surroundPoint)>-1)//如果存在
                {
                    float nowG = CalcG(surroundPoint,point);//计算出新的G值
                    if(nowG<surroundPoint.G)//如果路径更短,就换掉他的父亲
                    {
                        surroundPoint.UpdateParent(point, nowG);
                    }
                }
                else
                {
                    surroundPoint.Parent = point;
                    CalcF(surroundPoint, End);
                    openList.Add(surroundPoint);
                }
            }
            if(openList.IndexOf(End)>-1)//如果目标在开启列表里面说明找到了
            {
                break;
            }
        }
    }
    private void PointsFlter(List<Point> scr,List<Point> close)//过滤集合
    {
        foreach(Point p in close)
        {
            if(scr.IndexOf(p)>-1)
            {
                scr.Remove(p);
            }
        }
    }
    private Point FindMinfPoint(List<Point> openList)//寻找最小的f值
    {
        float f = float.MaxValue;//先让他是最大值
        Point temp=null;
        foreach(Point p in openList)
        {
            if(p.F<f)
            {
                temp = p;//保存找打的位置和他的f值
                f = p.F;
            }

        }
            return temp;
    }
    private List<Point> GetSurroundPoints(Point point)//寻找周围的点
    {
        Point up = null, down = null, left = null, right = null;//存储当前方块上下左右的方块
        Point lu = null, ru = null, ld = null, rd = null;
        if (point.Y<mapHeight - 1)//说明方块不是在最上面
        {
            up = map[point.X, point.Y + 1];//得到上面的方块
        }
        if(point.Y>0)//说名方块不是在最下面
        {
            down = map[point.X, point.Y - 1];//得到下面的方块
        }
        if(point.X>0)
        {
            left = map[point.X -1, point.Y];//得到最左边的
        }
        if(point.X<mapWith-1)
        {
            right = map[point.X + 1, point.Y];//得到最右边的
        }
        if(up!=null&&left!=null)//如果上面和左面的不为空,则左上不为空
        {
            lu = map[point.X - 1, point.Y - 1];//左上
        }
        if(up!=null&&right!=null)
        {
            ru=map[point.X-1,point.Y+1];//右上
        }
        if (down != null && left != null)//如果上面和左面的不为空,则左上不为空
        {
            ld = map[point.X + 1, point.Y - 1];//
        }
        if (down != null && right != null)
        {
            rd = map[point.X + 1, point.Y + 1];//右下
        }
        List<Point> list = new List<Point>();//添加到list集合里面
        if(down!=null&&down.IsWall==false)
        {
            list.Add(down);
        }
        if (up!= null && up.IsWall == false)
        {
            list.Add(up);
        }
        if (left != null && left.IsWall == false)
        {
            list.Add(left);
        }
        if (right != null && right.IsWall == false)
        {
            list.Add(right);
        }
        if(lu!=null&&lu.IsWall==false&&left.IsWall==false&&up.IsWall==false)
        {
            list.Add(lu);
        }
        if (ld != null && ld.IsWall == false && left.IsWall == false && down.IsWall == false)
        {
            list.Add(ld);
        }
        if (ru != null && ru.IsWall == false && right.IsWall == false && up.IsWall == false)
        {
            list.Add(ru);
        }
        if (rd != null && rd.IsWall == false && right.IsWall == false && down.IsWall == false)
        {
            list.Add(rd);
        }
        return list;
    }
    private float CalcG(Point now,Point parent)//计算G值
    {
       return Vector2.Distance(new Vector2(now.X, now.Y), new Vector2(parent.X,parent.Y)) + parent.G;//
    }
    private void CalcF(Point now, Point end)//计算F=G+H
    {
        float h = Mathf.Abs(end.X - now.X) + Mathf.Abs(end.Y - now.Y);
        float g = 0;
        if (now.Parent == null)
        {
            g = 0;
        }
        else
        {
            //他到父亲的距离加上父亲到开始点的距离
            g = Vector2.Distance(new Vector2(now.X, now.Y), new Vector2(now.Parent.X, now.Parent.Y)) + now.Parent.G;//
        }
        float f = g + h;
        now.F = f;
        now.G = g;
        now.H = h;
    }
    private void CreateCube(int x,int y,Color color)
    {
        GameObject go = GameObject.CreatePrimitive(PrimitiveType.Cube);
        go.transform.position = new Vector3(x, y, 0);
        go.GetComponent<Renderer>().material.color = color;
    }
}



  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Zero游戏开发

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值