Пример #1
0
    // 计算点周围可以选择的点
    private List <NodeOffset> ClacRoundPoint(PathNode pn)
    {
        var mapWidth  = this.Width;
        var mapHeight = this.Height;
        var tiles     = this.GetTiles();

        RoundNodes.Clear();

        for (int i = 0; i < offsets.Length; ++i)
        {
            NodeOffset offset = offsets[i];

            int x = pn.grid.x + offset.x;
            if (x < 0 || x >= mapWidth)
            {
                continue;
            }
            int y = pn.grid.z + offset.y;
            if (y < 0 || y >= mapHeight)
            {
                continue;
            }

            int index = y * mapWidth + x;
            if (closeDic.ContainsKey(index))
            {
                continue;
            }

            if (!CanWalk(tiles[x, y]))
            {
                continue;
            }

            // 忽略拐角拌脚点 斜方向
            if (Mathf.Abs(offset.y) + Mathf.Abs(offset.x) > 1)
            {
                if (!CanWalk(tiles[x, y - offset.y]) || !CanWalk(tiles[x - offset.x, y]))
                {
                    continue;
                }
            }

            RoundNodes.Add(offset);
        }

        return(RoundNodes);
    }
Пример #2
0
    public bool GetPathDistance(int fromGridX, int fromGridZ, int toGridX, int toGridZ, out List <MapGrid> path)
    {
        var mapWidth  = this.Width;
        var mapHeight = this.Height;

        //var tiles = this.GetTiles();

        path = new List <MapGrid>();
        if (CanWalk(tiles[fromGridX, fromGridZ]) == false)
        {
            return(false);
        }

        if (CanWalk(tiles[toGridX, toGridZ]) == false)
        {
            return(false);
        }

        // 同一个点也导出路径
        if (fromGridX == toGridX && fromGridZ == toGridZ)
        {
            path.Add(new MapGrid()
            {
                x = fromGridX, z = fromGridZ
            });
            path.Add(new MapGrid()
            {
                x = toGridX, z = toGridZ
            });
            return(true);
        }

        ClearPath();


        PathNode pnTo = new PathNode();//m_PathNodePool.Alloc();

        pnTo.Init(toGridZ * mapWidth + toGridX, 0, 0, 0);
        PathNode pnFrom = new PathNode();//m_PathNodePool.Alloc();

        pnFrom.Init(fromGridZ * mapWidth + fromGridX, 0, 0, 0);

        openDic.Add(pnFrom.index, pnFrom);
        InsertToList(pnFrom);
        totalDic.Add(pnFrom.index, pnFrom);


        while (openDic.Count > 0)
        {
            if (open_list.First == null)
            {
                break;
            }
            PathNode pn = open_list.First.Value;


            if (pn == null)
            {
                break;
            }

            closeDic.Add(pn.index, pn);
            openDic.Remove(pn.index);
            RemoveFromList(pn);
            if (pn.index == pnTo.index)
            {
                break;
            }

            List <NodeOffset> offsets = ClacRoundPoint(pn);
            if (offsets.Count <= 0)
            {
                openDic.Remove(pn.index);
                RemoveFromList(pn);
                continue;
            }

            for (int i = 0; i < offsets.Count; ++i)
            {
                NodeOffset offset = offsets[i];

                int x = pn.grid.x + offset.x;
                if (x < 0 || x >= mapWidth)
                {
                    continue;
                }
                int y = pn.grid.z + offset.y;
                if (y < 0 || y >= mapHeight)
                {
                    continue;
                }

                int index = y * mapWidth + x;

                if (closeDic.ContainsKey(index))
                {
                    continue;
                }

                PathNode pntmp = null;
                float    g     = pn.g + offset.distance;

                //if (openDic.ContainsKey(index))
                if (openDic.TryGetValue(index, out pntmp))
                {
                    pntmp = openDic[index];
                    if (g < pntmp.g)
                    {
                        pntmp.parentIndex = pn.index;
                        RemoveFromList(pntmp);
                        pntmp.setG(g);
                        InsertToList(pntmp);
                    }
                }
                else
                {
                    pntmp = new PathNode();//m_PathNodePool.Alloc();
                    pntmp.Init(index, pn.index, 0, 0);

                    openDic[index]  = pntmp;
                    totalDic[index] = pntmp;
                    pntmp.h         = GetDistance(pntmp, pnTo);//Math.Abs(Vector2.Distance(pntmp.position, pnTo.position));
                    pntmp.setG(g);
                    InsertToList(pntmp);
                }
            }
        }

        if (!closeDic.ContainsKey(pnTo.index))
        {
            return(false);
        }

        List <MapGrid> tmpPath = new List <MapGrid>();
        PathNode       node    = closeDic[pnTo.index];

        while (node != null)
        {
            tmpPath.Add(node.grid);

            if (node.parentIndex == 0)
            {
                break;
            }

            node = totalDic[node.parentIndex];
        }

        tmpPath.Reverse_NoHeapAlloc(); // 路径反转
        path = tmpPath;

        ClearPath();

        return(true);
    }
