using
directive to the top of the class file:using Microsoft.Xna.Framework;
#region Declarations public PathNode ParentNode; public PathNode EndNode; private Vector2 gridLocation; public float TotalCost; public float DirectCost; #endregion
#region Properties public Vector2 GridLocation { get { return gridLocation; } set { gridLocation = new Vector2( (float)MathHelper.Clamp(value.X,0f,(float)TileMap. MapWidth), (float)MathHelper.Clamp(value.Y,0f,(float)TileMap. MapHeight)); } } public int GridX { get { return (int)gridLocation.X; } } public int GridY { get { return (int)gridLocation.Y; } } #endregion
#region Constructor public PathNode( PathNode parentNode, PathNode endNode, Vector2 gridLocation, float cost) { ParentNode = parentNode; GridLocation = gridLocation; EndNode = endNode; DirectCost = cost; if (!(endNode==null)) { TotalCost = DirectCost + LinearCost(); } } #endregion
#region Helper Methods public float LinearCost() { return ( Vector2.Distance( EndNode.GridLocation, this.GridLocation)); } #endregion
#region Public Methods public bool IsEqualToNode(PathNode node) { return (GridLocation == node.GridLocation); } #endregion
When building a chain of nodes that represent a path, each node needs to know what node it was arrived at from. The ParentNode
member variable stores the reference to that node, while the EndNode
member stores the node that the search system is seeking as the destination. This information will be needed in calculating the indirect cost of the node.
The gridLocation
member and its associated GridLocation
property represent the X and Y coordinates of the node on the tile map, identifying the node's position in the game world. The GridX
and GridY
properties provide a shortcut for accessing the individual components of the gridLocation
vector.
When a new PathNode
is created, its direct cost (the cost associated with either a horizontal or vertical move) is stored in the DirectCost
variable. If the endNode
passed to the constructor is not null (which will be the case when the end node itself is created), the TotalCost
member is calculated by adding the DirectCost
and the result of the LinearCost()
method, which measures the distance between the node and the end node. We could make the TotalCost
a property that adds the two values and returns the result, but the Vector2.Distance()
method is relatively costly when it is run hundreds of times comparing costs, so caching the value will give us a slight edge in performance.
The IsEqualToNode()
method is needed because all classes are reference types in C#, meaning that the variables in our program are really pointers to objects in memory. Assigning a reference type to a new variable does not make a copy of the whole object, but rather it simply copies the pointer and creates a new reference to the same object.
In order to determine if two different instances of the PathNode
object represent the same square on the map, IsEqualToNode()
checks to see if the GridLocation
properties of the two nodes match. Since a Vector2
is a value type, the comparison happens between the actual data values in the Vector2
instead of reference pointers.
Now it is time to build the actual path-finding code, which we are going to do in a few stages for clarity. To begin, let's create a new static class, which will handle pathing for our game.
18.117.183.172