Example #1
0
    private PathWaypoint generateIdlePath(SortedVector2List <Platform> platforms, CollidableObj obj, AI ai, int jumpStrength, int xVelocity, float gravity, PathWaypoint curWapoint = null)
    {
        ConnectivityNode curNode = null;

        if (curWapoint != null && !(connectivityGraph.ContainsKey((int)curWapoint.position.X) && connectivityGraph[(int)curWapoint.position.X].ContainsKey((int)curWapoint.position.Y)))
        {
            curWapoint = null;
        }
        if (curWapoint != null)
        {
            curNode = connectivityGraph[(int)curWapoint.position.X][(int)curWapoint.position.Y];
        }

        if (curNode == null)
        {
            List <Vector2> res = getClosestNodeKeyForPosition(platforms, obj, obj.Position, obj.Position, gravity, xVelocity, jumpStrength);
            if (res == null)
            {
                return(null);
            }
            foreach (Vector2 v in res)
            {
                if (ai.inBoundingBox(v))
                {
                    return(new PathWaypoint(v, null, PathType.Free));
                }
            }
        }

        List <PathWaypoint> waypoints = new List <PathWaypoint> {
            new PathWaypoint(new Vector2(obj.Position.X, obj.getBot()), null, PathType.Free)
        };

        if (curNode != null)
        {
            foreach (ConnectivityPath path in curNode.connections)
            {
                if (ai.inBoundingBox(path.endNode.position))
                {
                    bool jumpPath     = path.jumpPath && path.jumpableStrengths[jumpStrength] && path.minXVel(jumpStrength, 0.15f) <= xVelocity;
                    bool straightPath = path.straightPath && path.minXVel(0, 0.15f) <= xVelocity;
                    if (straightPath)
                    {
                        waypoints.Add(new PathWaypoint(path.endNode.position, null, PathType.Straight));
                    }
                    if (jumpPath)
                    {
                        waypoints.Add(new PathWaypoint(path.endNode.position, null, PathType.Jump));
                    }
                }
            }
        }

        return(waypoints[new Random().Next(waypoints.Count)]);
    }
