Пример #1
0
        public static FloatRectangle Intersect(FloatRectangle source, FloatRectangle target)
        {
            float sourceOffsetX  = source.X + source.Width;
            float targetOffsetX  = target.X + target.Width;
            float sourceOffsetY  = source.Y + source.Height;
            float targetOffsetY  = target.Y + target.Height;
            float highestX       = source.X > target.X ? source.X : target.X;
            float highestY       = source.Y > target.Y ? source.Y : target.Y;
            float highestOffsetX = sourceOffsetX < targetOffsetX ? sourceOffsetX : targetOffsetX;
            float highestOffsetY = sourceOffsetY < targetOffsetY ? sourceOffsetY : targetOffsetY;

            FloatRectangle rectangle;

            if (highestOffsetX > highestX && highestOffsetY > highestY)
            {
                rectangle.X      = highestX;
                rectangle.Y      = highestY;
                rectangle.Width  = highestOffsetX - highestX;
                rectangle.Height = highestOffsetY - highestY;
            }
            else
            {
                rectangle.X      = 0;
                rectangle.Y      = 0;
                rectangle.Width  = 0;
                rectangle.Height = 0;
            }
            return(rectangle);
        }
Пример #2
0
        public IList<Tile> Intersect(FloatRectangle bounds)
        {
            IList<Tile> intersection = new List<Tile>();

            // calculate possible tile bounds to improve performance.
            int colStart = Math.Max(0, (int)bounds.Left / Tile.Width - 1);
            int colItems = (int)bounds.Width / Tile.Width + 2;
            int colLength = Math.Min(Tiles.GetLength(0), colStart + colItems + 1);

            int rowStart = Math.Max(0, (int)bounds.Top / Tile.Height - 1);
            int rowItems = (int)bounds.Height / Tile.Height + 2;
            int rowLength = Math.Min(Tiles.GetLength(1), rowStart + rowItems + 1);

            for (int x = colStart; x < colLength; x++)
            {
                for (int y = rowStart; y < rowLength; y++)
                {
                    Tile tile = Tiles[x, y];

                    var intersects = bounds.Intersects(tile.Bounds);
                    if (intersects)
                    {
                        intersection.Add(tile);
                    }
                }
            }

            return intersection;
        }
Пример #3
0
        public virtual MoveResult CanMove(FloatRectangle bounds, Vector2 interpolation, DetectionType detectionType)
        {
            FloatRectangle xTarget = bounds.Displace(interpolation * Direction.Right);
            FloatRectangle yTarget = bounds.Displace(interpolation * Direction.Down);
            FloatRectangle target = bounds.Displace(interpolation);

            return CanMove(bounds, interpolation, detectionType, xTarget, yTarget, target);
        }
        protected override IList<Tile> GetIntersection(FloatRectangle bounds)
        {
            IList<Tile> tiles = base.GetIntersection(bounds);

            movementGrid = null;
            matchGrid = null;
            intersectionGrid = null;

            if (Config.Diagnostic)
            {
                HighlightMovement(bounds);
                HighlightMatchingTiles(tiles, bounds);
                HighlightIntersection(tiles, bounds);
            }
            return tiles;
        }
Пример #5
0
        private bool CanSetSurfaced(IHitBox hitBox)
        {
            FloatRectangle bounds = hitBox.BoundingBox.Bounds;
            float x = bounds.X;
            float w = bounds.Width;
            float y = bounds.Bottom;
            float h = MagicNumbers.AcceptableSurfaceDistance;

            var rectangle = new FloatRectangle(x, y, w, h);

            var fit = CollisionDetection.CanFitInMatrix(rectangle);
            if (fit == FitResult.Solid) // ensure that the surface actually blocks further movement.
            {
                return true;
            }

            return false;
        }
Пример #6
0
        public virtual FitResult CanFitInMatrix(FloatRectangle bounds)
        {
            IList<Tile> intersection = GetIntersection(bounds);

            foreach (Tile tile in intersection)
            {
                if (tile.Deathly)
                {
                    return FitResult.Mortal; // died.
                }
                if (tile.Clear)
                {
                    return FitResult.LevelComplete;
                }
                if (tile.Impassable)
                {
                    return FitResult.Solid;
                }
            }

            return FitResult.Ok;
        }
