关于A星寻路的一些代码

来源:互联网 发布:零基础学算法可行 编辑:程序博客网 时间:2024/06/16 18:01

好不容易攒出了几个东西写在博客上面,看CSDN上面的大神太多,我还是吧这些博客当成笔记或日记来写吧,想来网站也不会封了我微笑

Unity的东西我感觉到了个瓶颈,有点难提升,官方的文档全英文看不懂,自己感觉还是去做做项目会好一点,等这几天把Shader研究到放弃,笔记博客谢谢好,就要开始大量“抄”项目了,看见什么实现什么。不多说,还是实现A星吧。


A星的思想大家可以百度一下,我这里就简单提一下公式:F=G+H   

F就是我们需要进行排序的值,G是已经过的路程长度(相当于),H是将要走的路程(也是相当于),具体百度,写不出来~害羞


大体的思想就是:一个出发点A和一个终点B,从A开始向四周遍历值F,如果位置合法(不越界,未访问,非障碍)加入到list集合中,把遍历过的点加入visited集合中,在每次遍历list的时候,根据F值进行排序,取最小的F值点,向八个方向遍历,把位置合法的点存入list中,直到list为空。而路径的求法就是在一开始定义点这个类的时候加点思想就可以啦,每个点都有一个父节点,在向八个方向访问的时候赋值,最后取路劲的时候,会把点从后往前推,直到起点A,我这用了一个Stack存储,也可以用list,然后倒一下,都行。然后贴上代码:

注:看懂了地图自己生成吧我这是0是起点,9是终点,1是可行走点,2是障碍物点。大小6*8(看你喜欢)



