示例#1
0
 private double[] getObjectMinMax(Vector2 axis, CollidableObj obj, float timeDisplacement = 0, bool useVelocity = false)
 {
     double[] ret = new double[2];
     for (int i = 0; i < obj.collisionArea.Count; ++i)
     {
         Vector2 p = obj.collisionArea[i] * new Vector2((int)obj.direction, 1) + obj.Position + (useVelocity ? obj.Velocity * timeDisplacement : new Vector2(0, 0));
         if (i == 0)
         {
             ret[0] = axis.X * p.X + axis.Y * p.Y;
             ret[1] = ret[0];
         }
         else
         {
             double curPointAxisMagnitude = axis.X * p.X + axis.Y * p.Y;
             if (curPointAxisMagnitude < ret[0])
             {
                 ret[0] = curPointAxisMagnitude;
             }
             else if (curPointAxisMagnitude > ret[1])
             {
                 ret[1] = curPointAxisMagnitude;
             }
         }
     }
     return(ret);
 }
示例#2
0
 public void collide(CollidableObj obj, List <Vector2>[] axis)
 {
     /*if (!(((BuffableObject)obj).useStat(StatTypes.Invincibility) > 0))
      * {
      *  ((Character)obj).takeDamage((float)useStat(StatTypes.Attack));
      *  obj.setVelocity(new Vector2(0, obj.Velocity.Y));
      *  obj.addVelocity(new Vector2((float)((Character)obj).calculateStat(StatTypes.Movement) * Math.Sign(obj.Position.X - Position.X), 0));
      *  obj.direction = (Direction)(-Math.Sign(obj.Position.X - Position.X));
      * }*/
 }
示例#3
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)]);
    }
示例#4
0
 public CollidableObj(CollidableObj obj)
 {
     Position      = obj.Position;
     Velocity      = obj.Velocity;
     direction     = obj.direction;
     collisionType = obj.collisionType;
     foreach (Vector2 vec in obj.collisionArea)
     {
         collisionArea.Add(vec);
     }
 }
示例#5
0
 public void setPath(PathWaypoint newPath, AIState state, CollidableObj obj = null)
 {
     timeSincePathUpdate = 0;
     path      = newPath;
     targetObj = obj;
     jumped    = false;
     if (this.state != AIState.Chasing && state == AIState.Chasing)
     {
         agroTimer      = 0;
         tiredIntervals = 1;
     }
     this.state = state;
 }
示例#6
0
 sealed public void collide(CollidableObj obj, List <Vector2>[] axis)
 {
     if (character != null && obj.collisionType == CollisionTypes.Enemy && attackID != null && !((Character)obj).getAttackedByID((TimeSpan)attackID))
     {
         Character target = (Character)obj;
         target.addAttackID((TimeSpan)attackID);
         target.takeDamage(character.useAttackDamage(target));
         if (target.calculateStat(StatTypes.Health) == 0)
         {
             character.addKillCount();
             character.useStat(StatTypes.Kills);
         }
         attackID = null;
     }
 }
示例#7
0
 public void collide(CollidableObj obj, List <Vector2>[] axis)
 {
     foreach (Vector2 vec in axis[0])
     {
         if (vec.X != 0)
         {
             deactivate();
             character.attack();
         }
     }
     if (axis[0].Count == 0)
     {
         deactivate();
         character.attack();
     }
 }
示例#8
0
    private List <Vector2> getCollisionAxis(CollidableObj obj, List <Vector2> foundAxis = null)
    {
        List <Vector2> axis = new List <Vector2>();

        for (int i = 0; i < obj.collisionArea.Count; ++i)
        {
            Vector2 p1        = obj.collisionArea[i] * new Vector2((int)obj.direction, 1) + obj.Position;
            Vector2 p2        = obj.collisionArea[(i == obj.collisionArea.Count - 1) ? 0 : i + 1] * new Vector2((int)obj.direction, 1) + obj.Position;
            float   xDif      = p1.X - p2.X;
            float   yDif      = p1.Y - p2.Y;
            double  magnitude = Math.Sqrt(Math.Pow(xDif, 2) + Math.Pow(yDif, 2));
            Vector2 curAxis   = new Vector2(-yDif / (float)magnitude, xDif / (float)magnitude);
            if (foundAxis != null && foundAxis.IndexOf(curAxis) == -1)
            {
                axis.Add(curAxis);
            }
        }
        return(axis);
    }
示例#9
0
 public void handleCollision(CollidableObj obj, float timeDisplacement)
 {
     List <Vector2>[] collisionAxis = hasCollision(obj, timeDisplacement);
     if (collisionAxis != null)
     {
         if (collisionType > obj.collisionType)
         {
             collide(obj, collisionAxis);
         }
         else if (collisionType < obj.collisionType)
         {
             obj.collide(this, collisionAxis);
         }
         else
         {
             collide(obj, collisionAxis);
             obj.collide(this, collisionAxis);
         }
     }
 }
示例#10
0
 public void collide(CollidableObj obj, List <Vector2>[] axis)
 {
 }
示例#11
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++];
            }
        }
    }
示例#12
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);
    }
