public bool CheckAABBCollision(AABB rect)
 {
     //return !(rect.y1 > y2 || rect.x1 > x2 || rect.x2 < x1 || rect.y2 < y1);
     if (rect.y1 > y2) return false;
     if (rect.x1 > x2) return false;
     if (rect.x2 < x1) return false;
     if (rect.y2 < y1) return false;
     return true;
 }
        public Vector2 SolveCollision(AABB rect)
        {
            // If the two AABBs don't collide, do nothing:
            //if (rect.y1 > y2) return Vector2.Zero;
            //if (rect.x1 > x2) return Vector2.Zero;
            //if (rect.x2 < x1) return Vector2.Zero;
            //if (rect.y2 < y1) return Vector2.Zero;
            if (!CheckAABBCollision(rect)) return Vector2.Zero;

            float Y1 = y1 - rect.y2; // distance to move object up
            float X1 = x1 - rect.x2; // distance to move object left
            float X2 = x2 - rect.x1; // distance to move object right
            float Y2 = y2 - rect.y1; // distance to move object down

            float aX1 = Math.Abs(X1);
            float aX2 = Math.Abs(X2);
            float aY1 = Math.Abs(Y1);
            float aY2 = Math.Abs(Y2);

            /*
            // Allow player to go up stairs!!
            if (!omitTop && (!omitLeft || !omitRight) && aY1 < Level.collisionSize.Y * 1.5) {
                if (rect.physObj != null) {
                    Line path = rect.physObj.GetMovementPath();
                    if (Math.Abs(path.nx) >= .25) {
                        return new Vector2(0, Y1);
                    }
                }
            }
            */

            if (incline)
            {
                if (aY1 <= aX1 && aY1 <= aX2 && aY1 <= aY2) return omitTop ? Vector2.Zero : new Vector2(0, Y1); // move up
                if (aX1 <= aY1 && aX1 <= aY2 && aX1 <= aX2) return omitLeft ? Vector2.Zero : new Vector2(X1, 0); // move left
                if (aX2 <= aY1 && aX2 <= aY2 && aX2 <= aX1) return omitRight ? Vector2.Zero : new Vector2(X2, 0); // more right
                if (aY2 <= aX1 && aY2 <= aX2 && aY2 <= aY1) return omitBottom ? Vector2.Zero : new Vector2(0, Y2); // move down
            }
            else
            {
                if (aY1 <= aX1 && aY1 <= aX2 && aY1 <= aY2) if (!omitTop) return new Vector2(0, Y1); // move up
                if (aX1 <= aY1 && aX1 <= aY2 && aX1 <= aX2) if (!omitLeft) return new Vector2(X1, 0); // move left
                if (aX2 <= aY1 && aX2 <= aY2 && aX2 <= aX1) if (!omitRight) return new Vector2(X2, 0); // more right
                if (aY2 <= aX1 && aY2 <= aX2 && aY2 <= aY1) if (!omitBottom) return new Vector2(0, Y2); // move down
            }

            return Vector2.Zero;
        }