usingUnityEngine;
usingSystem.Collections.Generic;
usingSystem.IO;
publicclassAStar:MonoBehaviour
{

   byte[,] mapData =newbyte[6, 8];
   Vector2start;
   Vector2end;

   //存放未访问的节点
   List<Node> list =newList<Node>();
   //存放已访问的节点
   List<Node> visited =newList<Node>();
   //路径
   Stack<Vector2> path =newStack<Vector2>();

   Vector2[] dirs =newVector2[] {Vector2.left,Vector2.right,Vector2.up,Vector2.down ,
       newVector2(1, 1),newVector2(-1, 1),newVector2(1, -1),newVector2(-1, -1) };
   GameObjectplayer;
   Vector3moveDir;
   Vector3target;
   publicvoidStart()
    {
        LoadMapData();
        BuildMap();
        BFS();
        player =GameObject.CreatePrimitive(PrimitiveType.Sphere);
        player.transform.position = GetPosition(start);
        target = GetPosition(path.Peek());
    }

   publicvoidUpdate()
    {
        moveDir = (target - player.transform.position).normalized;
        player.transform.Translate(moveDir *Time.deltaTime);
       if(Vector3.Distance(player.transform.position, target) < 0.1f)
        {
            path.Pop();
           if(path.Count == 0)
            {
               this.enabled =false;
            }
           else
            {
                target = GetPosition(path.Peek());
            }
        }
    }

   Vector3GetPosition(Vector2pos)
    {
       floatpos_x = -3 + pos.y;
       floatpos_y = 4 + pos.x;
       returnnewVector3(pos_x, 1, pos_y);
    }
   ///<summary>
   ///获取起始点和终止点
   ///</summary>
   voidGetStartEnd()
    {
       for(inti = 0; i < mapData.GetLength(0); i++)
        {
           for(intj = 0; j < mapData.GetLength(1); j++)
            {
               if(mapData[i, j] == 0)
                {
                    start.x = i;
                    start.y = j;
                }
               elseif(mapData[i, j] == 9)
                {
                    end.x = i;
                    end.y = j;
                }
            }
        }
    }
   ///<summary>
   ///关于Node类的排序规则
   ///</summary>
   ///<param name="x"></param>
   ///<param name="y"></param>
   ///<returns></returns>
   intNodeSort(Nodex,Nodey)
    {
       if(x.F == y.F)
        {
           return0;//表示不交换位置
        }
       elseif(x.F > y.F)
        {
           return1;//表示交换位置
        }
       else
        {
           return-1;//表示不交换位置
        }

    }
   ///<summary>
   ///判断是否合法
   ///</summary>
   ///<param name="point"></param>
   ///<returns></returns>
   boolisOk(Vector2point)
    {

       //越界
       if(point.x < 0 || point.y < 0 || point.x > mapData.GetLength(0) || point.y > mapData.GetLength(1))
        {
           returnfalse;
        }
       //障碍物
       if(mapData[(int)point.x, (int)point.y] == 2)
        {
           returnfalse;
        }
       //已访问
       for(inti = 0; i < visited.Count; i++)
        {
           if(visited[i].X == point.x && visited[i].Y == point.y)
            {
               returnfalse;
            }
        }
       returntrue;

    }
   ///<summary>
   ///A*算法
   ///</summary>
   voidAStar()
    {
        GetStartEnd();
       Noderoot =newNode(start);
        list.Add(root);

       while(list.Count > 0)
        {
            list.Sort(NodeSort);
           //先按F值排序,后取出F值最小的节点
           Nodenode = list[0];
            list.Remove(node);//移除
            visited.Add(node);//添加节点到已访问集合

           for(inti = 0; i < dirs.Length; i++)
            {
               Vector2point;
                point.x = node.X + dirs[i].x;
                point.y = node.Y + dirs[i].y;
               //判断位置是否合法
               if(isOk(point))
                {
                   Noden =newNode(point, node);
                    n.G = i > 3 ? node.G + 14 : node.G + 10;         G += 14 或10(基于方向是正的还是斜的)
                    n.CalcuteH(newNode(end));                ((end.x-n.x + end.y-n.y)*10 )
                    n.CalucuteF();                    F=G+H
                    list.Add(n);
                   if(point == end)
                    {
                       Debug.Log("Find!!");
                       Nodep = n;
                       //逆序输出路径
                       while(p !=null)
                        {
                            path.Push(newVector2(p.X, p.Y));
                            p = p.Parent;
                        }
                       return;
                    }
                }
            }
        }
    }
   ///<summary>
   ///给mapData赋值
   ///</summary>
   voidLoadMapData()
    {
       stringpath =Application.dataPath +"/Map/Map2.txt";
       StreamReadersr =newStreamReader(path);

       stringdata = sr.ReadToEnd();

       string[] allData = data.Split('\n');

       for(inti = 0; i < 6; i++)
        {
           for(intj = 0; j < 8; j++)
            {
                mapData[i, j] =byte.Parse(allData[i][j].ToString());
            }
        }

        sr.Close();
        sr.Dispose();
    }
   ///<summary>
   ///根据mapData创建地图
   ///</summary>
   voidBuildMap()
    {
       GameObjectCube =Resources.Load("Cube")asGameObject;
       GameObjectBlueCube =Resources.Load("BlueCube")asGameObject;
       GameObjectRedCube =Resources.Load("RedCube")asGameObject;
       GameObjectGreenCube =Resources.Load("GreenCube")asGameObject;

       for(inti = 0; i < mapData.GetLength(0); i++)
        {
           for(intj = 0; j < mapData.GetLength(1); j++)
            {
               GameObjectcube;
               switch(mapData[i, j])
                {
                   case0: cube = Instantiate(GreenCube);break;
                   case1: cube = Instantiate(Cube);break;
                   case2: cube = Instantiate(RedCube);break;
                   case9: cube = Instantiate(BlueCube);break;
                   default:
                        cube = Instantiate(Cube);
                       break;
                }
                cube.transform.position =newVector3(-3 + j, 0, 4 + i);
                cube.transform.localScale =Vector3.one * 0.8f;
                cube.transform.SetParent(transform);
            }
        }
    }
}
0 0
原创粉丝点击