示例#1
0
        private static bool GetSlopeEdge(
            ref BallCollision.TileEdges edgesToTest,
            Tile tile,
            Vector2 tilePosition,
            ref LineSegment edge)
        {
            switch (tile.slope())
            {
            case 0:
                return(false);

            case 1:
                edgesToTest &= BallCollision.TileEdges.Bottom | BallCollision.TileEdges.Left | BallCollision.TileEdges.BottomLeftSlope;
                if ((edgesToTest & BallCollision.TileEdges.BottomLeftSlope) == BallCollision.TileEdges.None)
                {
                    return(false);
                }
                edge.Start = tilePosition;
                edge.End   = new Vector2(tilePosition.X + 16f, tilePosition.Y + 16f);
                return(true);

            case 2:
                edgesToTest &= BallCollision.TileEdges.Bottom | BallCollision.TileEdges.Right | BallCollision.TileEdges.BottomRightSlope;
                if ((edgesToTest & BallCollision.TileEdges.BottomRightSlope) == BallCollision.TileEdges.None)
                {
                    return(false);
                }
                edge.Start = new Vector2(tilePosition.X, tilePosition.Y + 16f);
                edge.End   = new Vector2(tilePosition.X + 16f, tilePosition.Y);
                return(true);

            case 3:
                edgesToTest &= BallCollision.TileEdges.Top | BallCollision.TileEdges.Left | BallCollision.TileEdges.TopLeftSlope;
                if ((edgesToTest & BallCollision.TileEdges.TopLeftSlope) == BallCollision.TileEdges.None)
                {
                    return(false);
                }
                edge.Start = new Vector2(tilePosition.X, tilePosition.Y + 16f);
                edge.End   = new Vector2(tilePosition.X + 16f, tilePosition.Y);
                return(true);

            case 4:
                edgesToTest &= BallCollision.TileEdges.Top | BallCollision.TileEdges.Right | BallCollision.TileEdges.TopRightSlope;
                if ((edgesToTest & BallCollision.TileEdges.TopRightSlope) == BallCollision.TileEdges.None)
                {
                    return(false);
                }
                edge.Start = tilePosition;
                edge.End   = new Vector2(tilePosition.X + 16f, tilePosition.Y + 16f);
                return(true);

            default:
                return(false);
            }
        }
示例#2
0
        private static bool GetCollisionPointForTile(
            BallCollision.TileEdges edgesToTest,
            int x,
            int y,
            Vector2 center,
            ref Vector2 closestPointOut,
            ref float distanceSquaredOut)
        {
            Tile tile = Main.tile[x, y];

            if (tile == null || !tile.nactive() || !Main.tileSolid[(int)tile.type] && !Main.tileSolidTop[(int)tile.type] || !Main.tileSolid[(int)tile.type] && Main.tileSolidTop[(int)tile.type] && tile.frameY != (short)0)
            {
                return(false);
            }
            if (Main.tileSolidTop[(int)tile.type])
            {
                edgesToTest &= BallCollision.TileEdges.Top | BallCollision.TileEdges.BottomLeftSlope | BallCollision.TileEdges.BottomRightSlope;
            }
            Vector2     tilePosition = new Vector2((float)x * 16f, (float)y * 16f);
            bool        flag         = false;
            LineSegment edge         = new LineSegment();

            if (BallCollision.GetSlopeEdge(ref edgesToTest, tile, tilePosition, ref edge))
            {
                closestPointOut    = BallCollision.ClosestPointOnLineSegment(center, edge);
                distanceSquaredOut = Vector2.DistanceSquared(closestPointOut, center);
                flag = true;
            }
            if (BallCollision.GetTopOrBottomEdge(edgesToTest, x, y, tilePosition, ref edge))
            {
                Vector2 vector2 = BallCollision.ClosestPointOnLineSegment(center, edge);
                float   num     = Vector2.DistanceSquared(vector2, center);
                if (!flag || (double)num < (double)distanceSquaredOut)
                {
                    distanceSquaredOut = num;
                    closestPointOut    = vector2;
                }
                flag = true;
            }
            if (BallCollision.GetLeftOrRightEdge(edgesToTest, x, y, tilePosition, ref edge))
            {
                Vector2 vector2 = BallCollision.ClosestPointOnLineSegment(center, edge);
                float   num     = Vector2.DistanceSquared(vector2, center);
                if (!flag || (double)num < (double)distanceSquaredOut)
                {
                    distanceSquaredOut = num;
                    closestPointOut    = vector2;
                }
                flag = true;
            }
            return(flag);
        }