Пример #7
0
        public FloatRectangle Displace(Vector2 vector)
        {
            FloatRectangle extended = new FloatRectangle(this);
            var            x        = vector.X;

            if (x < 0)
            {
                extended.X += x;
                x           = -x;
            }
            extended.Width += x;

            var y = vector.Y;

            if (y < 0)
            {
                extended.Y += y;
                y           = -y;
            }
            extended.Height += y;

            return(extended);
        }
Пример #8
0
        private MoveResult CheckInboundMapLimits(FloatRectangle bounds, Vector2 interpolation)
        {
            if (interpolation.X < 0 && bounds.X + interpolation.X < Tile.Width)
            {
                return MoveResult.BlockedOnNegativeX | MoveResult.FlattenXSpeed;
            }

            if (interpolation.X > 0 && bounds.X + interpolation.X > TileMatrix.Instance.Width - Tile.Width)
            {
                return MoveResult.BlockedOnPositiveX | MoveResult.FlattenXSpeed;
            }

            if (interpolation.Y < 0 && bounds.Y + interpolation.Y < Tile.Height)
            {
                return MoveResult.BlockedOnNegativeY | MoveResult.FlattenYSpeed;
            }

            if (interpolation.Y > 0 && bounds.Y + interpolation.Y > TileMatrix.Instance.Height - Tile.Height)
            {
                return MoveResult.BlockedOnPositiveY | MoveResult.FlattenYSpeed;
            }

            return MoveResult.None;
        }
Пример #9
0
 protected virtual IList<Tile> GetIntersection(FloatRectangle bounds)
 {
     TileMatrix matrix = TileMatrix.Instance;
     IList<Tile> intersection = matrix.Intersect(bounds);
     return intersection;
 }
Пример #10
0
        public MoveResult CanMoveInterpolated(FloatRectangle bounds, Vector2 interpolation, DetectionType detectionType)
        {
            FloatRectangle xTarget = new FloatRectangle(bounds).Offset(interpolation.X, 0);
            FloatRectangle yTarget = new FloatRectangle(bounds).Offset(0, interpolation.Y);
            FloatRectangle target = new FloatRectangle(bounds).Offset(interpolation.X, interpolation.Y);

            return CanMove(bounds, interpolation, detectionType, xTarget, yTarget, target);
        }
        private void HighlightIntersection(IEnumerable<Tile> tiles, FloatRectangle bounds)
        {
            IList<Square> squares = new List<Square>();

            foreach (Tile tile in tiles)
            {
                Rectangle intersection = (Rectangle)FloatRectangle.Intersect(bounds, tile.Bounds);
                bool intersects = intersection.Width > 0 && intersection.Height > 0;
                if (!intersects)
                {
                    continue;
                }

                Square square = new Square
                {
                    Alpha = 1f,
                    Bounds = intersection,
                    Color = Color.DarkRed
                };
                squares.Add(square);
            }

            intersectionGrid = new SquareGrid(squares);
        }
Пример #12
0
 public bool Intersects(FloatRectangle value)
 {
     FloatRectangle rectangle = Intersect(this, value);
     return rectangle != Empty;
 }
 private void HighlightMovement(FloatRectangle bounds)
 {
     movementGrid = new SquareGrid(new List<Square>
     {
         new Square
         {
             Alpha = 1f,
             Color = Color.Yellow,
             Bounds = (Rectangle)bounds
         }
     });
 }
Пример #14
0
        public FloatRectangle Displace(Vector2 vector)
        {
            FloatRectangle extended = new FloatRectangle(this);
            var x = vector.X;
            if (x < 0)
            {
                extended.X += x;
                x = -x;
            }
            extended.Width += x;

            var y = vector.Y;
            if (y < 0)
            {
                extended.Y += y;
                y = -y;
            }
            extended.Height += y;

            return extended;
        }
