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); }
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; }
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; }
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; }
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; }
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); }
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; }
protected virtual IList<Tile> GetIntersection(FloatRectangle bounds) { TileMatrix matrix = TileMatrix.Instance; IList<Tile> intersection = matrix.Intersect(bounds); return intersection; }
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); }
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 } }); }
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; }
public FloatRectangle(FloatRectangle source) : this(source.X, source.Y, source.Width, source.Height) { }
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; }
public bool Intersects(FloatRectangle value) { FloatRectangle rectangle = Intersect(this, value); return(rectangle != Empty); }
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); }