Example #2
0
    private List <Vector2> getClosestNodeKeyForPosition(SortedVector2List <Platform> platforms, CollidableObj obj, Vector2 pos, Vector2 goal, float gravity, int xVelocity, int?jumpStrength = null)
    {
        if (connectivityGraph.Count == 0)
        {
            return(null);
        }

        int maxSearchRange = MAX_NODE_SEARCH_RANGE;

        if (jumpStrength != null)
        {
            maxSearchRange = (int)(Math.Pow((int)jumpStrength, 2) / gravity) / 2;
        }

        Vector2 ret   = new Vector2(0, 1);
        int     begin = 0;
        int     end   = connectivityGraph.Count;

        while (!(pos.X <= connectivityGraph.Keys[begin + (end - begin) / 2] && pos.X >= connectivityGraph.Keys[begin + (end - begin) / 2 - 1] ||
                 pos.X >= connectivityGraph.Keys[begin + (end - begin) / 2] && pos.X <= connectivityGraph.Keys[begin + (end - begin) / 2 + 1]))
        {
            if (pos.X > connectivityGraph.Keys[begin + (end - begin) / 2])
            {
                begin = begin + (end - begin) / 2 + 1;
            }
            else
            {
                end = begin + (end - begin) / 2;
            }
        }

        int i;

        if (pos.X < connectivityGraph.Keys[begin + (end - begin) / 2])
        {
            if (Math.Abs(pos.X - connectivityGraph.Keys[begin + (end - begin) / 2]) < Math.Abs(pos.X - connectivityGraph.Keys[begin + (end - begin) / 2 - 1]))
            {
                i = begin + (end - begin) / 2;
            }
            else
            {
                i = begin + (end - begin) / 2 - 1;
            }
        }
        else if (Math.Abs(pos.X - connectivityGraph.Keys[begin + (end - begin) / 2]) < Math.Abs(pos.X - connectivityGraph.Keys[begin + (end - begin) / 2 + 1]))
        {
            i = begin + (end - begin) / 2;
        }
        else
        {
            i = begin + (end - begin) / 2 + 1;
        }
        ret.X = connectivityGraph.Keys[i];
        int prevXIndex = i - 1;
        int postXIndex = i + 1;

        int lowXBound  = (int)(pos.X - Math.Sqrt(maxSearchRange * 2 / gravity) * xVelocity);
        int highXBound = (int)(pos.X + Math.Sqrt(maxSearchRange * 2 / gravity) * xVelocity);
        MinHeap <Tuple <float, Vector2> > bestNodes = new MinHeap <Tuple <float, Vector2> >(delegate(Tuple <float, Vector2> n1, Tuple <float, Vector2> n2)
        {
            if (n1.Item1 < n2.Item1)
            {
                return(-1);
            }
            else if (n1.Item1 == n2.Item1)
            {
                return(0);
            }
            else
            {
                return(1);
            }
        });

        while (true)
        {
            begin = 0;
            end   = connectivityGraph[(int)ret.X].Count;
            if ((end == 1 || end == 2) && obj.getBot(pos) <= connectivityGraph[(int)ret.X].Keys[0])
            {
                ret.Y = connectivityGraph[(int)ret.X].Keys[0];
            }
            else if (end == 2 && obj.getBot(pos) <= connectivityGraph[(int)ret.X].Keys[1])
            {
                ret.Y = connectivityGraph[(int)ret.X].Keys[1];
            }
            else
            {
                while (begin + (end - begin) / 2 != 0 &&
                       begin + (end - begin) / 2 + 1 != connectivityGraph[(int)ret.X].Count &&
                       !(obj.getBot(pos) <= connectivityGraph[(int)ret.X].Keys[begin + (end - begin) / 2] && obj.getBot(pos) >= connectivityGraph[(int)ret.X].Keys[begin + (end - begin) / 2 - 1] ||
                         obj.getBot(pos) >= connectivityGraph[(int)ret.X].Keys[begin + (end - begin) / 2] && obj.getBot(pos) <= connectivityGraph[(int)ret.X].Keys[begin + (end - begin) / 2 + 1]))
                {
                    if (obj.getBot(pos) > connectivityGraph[(int)ret.X].Keys[begin + (end - begin) / 2])
                    {
                        begin = begin + (end - begin) / 2 + 1;
                    }
                    else
                    {
                        end = begin + (end - begin) / 2;
                    }
                }

                if (begin + (end - begin) / 2 + 1 != connectivityGraph[(int)ret.X].Count)
                {
                    if (obj.getBot(pos) < connectivityGraph[(int)ret.X].Keys[begin + (end - begin) / 2])
                    {
                        ret.Y = connectivityGraph[(int)ret.X].Keys[begin + (end - begin) / 2];
                    }
                    else
                    {
                        ret.Y = connectivityGraph[(int)ret.X].Keys[begin + (end - begin) / 2 + 1];
                    }
                }
            }

            if (ret.Y != 1 &&
                straightable(platforms, new Vector2(pos.X, obj.getBot(pos)), ret) &&
                straightable(platforms, new Vector2(obj.getLeft(pos), pos.Y), new Vector2(obj.getLeft(pos), ret.Y + (pos.Y - obj.getBot(pos)))) &&
                straightable(platforms, new Vector2(obj.getRight(pos), pos.Y), new Vector2(obj.getRight(pos), ret.Y + (pos.Y - obj.getBot(pos)))) &&
                straightable(platforms, new Vector2(pos.X, obj.getTop(pos)), new Vector2(ret.X, ret.Y + (obj.getTop(pos) - obj.getBot(pos)))) &&
                (obj.getBot(pos) == ret.Y && (straightable(platforms, new Vector2(obj.getLeft(pos), obj.getBot(pos)), ret, true) || straightable(platforms, new Vector2(obj.getRight(pos), obj.getBot(pos)), ret, true)) ||
                 Math.Sqrt(Math.Abs(obj.getBot(pos) - ret.Y) * 2 / gravity) * xVelocity > Math.Abs(pos.X - ret.X) && Math.Abs(obj.getBot(pos) - ret.Y) < maxSearchRange))
            {
                bestNodes.add(new Tuple <float, Vector2>((float)Math.Sqrt(Math.Abs(pos.X - ret.Y) * 2 / gravity) + distance(ret, goal), ret));
            }
            ret.Y = 1;

            if (prevXIndex == -1 && (postXIndex == connectivityGraph.Keys.Count || connectivityGraph.Keys[postXIndex] > highXBound) ||
                prevXIndex != -1 && connectivityGraph.Keys[prevXIndex] < lowXBound && (postXIndex == connectivityGraph.Keys.Count || connectivityGraph.Keys[postXIndex] > highXBound))
            {
                if (!bestNodes.empty())
                {
                    List <Vector2> retList = new List <Vector2>();
                    while (!bestNodes.empty())
                    {
                        retList.Add(bestNodes.peek().Item2);
                        bestNodes.pop();
                    }
                    return(retList);
                }
                else
                {
                    return(null);
                }
            }

            if (prevXIndex == -1 || connectivityGraph.Keys[prevXIndex] < lowXBound)
            {
                ret.X = connectivityGraph.Keys[postXIndex++];
            }
            else if (postXIndex == connectivityGraph.Keys.Count || connectivityGraph.Keys[postXIndex] > highXBound)
            {
                ret.X = connectivityGraph.Keys[prevXIndex--];
            }
            else if (Math.Abs(pos.X - connectivityGraph.Keys[prevXIndex]) < Math.Abs(pos.X - connectivityGraph.Keys[postXIndex]))
            {
                ret.X = connectivityGraph.Keys[prevXIndex--];
            }
            else
            {
                ret.X = connectivityGraph.Keys[postXIndex++];
            }
        }
    }