示例#3
0
        private static bool GetLeftOrRightEdge(
            BallCollision.TileEdges edgesToTest,
            int x,
            int y,
            Vector2 tilePosition,
            ref LineSegment edge)
        {
            if ((edgesToTest & BallCollision.TileEdges.Left) != BallCollision.TileEdges.None)
            {
                Tile tile1 = Main.tile[x, y];
                Tile tile2 = Main.tile[x - 1, y];
                if ((!BallCollision.IsNeighborSolid(tile2) || tile2.slope() == (byte)1 || tile2.slope() == (byte)3 ? 1 : (!tile2.halfBrick() ? 0 : (!tile1.halfBrick() ? 1 : 0))) == 0)
                {
                    return(false);
                }
                edge.Start = new Vector2(tilePosition.X, tilePosition.Y);
                edge.End   = new Vector2(tilePosition.X, tilePosition.Y + 16f);
                if (tile1.halfBrick())
                {
                    edge.Start.Y += 8f;
                }
                return(true);
            }
            if ((edgesToTest & BallCollision.TileEdges.Right) == BallCollision.TileEdges.None)
            {
                return(false);
            }
            Tile tile3 = Main.tile[x, y];
            Tile tile4 = Main.tile[x + 1, y];

            if ((!BallCollision.IsNeighborSolid(tile4) || tile4.slope() == (byte)2 || tile4.slope() == (byte)4 ? 1 : (!tile4.halfBrick() ? 0 : (!tile3.halfBrick() ? 1 : 0))) == 0)
            {
                return(false);
            }
            edge.Start = new Vector2(tilePosition.X + 16f, tilePosition.Y);
            edge.End   = new Vector2(tilePosition.X + 16f, tilePosition.Y + 16f);
            if (tile3.halfBrick())
            {
                edge.Start.Y += 8f;
            }
            return(true);
        }
示例#4
0
        private static bool GetClosestEdgeToCircle(
            Vector2 position,
            Vector2 size,
            Vector2 velocity,
            out Vector2 collisionPoint,
            out Tile collisionTile)
        {
            Rectangle tileBounds = BallCollision.GetTileBounds(position, size);
            Vector2   center     = position + size * 0.5f;

            BallCollision.TileEdges tileEdges1  = BallCollision.TileEdges.None;
            BallCollision.TileEdges tileEdges2  = (double)velocity.Y >= 0.0 ? tileEdges1 | BallCollision.TileEdges.Top : tileEdges1 | BallCollision.TileEdges.Bottom;
            BallCollision.TileEdges tileEdges3  = (double)velocity.X >= 0.0 ? tileEdges2 | BallCollision.TileEdges.Left : tileEdges2 | BallCollision.TileEdges.Right;
            BallCollision.TileEdges tileEdges4  = (double)velocity.Y <= (double)velocity.X ? tileEdges3 | BallCollision.TileEdges.TopRightSlope : tileEdges3 | BallCollision.TileEdges.BottomLeftSlope;
            BallCollision.TileEdges edgesToTest = (double)velocity.Y <= -(double)velocity.X ? tileEdges4 | BallCollision.TileEdges.TopLeftSlope : tileEdges4 | BallCollision.TileEdges.BottomRightSlope;
            collisionPoint = Vector2.Zero;
            collisionTile  = (Tile)null;
            float   num1               = float.MaxValue;
            Vector2 closestPointOut    = new Vector2();
            float   distanceSquaredOut = 0.0f;

            for (int left = tileBounds.Left; left < tileBounds.Right; ++left)
            {
                for (int top = tileBounds.Top; top < tileBounds.Bottom; ++top)
                {
                    if (BallCollision.GetCollisionPointForTile(edgesToTest, left, top, center, ref closestPointOut, ref distanceSquaredOut) && (double)distanceSquaredOut < (double)num1 && (double)Vector2.Dot(velocity, center - closestPointOut) <= 0.0)
                    {
                        num1           = distanceSquaredOut;
                        collisionPoint = closestPointOut;
                        collisionTile  = Main.tile[left, top];
                    }
                }
            }
            float num2 = size.X / 2f;

            return((double)num1 < (double)num2 * (double)num2);
        }
示例#5
0
        private static bool GetTopOrBottomEdge(
            BallCollision.TileEdges edgesToTest,
            int x,
            int y,
            Vector2 tilePosition,
            ref LineSegment edge)
        {
            if ((edgesToTest & BallCollision.TileEdges.Bottom) != BallCollision.TileEdges.None)
            {
                Tile tile = Main.tile[x, y + 1];
                if ((!BallCollision.IsNeighborSolid(tile) || tile.slope() == (byte)1 || tile.slope() == (byte)2 ? 1 : (tile.halfBrick() ? 1 : 0)) == 0)
                {
                    return(false);
                }
                edge.Start = new Vector2(tilePosition.X, tilePosition.Y + 16f);
                edge.End   = new Vector2(tilePosition.X + 16f, tilePosition.Y + 16f);
                return(true);
            }
            if ((edgesToTest & BallCollision.TileEdges.Top) == BallCollision.TileEdges.None)
            {
                return(false);
            }
            Tile tile1 = Main.tile[x, y - 1];

            if ((Main.tile[x, y].halfBrick() || !BallCollision.IsNeighborSolid(tile1) || tile1.slope() == (byte)3 ? 1 : (tile1.slope() == (byte)4 ? 1 : 0)) == 0)
            {
                return(false);
            }
            if (Main.tile[x, y].halfBrick())
            {
                tilePosition.Y += 8f;
            }
            edge.Start = new Vector2(tilePosition.X, tilePosition.Y);
            edge.End   = new Vector2(tilePosition.X + 16f, tilePosition.Y);
            return(true);
        }