Пример #3
0
    public List <MapGrid> GetPath(int fromGridX, int fromGridZ, int toGridX, int toGridZ, TileType validType)
    {
        List <MapGrid> path = new List <MapGrid>();

        if ((this[fromGridX, fromGridZ] & validType) == 0)
        {
            return(path);
        }

        if ((this[toGridX, toGridZ] & validType) == 0)
        {
            return(path);
        }

        // 同一个点也导出路径
        if (fromGridX == toGridX && fromGridZ == toGridZ)
        {
            path.Add(new MapGrid()
            {
                x = fromGridX, z = fromGridZ
            });
            path.Add(new MapGrid()
            {
                x = toGridX, z = toGridZ
            });
            return(path);
        }

        PathNode pnFrom = new PathNode(fromGridZ * gridXNum + fromGridX, 0, 0, 0, this);
        PathNode pnTo   = new PathNode(toGridZ * gridXNum + toGridX, 0, 0, 0, this);

        Dictionary <int, PathNode> totalDic = new Dictionary <int, PathNode>();
        Dictionary <int, PathNode> openDic  = new Dictionary <int, PathNode>();
        Dictionary <int, PathNode> closeDic = new Dictionary <int, PathNode>();

        openDic.Add(pnFrom.index, pnFrom);
        totalDic.Add(pnFrom.index, pnFrom);

        float disCornor = Mathf.Sqrt(MapGrid.Width * MapGrid.Width + MapGrid.Height * MapGrid.Height);

        NodeOffset[] offsets = new NodeOffset[] { new NodeOffset(gridXNum - 1, disCornor), new NodeOffset(gridXNum, MapGrid.Height), new NodeOffset(gridXNum + 1, disCornor),
                                                  new NodeOffset(-1, MapGrid.Width), new NodeOffset(1, MapGrid.Width),
                                                  new NodeOffset(-gridXNum - 1, disCornor), new NodeOffset(-gridXNum, MapGrid.Height), new NodeOffset(-gridXNum + 1, disCornor) };
        while (openDic.Count > 0)
        {
            PathNode pn = null;
            foreach (KeyValuePair <int, PathNode> t in openDic)
            {
                if (pn == null)
                {
                    pn = t.Value;
                }
                if (t.Value.f < pn.f)
                {
                    pn = t.Value;
                }
            }

            closeDic.Add(pn.index, pn);
            openDic.Remove(pn.index);

            if (pn.index == pnTo.index)
            {
                break;
            }

            foreach (NodeOffset offset in offsets)
            {
                int index = pn.index + offset.offset;
                if (index < 0 || index > grids.Length)
                {
                    continue;
                }
                if (closeDic.ContainsKey(index))
                {
                    continue;
                }
                if ((grids[index] & validType) == 0)
                {
                    continue;
                }

                PathNode pntmp = null;
                float    g     = pn.g + offset.distance;

                if (openDic.ContainsKey(index))
                {
                    pntmp = openDic[index];
                    if (g < pntmp.g)
                    {
                        pntmp.parentIndex = pn.index;
                        pntmp.setG(g);
                    }
                }
                else
                {
                    pntmp           = new PathNode(index, pn.index, 0, 0, this);
                    openDic[index]  = pntmp;
                    totalDic[index] = pntmp;
                    pntmp.h         = Mathf.Abs(Vector3.Distance(pntmp.position, pnTo.position));
                    pntmp.setG(g);
                }
            }
        }

        if (!closeDic.ContainsKey(pnTo.index))
        {
            return(path);
        }

        List <MapGrid> tmpPath = new List <MapGrid>();
        PathNode       node    = closeDic[pnTo.index];

        while (node != null)
        {
            tmpPath.Add(node.grid);

            if (node.parentIndex == 0)
            {
                break;
            }
            node = totalDic[node.parentIndex];
        }

        path = LinePathEx(tmpPath, validType);
        return(path);
    }
