Ejemplo n.º 1
0
/// <summary>
        /// Removes the argument PositionedNode from the NodeNetwork.  Also destroys any links
        /// pointing to the argument PositionedNode.
/// </summary>
/// <param name="nodeToRemove">The PositionedNode to remove from the network.</param>
/// <param name="scanAndRemoveOneWayReferences">Scans the entire network and removes all links to this node. Used when not all link relationships are two way.</param>
        #endregion
        public virtual void Remove(PositionedNode nodeToRemove, bool scanAndRemoveOneWayReferences)
        {
            if (scanAndRemoveOneWayReferences)
            {
                foreach (PositionedNode node in mNodes)
                {
                    if (node.IsLinkedTo(nodeToRemove))
                    {
                        node.BreakLinkBetween(nodeToRemove);
                    }
                }

                mNodes.Remove(nodeToRemove);
            }
            else
            {
                Remove(nodeToRemove);
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Disconnects all Links between this and the argument node.
        /// </summary>
        /// <param name="node">The PositionedNode to break links between.</param>
        #endregion
        public void BreakLinkBetween(PositionedNode node)
        {
            for (int i = 0; i < node.mLinks.Count; i++)
            {
                if (node.mLinks[i].NodeLinkingTo == this)
                {
                    node.mLinks.RemoveAt(i);
                    break;
                }
            }

            for (int i = 0; i < mLinks.Count; i++)
            {
                if (mLinks[i].NodeLinkingTo == node)
                {
                    mLinks.RemoveAt(i);
                    break;
                }
            }
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Creates a new, empty TileNodeNetwork matching the arguments.
        /// </summary>
        /// <param name="xOrigin">The X position of the left-most nodes. This, along with the ySeed, define the bottom-left of the node network.
        /// For tile maps this should be the center X of the first tile column (typically TileWidth / 2).</param>
        /// <param name="yOrigin">The y position of the bottom-most nodes. This, along with xSeed, define the bottom-left of the node network.
        /// For tile maps this should be the center Y of the bottom tile row.
        /// If the top-left of the map is at 0,0, then this value would be (-EntireMapHeight + TileHeight/2)</param>
        /// <param name="gridSpacing">The X and Y distance between each node. That is, the X distance between two adjacent nodes (assumed to be equal to the Y distance). For a tile map this will equal the width of a tile.</param>
        /// <param name="numberOfXTiles">The number of nodes vertically.</param>
        /// <param name="numberOfYTiles">The number of nodes horizontally.</param>
        /// <param name="directionalType">Whether to create a Four-way or Eight-way node network. Eight creates diagonal links, enabling diagonal movement when following the node network.</param>
        public TileNodeNetwork(float xOrigin, float yOrigin, float gridSpacing, int numberOfXTiles,
                               int numberOfYTiles, DirectionalType directionalType)
        {
            mCosts = new float[PropertyIndexSize]; // Maybe expand this to 64 if we ever move to a long bit field?

            OccupiedCircleRadius = .5f;
            mTiledNodes          = new PositionedNode[numberOfXTiles][];
            mNumberOfXTiles      = numberOfXTiles;
            mNumberOfYTiles      = numberOfYTiles;
            mDirectionalType     = directionalType;
            mXSeed       = xOrigin;
            mYSeed       = yOrigin;
            mGridSpacing = gridSpacing;

            // Do an initial loop to create the arrays so that
            // linking works properly
            for (int x = 0; x < numberOfXTiles; x++)
            {
                mTiledNodes[x] = new PositionedNode[numberOfYTiles];
            }
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Creates Links from this to the argument nodeToLinkTo, and another Link from the
        /// argument nodeToLinkTo back to this.
        /// </summary>
        /// <remarks>
        /// If either this or the argument nodeToLinkTo already contains a link to the other
        /// PositionedNode, then the cost of the link is set to the argument costTo or costFrom as appropriate.
        /// </remarks>
        /// <param name="nodeToLinkTo">The other PositionedNode to create the Links between.</param>
        /// <param name="costTo">The cost to travel from this to the argument nodeToLinkTo.</param>
        /// <param name="costFrom">The cost to travel from the nodeToLinkTo back to this.</param>
        #endregion
        public void LinkTo(PositionedNode nodeToLinkTo, float costTo, float costFrom)
        {
#if DEBUG
            if (nodeToLinkTo == this)
            {
                throw new ArgumentException("Cannot have a node link to itself");
            }
#endif
            bool updated = false;

            for (int i = 0; i < mLinks.Count; i++)
            {
                if (mLinks[i].NodeLinkingTo == nodeToLinkTo)
                {
                    mLinks[i].Cost = costTo;
                    updated        = true;
                    break;
                }
            }
            if (!updated)
            {
                mLinks.Add(new Link(nodeToLinkTo, costTo));
            }

            // Now do the same for the other node
            updated = false;
            for (int i = 0; i < nodeToLinkTo.mLinks.Count; i++)
            {
                if (nodeToLinkTo.mLinks[i].NodeLinkingTo == this)
                {
                    nodeToLinkTo.mLinks[i].Cost = costFrom;
                    updated = true;
                    break;
                }
            }
            if (!updated)
            {
                nodeToLinkTo.mLinks.Add(new Link(this, costFrom));
            }
        }
Ejemplo n.º 5
0
 public float GetVisibleNodeRadius(Camera camera, PositionedNode positionedNode)
 {
     return(NodeVisualizationRadius / camera.PixelsPerUnitAt(positionedNode.Z));
 }
Ejemplo n.º 6
0
 /// <summary>
 /// Creates Links from this to the argument nodeToLinkTo, and another Link from the
 /// argument nodeToLinkTo back to this.
 /// </summary>
 /// <remarks>
 /// If either this or the argument nodeToLinkTo already contains a link to the other
 /// PositionedNode, then the cost of the link is set to the argument costTo.
 /// </remarks>
 /// <param name="nodeToLinkTo">The other PositionedNode to create Links between.</param>
 /// <param name="costTo">The cost to travel between this and the argument nodeToLinkTo.</param>
 #endregion
 public void LinkTo(PositionedNode nodeToLinkTo, float costTo)
 {
     LinkTo(nodeToLinkTo, costTo, costTo);
 }
Ejemplo n.º 7
0
        public void LinkTo(PositionedNode nodeToLinkTo)
        {
            float distanceToTravel = (Position - nodeToLinkTo.Position).Length();

            LinkTo(nodeToLinkTo, distanceToTravel);
        }
Ejemplo n.º 8
0
 /// <summary>
 /// Creates a new Link.
 /// </summary>
 /// <param name="nodeLinkingTo">The node to link to.</param>
 /// <param name="cost">The cost to travel the link.</param>
 #endregion
 public Link(PositionedNode nodeLinkingTo, float cost)
 {
     mNodeLinkingTo = nodeLinkingTo;
     mCost          = cost;
     mActive        = true;
 }
Ejemplo n.º 9
0
        public void RemoveAndUnlinkNode(ref Microsoft.Xna.Framework.Vector3 positionToRemoveNodeFrom)
        {
            PositionedNode nodeToRemove = GetClosestNodeTo(ref positionToRemoveNodeFrom);

            Remove(nodeToRemove);
        }
Ejemplo n.º 10
0
        public PositionedNode GetClosestUnoccupiedNodeTo(ref Microsoft.Xna.Framework.Vector3 targetPosition, ref Microsoft.Xna.Framework.Vector3 startPosition, bool ignoreCorners)
        {
            PositionedNode nodeToReturn = null;
            int            xTile, yTile;

            WorldToIndex(targetPosition.X, targetPosition.Y, out xTile, out yTile);

            if (IsTileOccupied(xTile, yTile) == false)
            {
                nodeToReturn = TiledNodeAt(xTile, yTile);
            }

            if (nodeToReturn == null)
            {
                int startXTile, startYTile, xTileCheck, yTileCheck, deltaX, deltaY;
                WorldToIndex(startPosition.X, startPosition.Y, out startXTile, out startYTile);
                float shortestDistanceSquared = 999;
                int   finalTileX = -1, finalTileY = -1;

                //Get the "target" Node
                PositionedNode node      = TiledNodeAt(xTile, yTile);
                PositionedNode startNode = TiledNodeAt(startXTile, startYTile);
                PositionedNode checkNode;
                if (node != null && startNode != null)
                {
                    for (int i = 0; i < node.Links.Count; i++)
                    {
                        //skip any tile I am already on...
                        checkNode = node.Links[i].NodeLinkingTo;
                        if (checkNode == startNode)
                        {
                            continue;
                        }
                        WorldToIndex(checkNode.X, checkNode.Y, out xTileCheck, out yTileCheck);

                        if (IsTileOccupied(xTileCheck, yTileCheck) == false)
                        {
                            deltaX = xTileCheck - xTile;
                            deltaY = yTileCheck - yTile;

                            if (ignoreCorners == false || (ignoreCorners == true && (deltaX == 0 || deltaY == 0)))
                            {
                                float distanceFromStartSquared = ((xTileCheck - startXTile) * (xTileCheck - startXTile)) + ((yTileCheck - startYTile) * (yTileCheck - startYTile));
                                if (distanceFromStartSquared < shortestDistanceSquared)
                                {
                                    shortestDistanceSquared = distanceFromStartSquared;
                                    finalTileX = xTileCheck;
                                    finalTileY = yTileCheck;
                                }
                            }
                        }
                    }

                    if (finalTileX != -1 && finalTileY != -1)
                    {
                        nodeToReturn = TiledNodeAt(finalTileX, finalTileY);
                    }
                }
            }

            return(nodeToReturn);
        }
Ejemplo n.º 11
0
 public float GetVisibleNodeRadius(Camera camera, PositionedNode positionedNode)
 {
     return(_visibleCoefficient / camera.PixelsPerUnitAt(positionedNode.Z));
 }