예제 #1
0
        public bool containsTile(Tile inputTile)
        {
            bool containsTileReturn = false;

            int index = this.AllMoveableTiles.FindIndex(tile => (tile.xPos == inputTile.xPos && tile.yPos == inputTile.yPos));

            if (index != -1)
                containsTileReturn = true;

            return containsTileReturn;
        }
예제 #2
0
        public const int baseCost = 1; //the cost of moving to any node. Set to 1 to make this simple for now.

        #endregion Fields

        #region Constructors

        public Node(Tile tile)
        {
            nodeTile = tile;
        }
예제 #3
0
        private static List<Node> getAdjacentNodes(Tile startingTile, Map map, List<Node> closedList, Node destinationNode)
        {
            List<Node> adjacentNodes = new List<Node>();
            List<Tile> tilesToCheck = new List<Tile>();
            Node startingNode = new Node(startingTile);

            int startingX = startingTile.xPos;
            int startingY = startingTile.yPos;

            if (map.coordinatesOnMap(startingX, startingY + 1))
                tilesToCheck.Add(map.tiles[startingX, startingY + 1]);

            if (map.coordinatesOnMap(startingX, startingY - 1))
                tilesToCheck.Add(map.tiles[startingX, startingY - 1]);

            if (map.coordinatesOnMap(startingX + 1, startingY))
                tilesToCheck.Add(map.tiles[startingX + 1, startingY]);

            if (map.coordinatesOnMap(startingX - 1, startingY))
                tilesToCheck.Add(map.tiles[startingX - 1, startingY]);

            foreach (Tile tile in tilesToCheck)
            {
                //make sure the tile isnt occupied and isnt in the checked list.
                if (!tile.isOccupied && !(closedList.FindIndex(node => node.nodeTile == tile) >= 0))
                {
                    Node newNode = new Node(tile);
                    newNode.FValue = calculateFValue(newNode, destinationNode);
                    newNode.parentNode = startingNode;
                    adjacentNodes.Add(newNode);
                }
            }

            return adjacentNodes;
        }
예제 #4
0
        public static List<Tile> shortestPath(Map map, Tile startingTile, Tile destinationTile)
        {
            List<Tile> path = new List<Tile>();
            List<Node> openNodes = new List<Node>();
            List<Node> closedNodes = new List<Node>();
            List<Node> adjacentNodes = new List<Node>();
            bool reachedDestination = false;

            //initialize. Set starting tile to be the first open node.

            Node startingNode = new Node(startingTile);
            Node destinationNode = new Node(destinationTile);
            startingNode.FValue = calculateFValue(startingNode, destinationNode);
            openNodes.Add(startingNode);
            Node nodeToEval = startingNode;

            while (openNodes.Count > 0) // while nodeToEval != destinationNode ?
            {
                //get adjacent nodes and add them to openNodes
                adjacentNodes = getAdjacentNodes(nodeToEval.nodeTile, map, closedNodes, destinationNode);
                openNodes.AddRange(adjacentNodes);
                openNodes.Remove(nodeToEval);
                closedNodes.Add(nodeToEval);
                //remove nodeToEval from open list, add to closed list

                if (nodeToEval.nodeTile.xPos == destinationNode.nodeTile.xPos && nodeToEval.nodeTile.yPos == destinationNode.nodeTile.yPos)
                {
                    reachedDestination = true;
                    break;
                }

                //Now we find the NEXT node to evaluate

                //We search for the lowest F value in the whole open list after adding the ajacent nodes above
                int lowestFValue = openNodes.Min(node => node.FValue);

                //Now get the node with that lowest value - thats our next node to examine.
                Node nextNodeToEval = openNodes.Find(node => node.FValue == lowestFValue);

                nodeToEval = nextNodeToEval;

                }

            if (reachedDestination == true)
            {
                //done! collect the destination and all parent nodes in a list
                path.Add(nodeToEval.nodeTile);
                Node nextParentNode = nodeToEval.parentNode;

                while (nextParentNode != null)
                {
                    path.Add(nextParentNode.nodeTile);
                    //find parent node in the closed list
                    Node currentParentNode = closedNodes.Find(node => node.nodeTile.xPos == nextParentNode.nodeTile.xPos && node.nodeTile.yPos == nextParentNode.nodeTile.yPos);
                    nextParentNode = currentParentNode.parentNode;
                }

            }

                // find adjacent available nodes and add nodeToEval to the closed list afterwards.

                //adjacentNodes = getAdjacentNodes(nodeToEval.nodeTile, map, closedNodes, destinationNode);
                //openNodes.Remove(nodeToEval);
               // openNodes.AddRange(adjacentNodes);

            return path;
        }
