/// <summary> /// Creates Navigation mesh used for ai /// </summary> private void CreateNavMesh() { TileCollision currentTileCollision; TileCollision above, below; int platformStart = -1; Platform tempPlatform; //This steps through each tile looking for valid walking platforms. A valid walking platforms is two passable tiles on an impassable/platform tile //Once it finds one it stores the edge in a platform object and adds it as a node for (int y = 0; y < Height; y++) { for (int x = 0; x < Width; x++) { currentTileCollision = Tiles[y, x].Collision; if (y - 1 >= 0) { above = Tiles[y - 1, x].Collision; } else { above = TileCollision.Passable; } if (y + 1 < Height) { below = Tiles[y + 1, x].Collision; } else { below = TileCollision.Passable; } //if current tile is valid for walking on. two passable on top of impassable/platform if ((currentTileCollision == TileCollision.Passable || currentTileCollision == TileCollision.Platform) && (above == TileCollision.Passable || above == TileCollision.Platform) && (below == TileCollision.Impassable || below == TileCollision.Platform)) { if (platformStart == -1)//left edge isn't set yet means new platform! { platformStart = x; } if (x == Width - 1)//at the end of the map? end the platform { tempPlatform = new Platform(platformStart * TileWidth, (x * TileWidth) + TileWidth, (y * TileHeight) + TileHeight); Platforms.Add(tempPlatform); NavMesh.AddNode(tempPlatform); platformStart = -1; } } else if (platformStart != -1)//end of current platform { tempPlatform = new Platform(platformStart * TileWidth, x * TileWidth, (y * TileHeight) + TileHeight); Platforms.Add(tempPlatform); NavMesh.AddNode(tempPlatform); platformStart = -1; } } } ConnectNodes(); }
static public Graph <Platform> FindPath(Platform start, Platform finish) { if (navmesh == null) { throw new NullReferenceException("No Navigation Mesh Loaded."); } GraphNode <Platform> startNode = (GraphNode <Platform>)navmesh.Nodes.FindByValue(start); GraphNode <Platform> finishNode = (GraphNode <Platform>)navmesh.Nodes.FindByValue(finish); if (startNode == null || finishNode == null) { throw new ArgumentNullException("Start or finish platform is not in nav mesh"); } Graph <Platform> path = new Graph <Platform>(); Queue <GraphNode <Platform> > frontier = new Queue <GraphNode <Platform> >(); Dictionary <GraphNode <Platform>, GraphNode <Platform> > cameFrom = new Dictionary <GraphNode <Platform>, GraphNode <Platform> >(); GraphNode <Platform> current; frontier.Enqueue(startNode); cameFrom.Add(startNode, null); bool foundIt = false; while (frontier.Count > 0) { current = frontier.Dequeue(); if (current.Equals(finishNode)) { foundIt = true; break; } foreach (GraphNode <Platform> neighbor in current.Neighbors) { if (!cameFrom.ContainsKey(neighbor)) { cameFrom.Add(neighbor, current); frontier.Enqueue(neighbor); } } } if (foundIt == false) { return(null); } GraphNode <Platform> previous; current = finishNode; path.AddNode(current.Value); while (current != startNode) { previous = current; current = cameFrom[current]; path.AddNode(current.Value); path.AddDirectedEdge((GraphNode <Platform>)path.Nodes.FindByValue(current.Value), (GraphNode <Platform>)path.Nodes.FindByValue(previous.Value), 1); } return(path); }