예제 #1
0
 public static WorldGraph GetWorldGraph()
 {
     if (worldGraphSingleton == null)
     {
         worldGraphSingleton = new WorldGraph();
     }
     return(worldGraphSingleton);
 }
예제 #2
0
        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);
        }
예제 #3
0
        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;
        }
예제 #4
0
        //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);
        }
예제 #5
0
        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
        }