Пример #4
0
	public List<MapGrid> GetPath(int fromGridX, int fromGridZ, int toGridX, int toGridZ, TileType validType)
	{
		List<MapGrid> path = new List<MapGrid>();
		if ((this[fromGridX, fromGridZ] & validType) == 0)
			return path;
		
		if ((this[toGridX, toGridZ] & validType) == 0)
			return path;

		// 同一个点也导出路径
		if(fromGridX == toGridX && fromGridZ == toGridZ)
		{
			path.Add(new MapGrid(){x = fromGridX, z = fromGridZ});
			path.Add(new MapGrid(){x = toGridX, z = toGridZ});
			return path;
		}

		PathNode pnFrom = new PathNode(fromGridZ * gridXNum + fromGridX, 0, 0, 0, this);
		PathNode pnTo = new PathNode(toGridZ * gridXNum + toGridX, 0, 0, 0, this);

		Dictionary<int, PathNode> totalDic = new Dictionary<int, PathNode>();
		Dictionary<int, PathNode> openDic = new Dictionary<int, PathNode>();
		Dictionary<int, PathNode> closeDic = new Dictionary<int, PathNode>();
		openDic.Add(pnFrom.index, pnFrom);
		totalDic.Add(pnFrom.index, pnFrom);

		float disCornor = Mathf.Sqrt(MapGrid.Width * MapGrid.Width + MapGrid.Height * MapGrid.Height);
		NodeOffset[] offsets = new NodeOffset[]{new NodeOffset(gridXNum-1, disCornor), new NodeOffset(gridXNum, MapGrid.Height),new NodeOffset(gridXNum+1, disCornor),
			new NodeOffset(-1, MapGrid.Width), new NodeOffset(1, MapGrid.Width),
			new NodeOffset(-gridXNum-1, disCornor), new NodeOffset(-gridXNum, MapGrid.Height),new NodeOffset(-gridXNum+1, disCornor)};
		while(openDic.Count > 0)
		{
			PathNode pn = null;
			foreach(KeyValuePair<int, PathNode> t in openDic)
			{
				if (pn == null) pn = t.Value;
				if (t.Value.f < pn.f) pn = t.Value;
			}

			closeDic.Add(pn.index, pn);
			openDic.Remove(pn.index);

			if (pn.index == pnTo.index) break;

			foreach(NodeOffset offset in offsets)
			{
				int index = pn.index + offset.offset;
				if (index < 0 || index > grids.Length) continue;
				if (closeDic.ContainsKey(index)) continue;
				if ((grids[index] & validType) == 0) continue;

				PathNode pntmp = null;
				float g = pn.g + offset.distance;

				if (openDic.ContainsKey(index)) 
				{
					pntmp = openDic[index];
					if (g < pntmp.g)
					{
						pntmp.parentIndex = pn.index;
						pntmp.setG(g);
					}
				}
				else
				{
					pntmp = new PathNode(index, pn.index, 0, 0, this);
					openDic[index] = pntmp;
					totalDic[index] = pntmp;
					pntmp.h = Mathf.Abs(Vector3.Distance(pntmp.position, pnTo.position));
					pntmp.setG(g);
				}
			}
		}

		if(!closeDic.ContainsKey(pnTo.index))
			return path;

		List<MapGrid> tmpPath = new List<MapGrid>();
		PathNode node = closeDic[pnTo.index];
		while(node != null)
		{
			tmpPath.Add(node.grid);

			if(node.parentIndex == 0)
				break;
			node = totalDic[node.parentIndex];
		}

		path = LinePathEx(tmpPath, validType);
		return path;
	}