Beispiel #3
0
        public static void CheckEnvironment(PhysObj obj)
        {
            Point cornerTopLeft = PositionToGrid(new Vector2(obj.hitBox.Left(), obj.hitBox.Top()));
            Point cornerBottomRight = PositionToGrid(new Vector2(obj.hitBox.Right(), obj.hitBox.Bottom()));
            bool collision = false;
            float friction = obj.frictionMultiplier;
            List<AABB> collisionList = new List<AABB>();
            List<float> frictionList = new List<float>();
            for (int y = cornerTopLeft.Y; y <= cornerBottomRight.Y; y++)
            {
                for (int x = cornerTopLeft.X; x <= cornerBottomRight.X; x++)
                {
                    if (CheckCollision(new Point(x, y)))
                    {
                        AABB aabb = new AABB(null, GridToPosition(new Point(x, y)), new Vector2(collisionSize));
                        if (environmentData[x, y].inclineType != InclineType.Flat)
                        {
                            aabb = SolveIncline(obj, x, y);

                        }
                        if (environmentData[x, y].oneWayPlatform)
                        {
                            aabb.omitLeft = true;
                            aabb.omitRight = true;
                            aabb.omitBottom = true;
                            if (obj.speed.Y < 0 || obj.ignoreOneWay)
                            {
                                aabb.omitTop = true;
                            }
                        }

                        if ((CheckCollision(x - 1, y) && !environmentData[x - 1, y].oneWayPlatform) || environmentData[x, y].omitLeft) aabb.omitLeft = true;
                        if ((CheckCollision(x + 1, y) && !environmentData[x + 1, y].oneWayPlatform) || environmentData[x, y].omitRight) aabb.omitRight = true;
                        if ((CheckCollision(x, y + 1) && !environmentData[x, y + 1].oneWayPlatform) || environmentData[x, y].omitBottom) aabb.omitBottom = true;
                        if ((CheckCollision(x, y - 1) && !environmentData[x, y - 1].oneWayPlatform) || environmentData[x, y].omitTop) aabb.omitTop = true;

                        //if (CheckCollision(x - 1, y) && environmentData[x,y].inclineType == InclineType.Flat)
                        //{
                        //    if (environmentData[x - 1, y].inclineType != InclineType.Flat && (obj.position.X > aabb.x1 && obj.position.X < aabb.x2)) aabb.omitTop = true;
                        //}

                        collisionList.Add(aabb);
                        collision = true;
                        frictionList.Add(GetFriction(obj, environmentData[x, y]));
                    }

                    CheckCurrent(obj, x, y);

                    if (IsLegalXY(x,y) && environmentData[x, y].killZone)
                    {
                        obj.Die();
                    }

                }
            }

            Point checkBelow = PositionToGrid(new Vector2(obj.position.X, obj.hitBox.Bottom() + 1));
            if (CheckCollision(checkBelow))
            {
                if (environmentData[checkBelow.X, checkBelow.Y].inclineType != InclineType.Flat)
                {
                    //Trace.WriteLine("Barf!");
                    if (!obj.jumpingLegacy)
                    {
                        //AABB aabb = new AABB(null, GridToPosition(checkBelow), new Vector2(collisionSize));
                        //aabb = SolveIncline(obj, checkBelow.X, checkBelow.Y);
                        //obj.hitBox.SetPosition(obj.hitBox.GetPosition() + new Vector2(0, aabb.y2 - obj.hitBox.Bottom()));
                        //collisionList.Add(aabb);
                        //frictionList.Add(GetFriction(obj, environmentData[checkBelow.X, checkBelow.Y]));
                        obj.nextForce.Y += 20;
                    }
                }
            }

            //int y1 = cornerBottomRight.Y + 1;
            //for (int x = cornerTopLeft.X; x <= cornerBottomRight.X; x++)
            //{
            //    if (CheckCollision(x, y1))
            //    {
            //        AABB aabb = new AABB(null, GridToPosition(new Point(x, y1)), new Vector2(collisionSize));
            //        if (environmentData[x, y1].inclineType != InclineType.Flat)
            //        {
            //            obj.position += new Vector2(0, 32);
            //            collisionList.Add(aabb);
            //            frictionList.Add(GetFriction(obj, environmentData[x, y1]));
            //        }
            //    }
            //}

            //if (collision == false)
            //{
            //    if (obj.state == PhysState.Grounded)
            //{ //check to see if there's ground beneath the object:

            //Point under = PositionToGrid(obj.tempPosition);
            //under.Y += 1;
            //if (CheckCollision(under.X, under.Y))
            //{
            //    collision = true;
            //}
            //if (!collision) obj.state = PhysState.Air;

            //int y = cornerBottomRight.Y + 1;
            //for (int x = cornerTopLeft.X; x < cornerBottomRight.X; x++)
            //{
            //    if (CheckCollision(x, y))
            //    {
            //        collision = true;
            //        break;
            //    }
            //}
            //if (!collision) obj.state = PhysState.Air;
            //    }
            //    return;
            //}

            foreach (AABB aabb in collisionList)
            {
                Vector2 solution = aabb.SolveCollision(obj.hitBox.GetAABB());
                obj.hitBox.SetPosition(obj.hitBox.GetPosition() + solution);
                if (solution.Y < 0)
                {
                    friction = frictionList.ElementAt(collisionList.IndexOf(aabb));
                }
            }
            Vector2 newpos = obj.hitBox.GetPosition();
            if (newpos.Y != obj.tempPosition.Y) obj.speed.Y = SolveBounce(obj, true);
            if (newpos.X != obj.tempPosition.X) obj.speed.X = SolveBounce(obj, false);
            if (newpos.Y < obj.tempPosition.Y)
            {
                obj.state = PhysState.Grounded;
            }

            obj.tempPosition = newpos;

            if (obj.state == PhysState.Grounded)
            {
                obj.frictionMultiplier = friction;
                if (friction == EnvironmentData.NORMAL)
                {
                    obj.moveForce = 1;
                }
                else if (friction == EnvironmentData.ICE)
                {
                    obj.moveForce = .2f;
                }
            }
            else
            {
                obj.frictionMultiplier = EnvironmentData.AIR;
                obj.moveForce = .2f;
            }
        }
 public AABB GetAABB()
 {
     AABB aabb = new AABB(physObj, WorldCornerMin, Size);
     aabb.omitTop = omitTop;
     aabb.omitBottom = omitBottom;
     aabb.omitRight = omitRight;
     aabb.omitLeft = omitLeft;
     return aabb;
 }