예제 #5
0
        public static List<Tile> getAdjacentUncheckedTiles(Tile StartingTile, Map map, List<Tile> checkedTiles)
        {
            List<Tile> AdjacentTiles = new List<Tile>();
            List<Tile> TilesToCheck = new List<Tile>();

            int startingTileX = StartingTile.xPos;
            int startingTileY = StartingTile.yPos;

            //check if the tiles passed in here resolve to null
            if (map.coordinatesOnMap(startingTileX, startingTileY + 1) )
            TilesToCheck.Add(map.tiles[startingTileX, startingTileY + 1]);

            if (map.coordinatesOnMap(startingTileX, startingTileY - 1))
            TilesToCheck.Add(map.tiles[startingTileX, startingTileY - 1]);

            if (map.coordinatesOnMap(startingTileX + 1, startingTileY))
            TilesToCheck.Add(map.tiles[startingTileX + 1, startingTileY]);

            if (map.coordinatesOnMap(startingTileX - 1, startingTileY))
            TilesToCheck.Add(map.tiles[startingTileX - 1, startingTileY]);

            if (TilesToCheck.Count > 0)
            {
                foreach (Tile currentTile in TilesToCheck)
                {
                    if (!currentTile.Equals(null)) // if the current tile is off the map, ie (1,0), the current tile will be null.
                    {
                        if (!currentTile.isOccupied && !checkedTiles.Contains(currentTile))
                        {
                            AdjacentTiles.Add(currentTile);
                        }
                    }
                }
            }

            return AdjacentTiles;
        }
예제 #6
0
        public static List<Tile> shortestPath(Map map, Tile startingTile, Tile destinationTile)
        {
            List<Tile> path = new List<Tile>();
            List<Node> openNodes = new List<Node>();
            List<Node> closedNodes = new List<Node>();
            List<Node> adjacentNodes = new List<Node>();
            bool reachedDestination = false;

            //initialize. Set starting tile to be the first open node.

            Node startingNode = new Node(startingTile);
            Node destinationNode = new Node(destinationTile);
            startingNode.FValue = calculateFValue(startingNode, destinationNode);
            openNodes.Add(startingNode);
            Node nodeToEval = startingNode;

            while (openNodes.Count > 0) // while nodeToEval != destinationNode ?
            {
                //get adjacent nodes and add them to openNodes
                adjacentNodes = getAdjacentNodes(nodeToEval.nodeTile, map, closedNodes, destinationNode);
                openNodes.AddRange(adjacentNodes);
                openNodes.Remove(nodeToEval);
                closedNodes.Add(nodeToEval);
                //remove nodeToEval from open list, add to closed list

                if (nodeToEval.nodeTile.xPos == destinationNode.nodeTile.xPos && nodeToEval.nodeTile.yPos == destinationNode.nodeTile.yPos)
                {
                    reachedDestination = true;
                    break;
                }

                //Now we find the NEXT node to evaluate

                //We search for the lowest F value in the whole open list after adding the ajacent nodes above
                int lowestFValue = openNodes.Min(node => node.FValue);

                //Now get the node with that lowest value - thats our next node to examine.
                Node nextNodeToEval = openNodes.Find(node => node.FValue == lowestFValue);

                //this method will give us boring L-shaped paths if two adjacent nodes have the same F value.
                //lets try forcing the game to prioritize the one that indicates a change in direction!

                if((openNodes.FindAll(node => node.FValue == lowestFValue).Count > 1))
                {
                    List<Node> potentialNextNodesToEval = openNodes.FindAll(node => node.FValue == lowestFValue);

                    foreach(Node node in potentialNextNodesToEval)
                    {
                        if (nodeToEval.parentNode != null){
                            if (nodeToEval.parentNode.nodeTile.xPos == nodeToEval.nodeTile.xPos && nodeToEval.nodeTile.xPos != node.nodeTile.xPos)
                            {
                                //change of direction in x, prioritize this node and exit
                                nextNodeToEval = node;
                                break;
                            }
                            else if (nodeToEval.parentNode.nodeTile.yPos == nodeToEval.nodeTile.yPos && nodeToEval.nodeTile.yPos != node.nodeTile.yPos)
                            {
                                //change of direction in y, prioritize this node and exit
                                nextNodeToEval = node;
                                break;
                            }
                        }
                    }
                }

                nodeToEval = nextNodeToEval;

                }

            if (reachedDestination == true)
            {
                //done! collect the destination and all parent nodes in a list
                path.Add(nodeToEval.nodeTile);
                Node nextParentNode = nodeToEval.parentNode;

                while (nextParentNode != null)
                {
                    path.Add(nextParentNode.nodeTile);
                    //find parent node in the closed list
                    Node currentParentNode = closedNodes.Find(node => node.nodeTile.xPos == nextParentNode.nodeTile.xPos && node.nodeTile.yPos == nextParentNode.nodeTile.yPos);
                    nextParentNode = currentParentNode.parentNode;
                }

            }

                // find adjacent available nodes and add nodeToEval to the closed list afterwards.

                //adjacentNodes = getAdjacentNodes(nodeToEval.nodeTile, map, closedNodes, destinationNode);
                //openNodes.Remove(nodeToEval);
               // openNodes.AddRange(adjacentNodes);

            return path;
        }