示例#13
0
    public List <Vector2>[] hasCollision(CollidableObj obj, float timeDisplacement)
    {
        if (collisionArea.Count == 0 || obj.collisionArea.Count == 0)
        {
            return(null);
        }
        List <Vector2> axis = new List <Vector2>();

        axis.AddRange(getCollisionAxis(this));
        axis.AddRange(getCollisionAxis(obj, axis));

        foreach (Vector2 curAxis in axis)
        {
            double[] obj1MinMax        = getObjectMinMax(curAxis, this, timeDisplacement, true);
            double[] obj2MinMax        = getObjectMinMax(curAxis, obj, timeDisplacement, true);
            double[] preMoveObj1MinMax = getObjectMinMax(curAxis, this);
            double[] preMoveObj2MinMax = getObjectMinMax(curAxis, obj);

            if (preMoveObj1MinMax[0] > preMoveObj2MinMax[1] && obj1MinMax[1] < obj2MinMax[0] || // If obj1 min was greater then obj2 max and now obj1 max is less then obj2 min
                preMoveObj1MinMax[1] < preMoveObj2MinMax[0] && obj1MinMax[0] > obj2MinMax[1]    // If obj1 max was less then obj2 min and now obj1 min is greater then obj2 max
                //|| preMoveObj1MinMax[0] > preMoveObj2MinMax[0] && preMoveObj1MinMax[0] < preMoveObj2MinMax[1] // Obj1 min is colliding with obj2
                //|| preMoveObj1MinMax[1] > preMoveObj2MinMax[0] && preMoveObj1MinMax[1] < preMoveObj2MinMax[1] // Obj1 max is colliding with obj2
                )
            {
                continue;
            }
            if (obj1MinMax[0] > obj2MinMax[1] || obj1MinMax[1] < obj2MinMax[0])
            {
                return(null);
            }
        }
        List <Vector2>[] collisionAxis = new List <Vector2> [2];
        collisionAxis[0] = new List <Vector2>();
        // Distance to obj
        collisionAxis[1] = new List <Vector2>();
        foreach (Vector2 curAxis in axis)
        {
            double[] preMoveObj1MinMax = getObjectMinMax(curAxis, this);
            double[] preMoveObj2MinMax = getObjectMinMax(curAxis, obj);
            if (preMoveObj1MinMax[0] >= preMoveObj2MinMax[1] /* || obj1MinMax[1] < obj2MinMax[0]*/)
            {
                collisionAxis[0].Add(curAxis * new Vector2(-1, -1));
                float distance = (float)((preMoveObj1MinMax[0] >= preMoveObj2MinMax[1]) ? preMoveObj1MinMax[0] - preMoveObj2MinMax[1] : preMoveObj2MinMax[0] - preMoveObj1MinMax[1]);
                collisionAxis[1].Add(new Vector2(distance * curAxis.X, distance * curAxis.Y));
            }
        }

        if (collisionAxis[0].Count == 2)
        {
            if (obj.Velocity * collisionAxis[0][0] + collisionAxis[0][0] * this.Velocity != new Vector2() &&
                obj.Velocity * collisionAxis[0][1] + collisionAxis[0][1] * this.Velocity != new Vector2())
            {
                Vector2 axis0 = obj.Velocity * collisionAxis[0][0] + collisionAxis[0][0] * this.Velocity;
                Vector2 axis1 = obj.Velocity * collisionAxis[0][1] + collisionAxis[0][1] * this.Velocity;
                if (axis0.X != 0 && axis0.X > axis1.Y ||
                    axis0.Y != 0 && axis0.Y > axis1.X)
                {
                    collisionAxis[0].RemoveAt(0);
                    collisionAxis[1].RemoveAt(0);
                }
                else if (axis0 == axis1)
                {
                    if (axis0.X == 0)
                    {
                        collisionAxis[0].RemoveAt(1);
                        collisionAxis[1].RemoveAt(1);
                    }
                    else
                    {
                        collisionAxis[0].RemoveAt(0);
                        collisionAxis[1].RemoveAt(0);
                    }
                }
                else
                {
                    collisionAxis[0].RemoveAt(1);
                    collisionAxis[1].RemoveAt(1);
                }
                return(collisionAxis);
            }

            if (collisionAxis[1][0].X == 0 && collisionAxis[1][0].Y == 0 && obj.Velocity * collisionAxis[0][0] == new Vector2() && this.Velocity * collisionAxis[0][0] == new Vector2() ||
                collisionAxis[1][1].X == 0 && collisionAxis[1][1].Y == 0 && obj.Velocity * collisionAxis[0][1] == new Vector2() && this.Velocity * collisionAxis[0][1] == new Vector2())
            {
                for (int i = collisionAxis[0].Count - 1; i >= 0; --i)
                {
                    if (obj.Velocity * collisionAxis[0][i] != new Vector2() || this.Velocity * collisionAxis[0][i] != new Vector2())
                    {
                        collisionAxis[0].RemoveAt(i);
                        collisionAxis[1].RemoveAt(i);
                    }
                }
            }
            return((collisionAxis[0].Count > 0) ? collisionAxis : null);
        }
        return(collisionAxis);
    }