Beispiel #5
0
 public static AABB SolveIncline(PhysObj obj, int x, int y)
 {
     bool omitTop = false;
     Vector2 cornerTopLeft = GridToPosition(new Point(x, y));
     Vector2 cornerBottomRight = cornerTopLeft + new Vector2(collisionSize);
     float thirdSize = collisionSize / 3;
     float halfSize = collisionSize / 2;
     switch (environmentData[x, y].inclineType)
     {
         case InclineType.ThreeTileRight1:
             float ratio = (cornerTopLeft.X - obj.tempPosition.X) / collisionSize;
             if (ratio > 0 || ratio < -1) omitTop = true;
             cornerTopLeft.Y = cornerBottomRight.Y + ratio * (thirdSize);
             break;
         case InclineType.ThreeTileRight2:
             ratio = (cornerTopLeft.X - obj.tempPosition.X) / collisionSize;
             cornerTopLeft.Y = cornerBottomRight.Y - (thirdSize) + ratio * (thirdSize);
             if (ratio > 0 || ratio < -1) omitTop = true;
             break;
         case InclineType.ThreeTileRight3:
             ratio = (cornerTopLeft.X - obj.tempPosition.X) / collisionSize;
             if (ratio > 0 || ratio < -1) omitTop = true;
             cornerTopLeft.Y = cornerBottomRight.Y - (2 * thirdSize) + ratio * (thirdSize);
             break;
         case InclineType.ThreeTileLeft1:
             ratio = (cornerTopLeft.X - obj.tempPosition.X) / collisionSize;
             if (ratio > 0 || ratio < -1) omitTop = true;
             cornerTopLeft.Y = cornerTopLeft.Y - ratio * (thirdSize);
             break;
         case InclineType.ThreeTileLeft2:
             ratio = (cornerTopLeft.X - obj.tempPosition.X) / collisionSize;
             //if (ratio > 0 || ratio < -1) omitTop = true;
             cornerTopLeft.Y = cornerTopLeft.Y + (thirdSize) - ratio * (thirdSize);
             break;
         case InclineType.ThreeTileLeft3:
             ratio = (cornerTopLeft.X - obj.tempPosition.X) / collisionSize;
             if (ratio > 0 || ratio < -1) omitTop = true;
             cornerTopLeft.Y = cornerTopLeft.Y + (2 * thirdSize) - ratio * (thirdSize);
             break;
         case InclineType.TwoTileRight1:
             ratio = (cornerTopLeft.X - obj.tempPosition.X) / collisionSize;
             if (ratio > 0 || ratio < -1) omitTop = true;
             cornerTopLeft.Y = cornerBottomRight.Y + ratio * (halfSize);
             break;
         case InclineType.TwoTileRight2:
             ratio = (cornerTopLeft.X - obj.tempPosition.X) / collisionSize;
             if (ratio > 0 || ratio < -1) omitTop = true;
             cornerTopLeft.Y = cornerBottomRight.Y - (halfSize) + ratio * (halfSize);
             break;
         case InclineType.TwoTileLeft1:
             ratio = (cornerTopLeft.X - obj.tempPosition.X) / collisionSize;
             if (ratio > 0 || ratio < -1) omitTop = true;
             cornerTopLeft.Y = cornerTopLeft.Y - ratio * (halfSize);
             break;
         case InclineType.TwoTileLeft2:
             ratio = (cornerTopLeft.X - obj.tempPosition.X) / collisionSize;
             if (ratio > 0 || ratio < -1) omitTop = true;
             cornerTopLeft.Y = cornerTopLeft.Y + (halfSize) - ratio * (halfSize);
             break;
     }
     AABB aabb = new AABB(null, cornerTopLeft.X, cornerTopLeft.Y, cornerBottomRight.X, cornerBottomRight.Y);
     aabb.omitLeft = true;
     aabb.omitRight = true;
     if (omitTop)
     {
         aabb.omitTop = true;
         aabb.omitBottom = true;
     }
     aabb.incline = true;
     return aabb;
 }