예제 #7
0
        public static Tile getCursorCurrentTile(Tile tile, Map map, Point cursorPoint, Rectangle tileRect)
        {
            //when the cursor is over a tile's rectangle, We need to find the space we're actually selecting. The rectangular sprite just containst the diamond
            //So the tile you pass in, is not necessarily the tile youre hovering over - it may be the edge, and therefore, in another tile.
            //We want to keep this general in case we chnge tile/asset sizes later. We can use the symmetry in iso art to our advantage.
            //Whatever the tile size, the angles will be the same, so the math will scale.

            //We have to go through each of the 5 possible areas designated by the given area. The center diamond, and the four sorrounding triangles. We'll do the center diamond first
            //if the point isnt in the center diamond, we can use a quick+dirty method of figuring out which triangle its in, and therefore which tile to return.

            //first get an array of points that make up the inner diamond

            Point[] polygon = new Point[4];

            polygon[0] = new Point(tileRect.X + Tile.width / 2, tileRect.Y);
            polygon[1] = new Point(tileRect.X, tileRect.Y + Tile.height / 2);
            polygon[2] = new Point(tileRect.X + Tile.width / 2, tileRect.Y + Tile.height);
            polygon[3] = new Point(tileRect.X + Tile.width, tileRect.Y + Tile.height / 2);

            bool insideDiamond = false;

            for (int i = 0, j = polygon.Length - 1; i < polygon.Length; j = i++)
            {
                if ((polygon[i].Y > cursorPoint.Y) != (polygon[j].Y > cursorPoint.Y) &&
                     cursorPoint.X < (polygon[j].X - polygon[i].X) * (cursorPoint.Y - polygon[i].Y) / (polygon[j].Y - polygon[i].Y) + polygon[i].X)
                {
                    insideDiamond = !insideDiamond;
                }
            }

            if (insideDiamond == true)
            {
                return tile;
            }
            else
            {
                //Ok, point is not in the diamond, so let's see which triangle it's in. Keep in mind that a tile adjacent to the given tile may be off the map.
                //Lets create bounding rectangles that contain the triangles in the corner, Then test if the point is in those rectangles. Since its not in the center diamond,
                //a hit here means the point is int the correponding triangle.
                Rectangle upperLeft = new Rectangle(tileRect.X, tileRect.Y, Tile.width/2, Tile.height/2);
                Rectangle upperRight = new Rectangle(tileRect.X + Tile.width / 2, tileRect.Y, Tile.width / 2, Tile.height / 2);
                Rectangle lowerLeft = new Rectangle(tileRect.X, tileRect.Y + Tile.height / 2, Tile.width / 2, Tile.height / 2);
                Rectangle lowerRight = new Rectangle(tileRect.X + Tile.width / 2, tileRect.Y + Tile.height / 2, Tile.width / 2, Tile.height / 2);

                if (upperLeft.Contains(cursorPoint))
                {
                    if (map.coordinatesOnMap(tile.xPos, tile.yPos - 1))
                    return map.tiles[tile.xPos, tile.yPos - 1];
                }
                else if (upperRight.Contains(cursorPoint))
                {
                    if (map.coordinatesOnMap(tile.xPos + 1, tile.yPos))
                    return map.tiles[tile.xPos + 1, tile.yPos];
                }
                else if (lowerLeft.Contains(cursorPoint))
                {
                    if (map.coordinatesOnMap(tile.xPos - 1, tile.yPos))
                    return map.tiles[tile.xPos - 1, tile.yPos];
                }
                else
                {
                    //only one left is bottom right:
                    if (map.coordinatesOnMap(tile.xPos, tile.yPos + 1))
                    return map.tiles[tile.xPos, tile.yPos + 1];
                }
            }

            return null;
        }