/// <summary> /// Creates a new HitGrid of the same size and sets its contents to the opposite of this one. /// Does not set type or anything else! /// </summary> /// <returns>The inverted grid</returns> public HitGrid Invert() { var result = new HitGrid(Width, Height, CellWidth, CellHeight); for (int c = 0; c < Columns; c++) { for (int r = 0; r < Rows; r++) { result[c, r] = !this[c, r]; } } return(result); }
public bool CollidesWith(HitGrid other) { if (!CheckBoundingBoxes(other)) { return(false); } if (Radius <= MathUtility.DistanceRectPoint(Left + Radius, Top + Radius, other.Left, other.Top, other.Width, other.Height)) { return(false); } var thisCenter = new Vector2(Left + Radius, Top + Radius); var oCenter = new Vector2(other.Left + other.Width / 2f, other.Top + other.Height / 2f); int rowStart = 0, rowMax = other.Rows, rowStep = 1; int colStart = 0, colMax = other.Columns, colStep = 1; if (thisCenter.X > oCenter.X) { colStart = other.Columns - 1; colStep = colMax = -1; } if (thisCenter.Y > oCenter.Y) { rowStart = other.Rows - 1; rowStep = rowMax = -1; } for (int row = rowStart; row != rowMax; row += rowStep) { for (int col = colStart; col != colMax; col += colStep) { if (!other[col, row]) { continue; } var cellPos = new Vector2(other.Left + col * other.CellWidth, other.Top + row * other.CellWidth); if (Radius > MathUtility.DistanceRectPoint(thisCenter.X, thisCenter.Y, cellPos.X, cellPos.Y, other.CellWidth, other.CellHeight)) { return(true); } } } return(false); }
public bool CollidesWith(HitGrid other) { // Find the X edges var ax1 = Left; var ax2 = Right; var bx1 = other.Left; var bx2 = other.Right; if (ax2 < bx1 || ax1 > bx2) { return(false); } // Find the Y edges var ay1 = Top; var ay2 = Bottom; var by1 = other.Top; var by2 = other.Bottom; if (ay2 < by1 || ay1 > by2) { return(false); } // Find the overlapping area var ox1 = ax1 > bx1 ? ax1 : bx1; var oy1 = ay1 > by1 ? ay1 : by1; var ox2 = ax2 < bx2 ? ax2 : bx2; var oy2 = ay2 < by2 ? ay2 : by2; // Find the smallest tile size, and snap the top and left overlapping // edges to that tile size. This ensures that corner checking works // properly. float tw, th; if (CellWidth < other.CellWidth) { tw = CellWidth; ox1 -= Left; ox1 = (int)(ox1 / tw) * tw; ox1 += Left; } else { tw = other.CellWidth; ox1 -= other.Left; ox1 = (int)(ox1 / tw) * tw; ox1 += other.Left; } if (CellHeight < other.CellHeight) { th = CellHeight; oy1 -= Top; oy1 = (int)(oy1 / th) * th; oy1 += Top; } else { th = other.CellHeight; oy1 -= other.Top; oy1 = (int)(oy1 / th) * th; oy1 += other.Top; } // Step through the overlapping rectangle for (float y = oy1; y < oy2; y += th) { // Get the row indices for the top and bottom edges of the tile int ar1 = (int)(y - Top) / CellHeight; int br1 = (int)(y - other.Top) / other.CellHeight; int ar2 = (int)((y - Top) + (th - 1)) / CellHeight; int br2 = (int)((y - other.Top) + (th - 1)) / other.CellHeight; for (float x = ox1; x < ox2; x += tw) { // Get the column indices for the left and right edges of the tile int ac1 = (int)(x - Left) / CellWidth; int bc1 = (int)(x - other.Left) / other.CellWidth; int ac2 = (int)((x - Left) + (tw - 1)) / CellWidth; int bc2 = (int)((x - other.Left) + (tw - 1)) / other.CellWidth; // Check all the corners for collisions if ((this.CheckCellSafely(ac1, ar1) && other.CheckCellSafely(bc1, br1)) || (this.CheckCellSafely(ac2, ar1) && other.CheckCellSafely(bc2, br1)) || (this.CheckCellSafely(ac1, ar2) && other.CheckCellSafely(bc1, br2)) || (this.CheckCellSafely(ac2, ar2) && other.CheckCellSafely(bc2, br2))) { return(true); } } } return(false); }