Пример #15
0
 public FloatRectangle(FloatRectangle source)
     : this(source.X, source.Y, source.Width, source.Height)
 {
 }
Пример #16
0
 public FloatRectangle(FloatRectangle source)
     : this(source.X, source.Y, source.Width, source.Height)
 {
 }
Пример #17
0
        public static FloatRectangle Intersect(FloatRectangle source, FloatRectangle target)
        {
            float sourceOffsetX = source.X + source.Width;
            float targetOffsetX = target.X + target.Width;
            float sourceOffsetY = source.Y + source.Height;
            float targetOffsetY = target.Y + target.Height;
            float highestX = source.X > target.X ? source.X : target.X;
            float highestY = source.Y > target.Y ? source.Y : target.Y;
            float highestOffsetX = sourceOffsetX < targetOffsetX ? sourceOffsetX : targetOffsetX;
            float highestOffsetY = sourceOffsetY < targetOffsetY ? sourceOffsetY : targetOffsetY;

            FloatRectangle rectangle;

            if (highestOffsetX > highestX && highestOffsetY > highestY)
            {
                rectangle.X = highestX;
                rectangle.Y = highestY;
                rectangle.Width = highestOffsetX - highestX;
                rectangle.Height = highestOffsetY - highestY;
            }
            else
            {
                rectangle.X = 0;
                rectangle.Y = 0;
                rectangle.Width = 0;
                rectangle.Height = 0;
            }
            return rectangle;
        }
Пример #18
0
        public bool Intersects(FloatRectangle value)
        {
            FloatRectangle rectangle = Intersect(this, value);

            return(rectangle != Empty);
        }
Пример #19
0
        public MoveResult CanMove(
			FloatRectangle bounds, Vector2 interpolation, DetectionType detectionType,
			FloatRectangle xTarget, FloatRectangle yTarget, FloatRectangle target)
        {
            MoveResult flags = MoveResult.None;

            FitResult fitX = CanFitInMatrix(xTarget);
            FitResult fitY = CanFitInMatrix(yTarget);
            FitResult fit = CanFitInMatrix(target);

            try
            {
                if (detectionType == DetectionType.Collision) // senseless to test this when retracing.
                {
                    flags |= CheckInboundMapLimits(bounds, interpolation);
                }

                if (fitX == FitResult.Mortal || fitY == FitResult.Mortal)
                {
                    flags |= MoveResult.Died;
                    return flags;
                }

                if (fitX == FitResult.LevelComplete || fitY == FitResult.LevelComplete)
                {
                    flags |= MoveResult.LevelCompleted;
                    return flags;
                }

                if (fitX == FitResult.Solid && fitY == FitResult.Solid)
                {
                    flags = MoveResult.Blocked;
                    return flags;
                }

                if (fit == FitResult.Mortal)
                {
                    flags |= MoveResult.Died;
                    return flags;
                }

                if (fit == FitResult.LevelComplete)
                {
                    flags |= MoveResult.LevelCompleted;
                    return flags;
                }

                if (fit == FitResult.Ok)
                {
                    flags |= MoveResult.X | MoveResult.Y;
                    return flags;
                }

                flags |= AdjustFlags(interpolation, fitX, fitY);

                return flags;
            }
            finally
            {
                RefreshDiagnostics(detectionType, fit, fitX, fitY, flags);
            }
        }
        private void HighlightMatchingTiles(IEnumerable<Tile> tiles, FloatRectangle bounds)
        {
            IList<Square> squares = new List<Square>();

            foreach (Tile tile in tiles)
            {
                FloatRectangle intersection = (Rectangle)FloatRectangle.Intersect(bounds, tile.Bounds);
                bool intersects = intersection.Width > 0 && intersection.Height > 0;

                Square square = new Square
                {
                    Alpha = 0.7f,
                    Bounds = tile.Bounds,
                    Color = intersects ? Color.MediumPurple : Color.MintCream
                };
                squares.Add(square);
            }

            matchGrid = new SquareGrid(squares);
        }