Example #3
0
    private PathWaypoint getPath(SortedVector2List <Platform> platforms, CollidableObj start, CollidableObj end, int jumpStrength, int xVelocity, float gravity, PathWaypoint curWapoint = null)
    {
        Dictionary <Vector2, ConnectivityNodeWrapper> exploredSet = new Dictionary <Vector2, ConnectivityNodeWrapper>();
        Dictionary <Vector2, ConnectivityNodeWrapper> openSet     = new Dictionary <Vector2, ConnectivityNodeWrapper>();

        MinHeap <ConnectivityNodeWrapper> queue = new MinHeap <ConnectivityNodeWrapper>(delegate(ConnectivityNodeWrapper n1, ConnectivityNodeWrapper n2)
        {
            if (n1.heurisitc < n2.heurisitc)
            {
                return(-1);
            }
            else if (n1.heurisitc == n2.heurisitc)
            {
                return(0);
            }
            else
            {
                return(1);
            }
        });

        List <Vector2>          res;
        ConnectivityNodeWrapper curNode;

        if (curWapoint != null && !(connectivityGraph.ContainsKey((int)curWapoint.position.X) && connectivityGraph[(int)curWapoint.position.X].ContainsKey((int)curWapoint.position.Y)))
        {
            curWapoint = null;
        }
        if (curWapoint != null)
        {
            curNode = new ConnectivityNodeWrapper(connectivityGraph[(int)curWapoint.position.X][(int)curWapoint.position.Y], calculateHeuristic(curWapoint.position, end.Position, xVelocity, jumpStrength));
        }
        else
        {
            res = getClosestNodeKeyForPosition(platforms, start, start.Position, end.Position, gravity, xVelocity);
            if (res == null)
            {
                return(null);
            }
            foreach (Vector2 vec in res)
            {
                ConnectivityNodeWrapper cnw = new ConnectivityNodeWrapper(connectivityGraph[(int)vec.X][(int)vec.Y], calculateHeuristic(vec, end.Position, xVelocity, jumpStrength));
                queue.add(cnw);
                openSet.Add(cnw.node.position, cnw);
            }
            curNode = queue.peek();
            queue.pop();
            openSet.Remove(curNode.node.position);
        }


        res = getClosestNodeKeyForPosition(platforms, end, end.Position, end.Position, gravity, xVelocity, jumpStrength);
        if (res == null)
        {
            return(null);
        }
        ConnectivityNode endNode = connectivityGraph[(int)res[0].X][(int)res[0].Y];

        int it = 0;

        while (curNode != endNode)
        {
            foreach (ConnectivityPath path in curNode.node.connections)
            {
                if (!exploredSet.ContainsKey(path.endNode.position))
                {
                    bool jumpPath     = path.jumpPath && path.jumpableStrengths[jumpStrength] && path.minXVel(jumpStrength, gravity) <= xVelocity;
                    bool straightPath = path.straightPath && (path.minXVel(0, gravity) <= xVelocity || path.walkable);
                    if (straightPath)
                    {
                        float h = calculateHeuristic(path.endNode.position, endNode.position, xVelocity, jumpStrength);
                        if (!openSet.ContainsKey(path.endNode.position))
                        {
                            ConnectivityNodeWrapper cnw = new ConnectivityNodeWrapper(path.endNode, path.getStraightPathCost(xVelocity, gravity), h, curNode, PathType.Straight);
                            queue.add(cnw);
                            openSet.Add(cnw.node.position, cnw);
                        }
                        else if (openSet[path.endNode.position].heurisitc > h)
                        {
                            ConnectivityNodeWrapper cnw = new ConnectivityNodeWrapper(path.endNode, path.getStraightPathCost(xVelocity, gravity), h, curNode, PathType.Straight);
                            queue.add(cnw);
                            openSet[path.endNode.position] = cnw;
                        }
                    }
                    else if (jumpPath)
                    {
                        queue.add(new ConnectivityNodeWrapper(path.endNode, path.jumpCosts[jumpStrength], calculateHeuristic(path.endNode.position, endNode.position, xVelocity, jumpStrength), curNode, PathType.Jump));
                    }
                }
            }
            exploredSet.Add(curNode.node.position, curNode);

            ++it;
            if (it == 20)
            {
                return(null);
            }

            do
            {
                if (queue.empty())
                {
                    return(null);
                }
                curNode = queue.peek();
                queue.pop();
            } while (exploredSet.ContainsKey(curNode.node.position));
        }

        PathWaypoint pathWaypoint = new PathWaypoint(new Vector2(end.Position.X, end.getBot()), null, PathType.Free);

        while (curNode != (object)null)
        {
            pathWaypoint = new PathWaypoint(curNode.node.position, pathWaypoint, curNode.pathType);
            curNode      = curNode.parent;
        }
        if (curWapoint != null)
        {
            pathWaypoint = pathWaypoint.nextWaypoint;
        }
        return(pathWaypoint);
    }