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); } }
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); }
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); }
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); }
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); }