zoukankan      html  css  js  c++  java
  • Unity C#写的A*寻路

    原地址:http://www.unity蛮牛.com/blog-13769-1078.html

    首先看了这篇翻译外国人的文章http://www.raywenderlich.com/zh-hans/21503/a%E6%98%9F%E5%AF%BB%E8%B7%AF%E7%AE%97%E6%B3%95%E4%BB%8B%E7%BB%8D

     
     
    1.定义地图节点,及初始化地图数据

    [code]csharpcode:

    using UnityEngine;
    using System.Collections.Generic;
    
    public class Map
    {
        /// <summary>
        /// 初始化地图
        /// </summary>
        /// <returns></returns>
        public static Dictionary<string, MapInfo> GetMap()
        {
            Dictionary<string, MapInfo> temp = new Dictionary<string, MapInfo>();
    
            for (int i = 0; i < 10; i++)
            {
                string s = "";
                for (int j = 0; j < 10; j++)
                {
                    int tt = 0;
                    if (i > 1 && i < 8 && j == 5)
                    {
                        tt = 1;
                    }
                    MapInfo mi = new MapInfo(i, j, tt);
                    temp.Add(i + "-" + j, mi);
                    s += mi.tag + " ";
                }
                Debug.Log(s);
            }
            return temp;
        }
    }
    
    /// <summary>
    /// 地图节点
    /// </summary>
    public class MapInfo
    {
        /// <summary>
        /// X
        /// </summary>
        public int x;
        /// <summary>
        /// Y
        /// </summary>
        public int y;
        /// <summary>
        /// 是否可行走
        /// </summary>
        public int tag;
        /// <summary>
        /// G
        /// </summary>
        public int gValue;
        /// <summary>
        /// H
        /// </summary>
        public int hValue;
        /// <summary>
        /// 父节点
        /// </summary>
        public MapInfo parent;
    
        public MapInfo()
        { }
    
        /// <summary>
        /// 构造
        /// </summary>
        /// <param name="x"></param>
        /// <param name="y"></param>
        /// <param name="tag"></param>
        public MapInfo(int x, int y,int tag)
        {
            this.x = x;
            this.y = y;
            this.tag = tag;
            this.gValue = 0;
            this.hValue = 0;
            this.parent = null;
        }
    }
    2.由起点终点寻路,有注释,知道原理的话,应该很容易懂

    [code]csharpcode:

    using UnityEngine;
    using System.Collections.Generic;
    
    public class AStar : MonoBehaviour
    {
        /// <summary>
        /// 地图
        /// </summary>
        Dictionary<string, MapInfo> map;
        /// <summary>
        /// open列表
        /// </summary>
        Dictionary<string, MapInfo> openList = new Dictionary<string, MapInfo>();
        /// <summary>
        /// close列表
        /// </summary>
        Dictionary<string, MapInfo> closeList = new Dictionary<string, MapInfo>();
    
        /// <summary>
        /// 当前点
        /// </summary>
        MapInfo currentV;
        /// <summary>
        /// 当前点的相邻节点列表
        /// </summary>
        Dictionary<string, MapInfo> adjancentMap;
    
    
        // Use this for initialization
        void Start () 
        {
            map = Map.GetMap();
            MapInfo st = map["5-2"];//start
            MapInfo end = map["6-8"];//end
    
            FindPath(st, end);
        }
            
          
        /// <summary>
        /// 寻路
        /// </summary>
        /// <param name="start">起点</param>
        /// <param name="end">终点</param>
        public void FindPath(MapInfo start,MapInfo end)
        {
            openList.Add(start.x + "-" + start.y, start);
    
            do
            {
                currentV = GetTheLowestFrom(openList);
    
                closeList.Add(currentV.x + "-" + currentV.y, currentV);
                openList.Remove(currentV.x + "-" + currentV.y);
    
                if (closeList.ContainsKey(end.x + "-" + end.y))
                {
                    Debug.Log("FindPath");
    
                    PrintThePath(end);
                    break;
                }
    
                adjancentMap = AdjacentList(currentV);
    
                foreach (string k in adjancentMap.Keys)
                {
                    if (closeList.ContainsKey(k))
                    {
                        continue;
                    }
    
                    if (!openList.ContainsKey(k))
                    {
                        adjancentMap[k].parent = currentV;
                        adjancentMap[k].gValue = currentV.gValue + 1;
                        adjancentMap[k].hValue = GetManhattanDistance(adjancentMap[k], end);
                        openList.Add(k, adjancentMap[k]);
                    }
                    else
                    {
                        int g = currentV.gValue + 1;
                        if (g < adjancentMap[k].gValue)
                        {
                            adjancentMap[k].gValue = g;
                            adjancentMap[k].parent = currentV;
                        }
                    }
                }
    
    
            } while (openList.Count > 0);
        }
    
        /// <summary>
        /// 获取openlist中F最小的节点
        /// </summary>
        /// <param name="open"></param>
        /// <returns></returns>
        public MapInfo GetTheLowestFrom(Dictionary<string, MapInfo> open)
        {
            MapInfo result=null;
            int min = 10000;
            foreach (MapInfo m in open.Values)
            {
                if (m.gValue + m.hValue < min)
                {
                    result = m;
                    min = m.gValue + m.hValue;
                }
            }
            return result;
        }
    
        /// <summary>
        /// 获取当前节点的相邻节点
        /// </summary>
        /// <param name="m">当前节点</param>
        /// <returns></returns>
        public Dictionary<string, MapInfo> AdjacentList(MapInfo m)
        {
            Dictionary<string, MapInfo> resultDic=new Dictionary<string,MapInfo>();
    
            string left = (m.x - 1) + "-" + m.y;
            string right = (m.x + 1) + "-" + m.y;
            string top = m.x + "-" + (m.y - 1);
            string bot = m.x + "-" + (m.y + 1);
    
            if (map.ContainsKey(left))
            {
                if(map[left].tag==0)
                    resultDic.Add(left, map[left]);
            }
    
            if (map.ContainsKey(right))
            {
                if (map[right].tag == 0)
                    resultDic.Add(right, map[right]);
            }
    
            if (map.ContainsKey(top))
            {
                if (map[top].tag == 0)
                    resultDic.Add(top, map[top]);
            }
    
            if (map.ContainsKey(bot))
            {
                if (map[bot].tag == 0)
                    resultDic.Add(bot, map[bot]);
            }
            return resultDic;
        }
    
        /// <summary>
        /// 获得两个点的曼哈顿距离
        /// 作为估值函数
        /// </summary>
        /// <param name="st"></param>
        /// <param name="end"></param>
        /// <returns></returns>
        public int GetManhattanDistance(MapInfo st, MapInfo end)
        {
            int result = 0;
            result = Mathf.Abs(st.x - end.x) + Mathf.Abs(st.y - end.y);
            return result;
        }
    
        /// <summary>
        /// 输出路径
        /// </summary>
        /// <param name="end">终点</param>
        public void PrintThePath(MapInfo end)
        {
            string s = "";
            MapInfo m = end;
            while (m.parent != null)
            {
                s += "("+m.parent.x + "," + m.parent.y + ")->";            
                m = m.parent;
            }
            Debug.Log(s);
        }
    }
  • 相关阅读:
    left join
    order by 对null的处理
    checkbox不显示,试试去掉-webkit-appearance这个样式
    浅谈ES6的let和const的异同点
    ES6中箭头函数的作用
    HTML页面每次打开的时候都清除页面缓存
    解决HTML加载时,外部js文件引用较多,影响页面打开速度问题
    JQuery和Zepto的差异(部分)
    vue-router 快速入门
    vue-resource插件使用
  • 原文地址:https://www.cnblogs.com/123ing/p/3868097.html
Copyright © 2011-2022 走看看