public static WorldGraph GetWorldGraph() { if (worldGraphSingleton == null) { worldGraphSingleton = new WorldGraph(); } return(worldGraphSingleton); }
public float GetHeuristic(Physics.Vector2D destination) { //Apply a simple euclidean distance heuristic //Intended to give nodes a higher cost the further they are from the final goal //If a different destination node is used as an argument then this heuristic may work better or worse WorldGraph mainGraph = WorldGraph.GetWorldGraph(); Physics.Vector2D currentPosition = mainGraph.topLevelNode.GetNodePosition(index); return((currentPosition - destination).Length() * 10); }
public AIEngine(Physics.Player thePlayer) { physEng = Physics.PhysicsEngine.GetPhysicsEngine(); mainGraph = WorldGraph.GetWorldGraph(); AIPlayer = thePlayer; actionPlan = new List <act_dur>(); currentState = STATES.WAITING; currentStateCooldown = 0.0f; walkingSpeed = 500f; destinationNode = null; currentlyJumping = false; }
//The following method assumes the nodes provided are rigidbodies with leaf nodes attached to them private static CONNECTION_TYPE GetConnectionBetweenRigidBodies(Node rigidBody1, Node rigidBody2) { WorldGraph mainGraph = WorldGraph.GetWorldGraph(); CONNECTION_TYPE toReturn = CONNECTION_TYPE.NONE; List <Physics.Vector2D> nodePositions1, nodePositions2; //compare each node from rigidbody 1 to each node in rigidbody 2 foreach (Node node1 in rigidBody1.internalNodes) { foreach (Node node2 in rigidBody2.internalNodes) { //Due to the presence of moving platforms, create lists of the different possible positions of each node nodePositions1 = new List <Physics.Vector2D>(); nodePositions2 = new List <Physics.Vector2D>(); //add the node's default positions nodePositions1.Add(mainGraph.topLevelNode.GetNodePosition(node1)); nodePositions2.Add(mainGraph.topLevelNode.GetNodePosition(node2)); //if rigidbody 1 moves between two points, add the position of node1 at BOTH those points to the list if (rigidBody1 is NodeOnRails) { nodePositions1.Add( mainGraph.topLevelNode.GetNodePosition(rigidBody1.index.GetParentIndex()) + ((NodeOnRails)rigidBody1).railPoint1 + node1.position); nodePositions1.Add( mainGraph.topLevelNode.GetNodePosition(rigidBody1.index.GetParentIndex()) + ((NodeOnRails)rigidBody1).railPoint2 + node1.position); } //if rigidbody 2 moves between two points, add the position of node2 when at BOTH those points to the list if (rigidBody2 is NodeOnRails) { nodePositions2.Add( mainGraph.topLevelNode.GetNodePosition(rigidBody2.index.GetParentIndex()) + ((NodeOnRails)rigidBody2).railPoint1 + node2.position); nodePositions2.Add( mainGraph.topLevelNode.GetNodePosition(rigidBody2.index.GetParentIndex()) + ((NodeOnRails)rigidBody2).railPoint2 + node2.position); } //at this point two lists have been created containing all the positions each node could occupy //loop through both lists to determine if any position combinations should be connected CONNECTION_TYPE temp; //loop through both lists, adding all possible connections to node1 foreach (Physics.Vector2D pos1 in nodePositions1) { foreach (Physics.Vector2D pos2 in nodePositions2) { //find out if the two nodes can be connected temp = GetConnectionBetween(node1.type, node2.type, pos1, pos2); if (temp != CONNECTION_TYPE.NONE) { float cost = (pos1 - pos2).Length(); //modify cost based on the type of connection switch (temp) { case CONNECTION_TYPE.JUMP: cost += 20; break; case CONNECTION_TYPE.FALL: cost += 5; break; default: cost += 2; break; } node1.addConnection(new Connection(node2.index, cost, temp)); //change the return value to reflect the presence of a connection toReturn = CONNECTION_TYPE.HIGH_LEVEL; } } } } } return(toReturn); }
public static List <NodeIndex> AstarPathfind(Node startNode, Node endNode, List <Node> nodesToSearch) { //ASSUMPTIONS: // Start Node is on the same layer as the set of nodes to search // End Node is on the same layer as the start Node, or one level above! //reset the path of all nodes foreach (Node n in nodesToSearch) { n.ResetPath(); } WorldGraph fullAIGraph = WorldGraph.GetWorldGraph(); //create the open and closed lists List <NodeIndex> openList = new List <NodeIndex>(); List <NodeIndex> closedList = new List <NodeIndex>(); //find the current layer being searched through int nodeListDepth = startNode.index.GetMaxDepth(); bool endNodeOnSameLayer = nodeListDepth == endNode.index.GetMaxDepth(); //currentNode is the node being examined NodeIndex currentNode; NodeIndex nextNode; openList.Add(startNode.index); while (openList.Count() > 0) { //Get the cheapest node in the open list currentNode = GetCheapestNode(openList, nodesToSearch, endNode.internalNodes); //if the goal has been found then retrace the path and return it if (currentNode.EqualAtDepth(endNode.index, endNode.index.GetMaxDepth())) { if (endNodeOnSameLayer) { //retrace the path from the end node return(RetracePath(endNode, nodesToSearch)); } else { return(RetracePath(endNode.GetNode(currentNode), nodesToSearch)); } } //if the goal has not been found then add the nodes at the end of all connections to the open list, and close the current node foreach (Connection edge in nodesToSearch[currentNode.GetLowestIndex()].connections) { nextNode = edge.destination; //ignore if the node has already been closed if (!closedList.Contains(nextNode)) { //calculate the cost by looking at the accumulated cost, the connection cost, and the heuristic float totalCost = Math.Abs(nodesToSearch[currentNode.GetLowestIndex()].accumulatedCost + edge.traversalCost + fullAIGraph.topLevelNode.GetNode(nextNode).GetHeuristic(fullAIGraph.goalCoords)); Node tempNode = GetNodeFromLists(nextNode, nodesToSearch, endNode.internalNodes); if (tempNode != null) { //if the node is not currently in the open list then add it to the open list if (!openList.Contains(nextNode)) { openList.Add(nextNode); //set the parent Id and the current cost tempNode.previousNode = currentNode; tempNode.accumulatedCost = totalCost; } //update the node in the list if the new path is faster else if (tempNode.accumulatedCost > totalCost) { //set the parent Id and the current cost tempNode.previousNode = currentNode; tempNode.accumulatedCost = totalCost; } } } } closedList.Add(currentNode); openList.Remove(currentNode); } return(null); // If the goal is not found, return null }