Beispiel #1
0
        /// <summary>
        /// Initializes a new instance of the <see cref="Map"/> class.
        /// </summary>
        /// <param name="tileset"> The tileset to create the map from. </param>
        /// <param name="layer"> The layer to create the map from. </param>
        public Map(Tileset tileset, MapLayer layer)
        {
            this.tilesets = new List<Tileset>();
            this.tilesets.Add(tileset);

            this.mapLayers = new List<MapLayer>();
            this.mapLayers.Add(layer);

            mapWidth = this.mapLayers[0].Width;
            mapHeight = this.mapLayers[0].Height;

            this.dataMap = new MapData(this.MapHeight, this.MapWidth);
            this.dataMap.AddCollision(this.mapLayers, this.tilesets);
        }
Beispiel #2
0
        /// <summary>
        /// Finds the shortest path between the start vector and the goal vector,
        /// taking into account whether the unit can actually get there or not.
        /// A* pathfinding.
        /// </summary>
        /// <param name="start"> The vector to start the search from. </param>
        /// <param name="goal"> The vector to end the search at. </param>
        /// <param name="unit"> The unit that is trying to find the route. </param>
        /// <param name="dataMap"> The data map. </param>
        /// <returns>
        /// A list representing the shortest path.
        /// </returns>
        public static List<Vector> FindShortestPathWithinReach(Vector start, Vector goal, Unit unit, MapData dataMap)
        {
            // Set stuff up
            var closedList = new List<Vector>();
            var openList = new List<Vector>();
            var openListQueue = new PriorityQueue<Vector, int>();

            var newStart = start;
            newStart.CameFrom = null;
            newStart.GScore = 0;
            newStart.FScore = newStart.GScore + CostEstimate(newStart, goal);

            openList.Add(newStart);
            openListQueue.Enqueue(newStart);

            if (newStart.Equals(goal))
            {
                return openList;
            }

            // While the queue isn't empty ...
            while (!openListQueue.Empty)
            {
                // ... get highest prioritied point
                var current = openListQueue.Dequeue();
                openList.Remove(current);

                if (current.Equals(goal))
                {
                    return RetracePath(current);
                }

                closedList.Add(current);

                // Iterates over nearby points
                foreach (var neighbor in NeighborNodes(current))
                {
                    // If the point has been visited, ignore it
                    if (closedList.Contains(neighbor))
                    {
                        continue;
                    }

                    // If it hasn't been visited and the unit can reach it, add it
                    // to the list.
                    if (!openList.Contains(neighbor)
                        && dataMap.WithinMapAndCanTraverse(neighbor.X, neighbor.Y, unit)
                        && CostEstimate(unit.Location, neighbor) <= unit.MoveRange)
                    {
                            neighbor.CameFrom = current;
                            neighbor.GScore = current.GScore + 1;
                            neighbor.FScore = newStart.GScore + CostEstimate(neighbor, goal);

                            openList.Add(neighbor);
                            openListQueue.Enqueue(neighbor);
                    }
                }
            }

            return openList;
        }
Beispiel #3
0
        /// <summary>
        /// Initializes a new instance of the <see cref="Map"/> class.
        /// </summary>
        /// <param name="tilesets"> The tilesets to create the map from. </param>
        /// <param name="layers"> The layers to create the map from. </param>
        public Map(List<Tileset> tilesets, List<MapLayer> layers)
        {
            this.tilesets = tilesets;
            this.mapLayers = layers;

            mapWidth = this.mapLayers[0].Width;
            mapHeight = this.mapLayers[0].Height;

            // Makes sure that all layers are of the same size.
            for (int i = 1; i < layers.Count; i++)
            {
                if (mapWidth != this.mapLayers[i].Width || mapHeight != this.mapLayers[i].Height)
                {
                    throw new Exception("MapData layer size exception");
                }
            }

            this.dataMap = new MapData(this.MapHeight, this.MapWidth);
            this.dataMap.AddCollision(this.mapLayers, this.tilesets);
        }
Beispiel #4
0
        /// <summary>
        /// Finds the areas the unit can move to.
        /// </summary>
        /// <param name="unit"> The unit.  </param>
        /// <param name="dataMapData"> The datamap.  </param>
        /// <returns>
        /// The list of vectors.
        /// </returns>
        public static List<Vector> MarkValidMoves(Unit unit, MapData dataMapData)
        {
            var startVector = new Vector(unit.Location.X, unit.Location.Y);

            var validMovesList = new List<Vector>();
            var validMoves = new LinkedList<Vector>();

            validMovesList.Add(startVector);
            validMoves.AddFirst(startVector);

            // While there are places left to check ...
            while (validMoves.Count > 0)
            {
                // ... get the first move
                var moveNode = validMoves.First.Value;
                validMoves.RemoveFirst();

                // Find further possible moves
                foreach (var neighborNode in NeighborNodes(moveNode))
                {
                    var tempVector = new Vector(neighborNode.X, neighborNode.Y);

                    // If the point has been visited, ignore it
                    if (validMovesList.Contains(tempVector) ||
                        !unit.PointWithinMoveRange(tempVector))
                    {
                        continue;
                    }

                    // If the unit can move there ...
                    if (dataMapData.WithinMapMoveRangeAndCanTraverse(tempVector.X, tempVector.Y, unit))
                    {
                        // ... add it to the list.
                        validMoves.AddLast(tempVector);
                        validMovesList.Add(tempVector);
                    }
                }
            }

            return validMovesList;
        }