コード例 #1
0
ファイル: GetDamage.cs プロジェクト: JOCP9733/tank
 public GetDamage(ITankLogic pLogic)
     : base(pLogic)
 {
     _basePolygon = new Polygon(0,0, 50,0, 50,50, 0,50);
     Tank.AddCollider(new PolygonCollider(_basePolygon, CollidableTags.Tank));
     Tank.Collider.CenterOrigin();
 }
コード例 #2
0
ファイル: Polygon.cs プロジェクト: KrissLaCross/BreakOut
 /// <summary>
 /// Creates a Polygon in the shape of a rectangle.
 /// </summary>
 /// <param name="width">The width of the rectangle.</param>
 /// <param name="height">The height of the rectangle.</param>
 /// <returns>A rectangle shaped Polygon.</returns>
 public static Polygon CreateRectangle(float width, float height) {
     var poly = new Polygon();
     poly.Add(0, 0);
     poly.Add(width, 0);
     poly.Add(width, height);
     poly.Add(0, height);
     return poly;
 }
コード例 #3
0
ファイル: Polygon.cs プロジェクト: KrissLaCross/BreakOut
 /// <summary>
 /// Creates a Polygon in the shape of a circle.
 /// </summary>
 /// <param name="radius">The radius of the circle.</param>
 /// <param name="steps">How many steps to use to create the circle (higher is rounder.)</param>
 /// <returns>A circle shaped Polygon.</returns>
 public static Polygon CreateCircle(float radius, int steps = 32) {
     var poly = new Polygon();
     (steps).Times((i) => {
         var angle = 360f / steps * i;
         poly.Add(Util.PolarX(angle, radius) + radius, Util.PolarY(angle, radius) + radius);
     });
     return poly;
 }
コード例 #4
0
        public PolygonCollider(params float[] points) {
            var i = 0;
            float x = 0;
            List<Vector2> vectorPoints = new List<Vector2>();
            foreach (var p in points) {
                if (i == 0) {
                    x = p;
                    i = 1;
                }
                else {
                    vectorPoints.Add(new Vector2(x, p));
                    i = 0;
                }
            }
            if (i == 1) {
                vectorPoints.Add(new Vector2(x, 0));
            }

            this.polygon = new Polygon(points);
        }
コード例 #5
0
ファイル: Polygon.cs プロジェクト: KrissLaCross/BreakOut
 /// <summary>
 /// Create a new Polygon.
 /// </summary>
 /// <param name="copy">The source Polygon to copy.</param>
 public Polygon(Polygon copy) {
     Points = new List<Vector2>();
     Points.AddRange(copy.Points);
 }
コード例 #6
0
ファイル: Polygon.cs プロジェクト: KrissLaCross/BreakOut
        /// <summary>
        /// Test another Polygon for an overlap.  Will not work if either Polygon is concave!
        /// </summary>
        /// <param name="other">The other polygon to check.</param>
        /// <returns>True if this polygon overlaps the other polygon.</returns>
        public bool Overlap(Polygon other) {
            var axes = GetAxes();
            axes.AddRange(other.GetAxes());

            int i = 0;
            foreach (var axis in axes) {
                var p1 = Projection(axis);
                var p2 = other.Projection(axis);
                if (!p1.Overlap(p2)) {
                    return false;
                }
                i++;
            }

            return true;
        }
コード例 #7
0
 public PolygonCollider(Vector2 firstPoint, params Vector2[] points)
 {
     polygon = new Polygon(firstPoint, points);
 }
コード例 #8
0
 public PolygonCollider(Polygon polygon, Enum tag, params Enum[] tags) : this(polygon) {
     AddTag(tag);
     AddTag(tags);
 }
コード例 #9
0
 public PolygonCollider(Polygon polygon, params int[] tags)
 {
     this.polygon = polygon;
     AddTag(tags);
 }
コード例 #10
0
ファイル: Collider.cs プロジェクト: NeroInu/TragicMagicOtter
        /// <summary>
        /// Giant function that checks for overlaps between many different types
        /// </summary>
        /// <param name="first">The first collider to test.</param>
        /// <param name="second">The second collider to test.</param>
        /// <returns>True if overlapping something</returns>
        internal static bool OverlapTest(Collider first, Collider second) {

            #region Box vs Box
            if (first is BoxCollider && second is BoxCollider) {
                if (first.Right <= second.Left) return false;
                if (first.Bottom <= second.Top) return false;
                if (first.Left >= second.Right) return false;
                if (first.Top >= second.Bottom) return false;
                return true;
            }
            #endregion

            #region Box vs Circle
            else if ((first is BoxCollider && second is CircleCollider) || (first is CircleCollider && second is BoxCollider)) {
                CircleCollider circle;
                BoxCollider box;
                if (first is CircleCollider) {
                    circle = first as CircleCollider;
                    box = second as BoxCollider;
                }
                else {
                    circle = second as CircleCollider;
                    box = first as BoxCollider;
                }

                //check is c center point is in the rect
                if (Util.InRect(circle.CenterX, circle.CenterY, box.Left, box.Top, box.Width, box.Height)) {
                    return true;
                }

                //check to see if any corners are in the circle
                if (Util.DistanceRectPoint(circle.CenterX, circle.CenterY, box.Left, box.Top, box.Width, box.Height) < circle.Radius) {
                    return true;
                }

                //check to see if any lines on the box intersect the circle
                Line2 boxLine;

                boxLine = new Line2(box.Left, box.Top, box.Right, box.Top);
                if (boxLine.IntersectCircle(new Vector2(circle.CenterX, circle.CenterY), circle.Radius)) return true;

                boxLine = new Line2(box.Right, box.Top, box.Right, box.Bottom);
                if (boxLine.IntersectCircle(new Vector2(circle.CenterX, circle.CenterY), circle.Radius)) return true;

                boxLine = new Line2(box.Right, box.Bottom, box.Left, box.Bottom);
                if (boxLine.IntersectCircle(new Vector2(circle.CenterX, circle.CenterY), circle.Radius)) return true;

                boxLine = new Line2(box.Left, box.Bottom, box.Left, box.Top);
                if (boxLine.IntersectCircle(new Vector2(circle.CenterX, circle.CenterY), circle.Radius)) return true;

                return false;
            }
            #endregion

            #region Box vs Grid
            else if ((first is BoxCollider && second is GridCollider) || (first is GridCollider && second is BoxCollider)) {
                BoxCollider box;
                GridCollider grid;
                if (first is BoxCollider) {
                    box = first as BoxCollider;
                    grid = second as GridCollider;
                }
                else {
                    box = second as BoxCollider;
                    grid = first as GridCollider;
                }

                if (box.Right <= grid.Left) return false;
                if (box.Bottom <= grid.Top) return false;
                if (box.Left >= grid.Right) return false;
                if (box.Top >= grid.Bottom) return false;

                //This is a quick fix and might have to be addressed later
                if (grid.GetRect(box.Left, box.Top, box.Right - 1, box.Bottom - 1, false)) return true;
                return false;
            }
            #endregion

            #region Box vs Line
            else if ((first is BoxCollider && second is LineCollider) || (first is LineCollider && second is BoxCollider)) {
                BoxCollider box;
                LineCollider line;
                if (first is BoxCollider) {
                    box = first as BoxCollider;
                    line = second as LineCollider;
                }
                else {
                    box = second as BoxCollider;
                    line = first as LineCollider;
                }

                if (line.Line2.IntersectsRect(box.Left, box.Top, box.Width, box.Height)) return true;

                return false;
            }
            #endregion
                
            #region Circle vs Circle
            else if (first is CircleCollider && second is CircleCollider) {
                CircleCollider
                    circle1 = first as CircleCollider,
                    circle2 = second as CircleCollider;
                if (Util.Distance(circle1.CenterX, circle1.CenterY, circle2.CenterX, circle2.CenterY) < circle1.Radius + circle2.Radius) {
                    return true;
                }
                return false;
            }
            #endregion

            #region Circle vs Grid
                        else if ((first is CircleCollider && second is GridCollider) || (first is GridCollider && second is CircleCollider)) {
                            //make a rectangle out of the circle, check for any tiles in that rectangle
                            //if there are tiles, check each tile as a rectangle against the circle
                            CircleCollider circle;
                            GridCollider grid;
                            if (first is CircleCollider) {
                                circle = first as CircleCollider;
                                grid = second as GridCollider;
                            }
                            else {
                                circle = second as CircleCollider;
                                grid = first as GridCollider;
                            }

                            int gridx, gridy, gridx2, gridy2;
                            gridx = (int)(Util.SnapToGrid(circle.Left - grid.Left, grid.TileWidth) / grid.TileWidth);
                            gridy = (int)(Util.SnapToGrid(circle.Top - grid.Top, grid.TileHeight) / grid.TileHeight);
                            gridx2 = (int)(Util.SnapToGrid(circle.Right - grid.Left, grid.TileWidth) / grid.TileWidth);
                            gridy2 = (int)(Util.SnapToGrid(circle.Bottom - grid.Top, grid.TileHeight) / grid.TileHeight);

                            //if (grid.GetRect(gridx, gridy, gridx2, gridy2, false)) {
                            if (grid.GetRect(circle.Left, circle.Top, circle.Right, circle.Bottom, false)) {
                                float rectX, rectY;
                                for (int i = gridx; i <= gridx2; i++) {
                                    for (int j = gridy; j <= gridy2; j++) {
                                        if (grid.GetTile(i, j)) {
                                            rectX = (i * grid.TileWidth) + grid.Left;
                                            rectY = (j * grid.TileHeight) + grid.Top;

                                            //check is c center point is in the rect
                                            if (Util.InRect(circle.CenterX, circle.CenterY, rectX, rectY, grid.TileWidth, grid.TileHeight)) {
                                                return true;
                                            }

                                            //check to see if any corners are in the circle
                                            if (Util.DistanceRectPoint(circle.CenterX, circle.CenterY, rectX, rectY, grid.TileWidth, grid.TileHeight) < circle.Radius) {
                                                //return true;
                                            }

                                            //check to see if any lines on the box intersect the circle
                                            Line2 boxLine;

                                            boxLine = new Line2(rectX, rectY, rectX + grid.TileWidth, rectY);
                                            if (boxLine.IntersectCircle(new Vector2(circle.CenterX, circle.CenterY), circle.Radius)) return true;

                                            boxLine = new Line2(rectX + grid.TileWidth, rectY, rectX + grid.TileWidth, rectY + grid.TileHeight);
                                            if (boxLine.IntersectCircle(new Vector2(circle.CenterX, circle.CenterY), circle.Radius)) return true;

                                            boxLine = new Line2(rectX + grid.TileWidth, rectY + grid.TileHeight, rectX, rectY + grid.TileHeight);
                                            if (boxLine.IntersectCircle(new Vector2(circle.CenterX, circle.CenterY), circle.Radius)) return true;

                                            boxLine = new Line2(rectX, rectY + grid.TileHeight, rectX, rectY);
                                            if (boxLine.IntersectCircle(new Vector2(circle.CenterX, circle.CenterY), circle.Radius)) return true;

                                        }
                                    }
                                }
                            }
                            return false;

                        }
                        #endregion

            #region Line vs Line
            else if (first is LineCollider && second is LineCollider) {
                return (first as LineCollider).Line2.Intersects((second as LineCollider).Line2);
            }
            #endregion

            #region Line vs Grid
            else if ((first is LineCollider && second is GridCollider) || (first is GridCollider && second is LineCollider)) {
                //check any tiles along the line segment, somehow?
                LineCollider line;
                GridCollider grid;
                if (first is LineCollider) {
                    line = first as LineCollider;
                    grid = second as GridCollider;
                }
                else {
                    line = second as LineCollider;
                    grid = first as GridCollider;
                }

                //make a rectangle out of the line segment, check for any tiles in that rectangle

                //if there are tiles in there, loop through and check each one as a rectangle against the line
                if (grid.GetRect(line.Left, line.Top, line.Right, line.Bottom, false)) {
                    float rectX, rectY;
                    int
                        gridx = grid.GridX(line.Left),
                        gridy = grid.GridY(line.Top),
                        gridx2 = grid.GridX(line.Right),
                        gridy2 = grid.GridY(line.Bottom);

                    for (int i = gridx; i <= gridx2; i++) {
                        for (int j = gridy; j <= gridy2; j++) {
                            if (grid.GetTile(i, j)) {
                                rectX = i * grid.TileWidth + grid.Left;
                                rectY = j * grid.TileHeight + grid.Top;
                                if (Util.InRect((float)line.Line2.PointA.X, (float)line.Line2.PointA.Y, rectX, rectY, grid.TileWidth, grid.TileHeight)) {
                                    return true;
                                }
                                if (Util.InRect((float)line.Line2.PointB.X, (float)line.Line2.PointB.Y, rectX, rectY, grid.TileWidth, grid.TileHeight)) {
                                    return true;
                                }
                                if (line.Line2.IntersectsRect(rectX, rectY, grid.TileWidth, grid.TileHeight)) {
                                    return true;
                                }

                            }
                        }
                    }
                }
                return false;

            }
            #endregion

            #region Line vs Circle
            else if ((first is LineCollider && second is CircleCollider) || (first is CircleCollider && second is LineCollider)) {
                CircleCollider circle;
                LineCollider line;
                if (first is LineCollider) {
                    line = first as LineCollider;
                    circle = second as CircleCollider;
                }
                else {
                    line = second as LineCollider;
                    circle = first as CircleCollider;
                }

                if (line.Line2.IntersectCircle(new Vector2(circle.CenterX, circle.CenterY), circle.Radius)) {
                    return true;
                }
                return false;
            }
            #endregion
                
            #region Grid vs Grid
            else if (first is GridCollider && second is GridCollider) {
                //loop through one grid, check tile as rectangle in second grid?
                //first check if grids even touch with basic box test
                //then check each tile on first as a rect against second's tilemap
                //maybe optimize by looping through the smaller (area wise) tilemap

                if (!Util.IntersectRectangles(first.Left, first.Top, first.Width, first.Height, second.Left, second.Top, second.Width, second.Height)) {
                    return false;
                }

                GridCollider small, large;

                if ((first as GridCollider).TileArea < (second as GridCollider).TileArea) {
                    small = first as GridCollider;
                    large = second as GridCollider;
                }
                else {
                    small = second as GridCollider;
                    large = first as GridCollider;
                }

                for (int i = 0; i < small.TileColumns; i++) {
                    for (int j = 0; j < small.TileRows; j++) {
                        if (small.GetTile(i, j)) {
                            //check rects
                            float rectx, recty;
                            rectx = i * small.TileWidth + small.Left;
                            recty = j * small.TileHeight + small.Top;
                            if (large.GetRect(rectx, recty, rectx + small.TileWidth, recty + small.TileHeight, false)) {
                                return true;
                            }
                        }
                    }
                }

                return false;

            }
            #endregion

            #region Point vs Point
            else if (first is PointCollider && second is PointCollider) {
                if (first.Left != second.Left) return false;
                if (first.Top != second.Top) return false;
                return true;
            }
            #endregion

            #region Point vs Circle
            else if ((first is PointCollider && second is CircleCollider) || (first is CircleCollider && second is PointCollider)) {
                PointCollider point;
                CircleCollider circle;

                if (first is PointCollider) {
                    point = first as PointCollider;
                    circle = second as CircleCollider;
                }
                else {
                    point = second as PointCollider;
                    circle = first as CircleCollider;
                }

                if (Util.Distance(point.Left, point.Top, circle.CenterX, circle.CenterY) < circle.Radius) return true;
                return false;
            }
            #endregion

            #region Point vs Box
            else if ((first is PointCollider && second is BoxCollider) || (first is BoxCollider && second is PointCollider)) {
                PointCollider point;
                BoxCollider box;

                if (first is PointCollider) {
                    point = first as PointCollider;
                    box = second as BoxCollider;
                }
                else {
                    point = second as PointCollider;
                    box = first as BoxCollider;
                }

                if (Util.InRect(point.Left, point.Top, box.Left, box.Top, box.Width, box.Height)) return true;
                return false;
            }
            #endregion

            #region Point vs Grid
            else if ((first is PointCollider && second is GridCollider) || (first is GridCollider && second is PointCollider)) {
                PointCollider point;
                GridCollider grid;

                if (first is PointCollider) {
                    point = first as PointCollider;
                    grid = second as GridCollider;
                }
                else {
                    point = second as PointCollider;
                    grid = first as GridCollider;
                }

                int gridx, gridy;
                gridx = (int)Util.SnapToGrid(point.Left, grid.TileWidth);
                gridy = (int)Util.SnapToGrid(point.Top, grid.TileHeight);

                if (grid.GetTile(gridx, gridy)) return true;
                return false;
            }
            #endregion

            #region Point vs Line
            else if ((first is PointCollider && second is LineCollider) || (first is LineCollider && second is PointCollider)) {
                PointCollider point;
                LineCollider line;

                if (first is PointCollider) {
                    point = first as PointCollider;
                    line = second as LineCollider;
                }
                else {
                    point = second as PointCollider;
                    line = first as LineCollider;
                }

                //first take care of weird cases that might result in division by 0
                Line2 line2 = line.Line2;
                if (line2.X1 == line2.X2) {
                    if (line2.Y1 == line2.Y2) {
                        if (point.Left == line2.X1 && point.Top == line2.Y1) {
                            return true;
                        }
                    }
                    if (point.Left == line2.X1 && point.Top >= Math.Min(line2.Y1, line2.Y2) && point.Top <= Math.Max(line2.Y1, line2.Y2)) {
                        return true;
                    }
                }
                if (line2.Y1 == line2.Y2) {
                    if (point.Top == line2.Y1 && point.Left >= Math.Min(line2.X1, line2.X2) && point.Left <= Math.Max(line2.X1, line2.X2)) {
                        return true;
                    }
                }

                //if no special cases, this should work!
                if ((point.Left - line2.X1) / (line2.X2 - line2.X1) == (point.Top - line2.Y1) / (line2.Y2 - line2.Y1)) return true;
                return false;
            }
            #endregion

            #region Pixel vs Pixel
            else if ((first is PixelCollider && second is PixelCollider)) {
                //AABB test first

                var pixel1 = first as PixelCollider;
                var pixel2 = second as PixelCollider;

                if (first.Right <= second.Left) return false;
                if (first.Left >= second.Right) return false;
                if (first.Top >= second.Bottom) return false;
                if (first.Bottom <= second.Top) return false;

                //get intersecting area

                float x1 = Math.Max(first.Left, second.Left);
                float x2 = Math.Min(first.Right, second.Right);

                float y1 = Math.Max(first.Top, second.Top);
                float y2 = Math.Min(first.Bottom, second.Bottom);

                //scan both pixels and see if they collide

                var p1 = first as PixelCollider;
                var p2 = second as PixelCollider;
                for (var i = x1; i < x2; i++) {
                    for (var j = y1; j < y2; j++) {
                        var xx = (int)Math.Floor(i - first.Left);
                        var yy = (int)Math.Floor(j - first.Top);

                        if (p1.PixelAt(xx, yy)) {
                            xx = (int)Math.Floor(i - second.Left);
                            yy = (int)Math.Floor(j - second.Top);
                            if (p2.PixelAt(xx, yy)) {
                                return true;
                            }
                        }
                    }
                }

                return false;
            }
            #endregion

            #region Pixel vs Box
            else if ((first is PixelCollider && second is BoxCollider) || (first is BoxCollider && second is PixelCollider)) {
                PixelCollider pixel;
                BoxCollider box;

                if (first is PixelCollider) {
                    pixel = first as PixelCollider;
                    box = second as BoxCollider;
                }
                else {
                    pixel = second as PixelCollider;
                    box = first as BoxCollider;
                }

                //AABB test

                if (box.Right <= pixel.Left) return false;
                if (box.Left >= pixel.Right) return false;
                if (box.Top >= pixel.Bottom) return false;
                if (box.Bottom <= pixel.Top) return false;

                //get intersecting area

                float x1 = Math.Max(box.Left, pixel.Left);
                float x2 = Math.Min(box.Right, pixel.Right);

                float y1 = Math.Max(box.Top, pixel.Top);
                float y2 = Math.Min(box.Bottom, pixel.Bottom);

                //scan for pixels in area

                for (var i = x1; i < x2; i++) {
                    for (var j = y1; j < y2; j++) {
                        var xx = (int)Math.Floor(i - pixel.Left);
                        var yy = (int)Math.Floor(j - pixel.Top);

                        if (pixel.PixelAt(xx, yy)) {
                            return true;
                        }
                    }
                }

                return false;

            }
            #endregion

            #region Pixel vs Circle
            else if ((first is PixelCollider && second is CircleCollider) || (first is CircleCollider && second is PixelCollider)) {
                PixelCollider pixel;
                CircleCollider circle;

                if (first is PixelCollider) {
                    pixel = first as PixelCollider;
                    circle = second as CircleCollider;
                }
                else {
                    pixel = second as PixelCollider;
                    circle = first as CircleCollider;
                }

                //circle to rectangle collision first

                bool firstCollisionCheck = false;

                //check is c center point is in the rect
                if (Util.InRect(circle.CenterX, circle.CenterY, pixel.Left, pixel.Top, pixel.Width, pixel.Height)) {
                    firstCollisionCheck = true;
                }

                if (!firstCollisionCheck) {
                    //check to see if any corners are in the circle
                    if (Util.DistanceRectPoint(circle.CenterX, circle.CenterY, pixel.Left, pixel.Top, pixel.Width, pixel.Height) < circle.Radius) {
                        firstCollisionCheck = true;
                    }
                }

                if (!firstCollisionCheck) {
                    //check to see if any lines on the box intersect the circle
                    Line2 boxLine;

                    boxLine = new Line2(pixel.Left, pixel.Top, pixel.Right, pixel.Top);
                    if (boxLine.IntersectCircle(new Vector2(circle.CenterX, circle.CenterY), circle.Radius)) firstCollisionCheck = true;

                    if (!firstCollisionCheck) {
                        boxLine = new Line2(pixel.Right, pixel.Top, pixel.Right, pixel.Bottom);
                        if (boxLine.IntersectCircle(new Vector2(circle.CenterX, circle.CenterY), circle.Radius)) firstCollisionCheck = true;
                    }

                    if (!firstCollisionCheck) {
                        boxLine = new Line2(pixel.Right, pixel.Bottom, pixel.Left, pixel.Bottom);
                        if (boxLine.IntersectCircle(new Vector2(circle.CenterX, circle.CenterY), circle.Radius)) firstCollisionCheck = true;
                    }

                    if (!firstCollisionCheck) {
                        boxLine = new Line2(pixel.Left, pixel.Bottom, pixel.Left, pixel.Top);
                        if (boxLine.IntersectCircle(new Vector2(circle.CenterX, circle.CenterY), circle.Radius)) firstCollisionCheck = true;
                    }

                }

                if (!firstCollisionCheck) return false;

                //get intersecting area as if circle was rect

                //scan for pixels in area

                //only check pixels inside circle radius

                //okay the math for that is super hard so we're doing it the easy + dumb wy

                //dumb way, scan through pixels to see if one of the pixels is in the circle?

                for (var xx = 0; xx < pixel.Width; xx++) {
                    for (var yy = 0; yy < pixel.Height; yy++) {
                        var pixelx = xx + pixel.Left;
                        var pixely = yy + pixel.Top;
                        if (Util.Distance(pixelx, pixely, circle.CenterX, circle.CenterY) <= circle.Radius + 1) {
                            if (pixel.PixelAt(xx, yy)) {
                                return true;
                            }
                        }
                    }
                }
            }
            #endregion

            #region Pixel vs Point
            else if ((first is PixelCollider && second is PointCollider) || (first is PointCollider && second is PixelCollider)) {
                PixelCollider pixel;
                PointCollider point;

                if (first is PixelCollider) {
                    pixel = first as PixelCollider;
                    point = second as PointCollider;
                }
                else {
                    pixel = second as PixelCollider;
                    point = first as PointCollider;
                }

                //rectangle to point first
                if (!Util.InRect(point.Left, point.Top, pixel.Left, pixel.Top, pixel.Width, pixel.Height)) return false;

                //check for pixel at point
                if (pixel.PixelAtRelative((int)point.Left, (int)point.Top)) {
                    return true;
                }
                return false;
            }
            #endregion

            #region Pixel vs Line
            else if ((first is PixelCollider && second is LineCollider) || (first is LineCollider && second is PixelCollider)) {
                PixelCollider pixel;
                LineCollider line;

                if (first is PixelCollider) {
                    pixel = first as PixelCollider;
                    line = second as LineCollider;
                }
                else {
                    pixel = second as PixelCollider;
                    line = first as LineCollider;
                }

                //line to rectangle first

                if (!line.Line2.IntersectsRect(pixel.Left, pixel.Top, pixel.Width, pixel.Height)) return false;

                //dumb way, check all pixels for distance to line == 0
                for (var xx = 0; xx < pixel.Width; xx++) {
                    for (var yy = 0; yy < pixel.Height; yy++) {
                        if (pixel.PixelAt(xx, yy)) {
                            if (Util.DistanceLinePoint(xx + pixel.Left, yy + pixel.Top, line.Line2) < 0.1f) {
                                return true;
                            }
                        }
                    }
                }

            }
            #endregion

            #region Pixel vs Grid
            else if ((first is PixelCollider && second is GridCollider) || (first is GridCollider && second is PixelCollider)) {
                PixelCollider pixel;
                GridCollider grid;

                if (first is PixelCollider) {
                    pixel = first as PixelCollider;
                    grid = second as GridCollider;
                }
                else {
                    pixel = second as PixelCollider;
                    grid = first as GridCollider;
                }

                //collide rectangle into tiles first
                if (pixel.Right <= grid.Left) return false;
                if (pixel.Bottom <= grid.Top) return false;
                if (pixel.Left >= grid.Right) return false;
                if (pixel.Top >= grid.Bottom) return false;

                //This is a quick fix and might have to be addressed later
                if (!grid.GetRect(pixel.Left, pixel.Top, pixel.Right - 1, pixel.Bottom - 1, false)) return false;

                //go through tiles that pixel is overlapping
                for (var xx = 0; xx < pixel.Width; xx++) {
                    for (var yy = 0; yy < pixel.Height; yy++) {
                        float checkx = xx + pixel.Left;
                        float checky = yy + pixel.Top;
                        if (grid.GetTileAtPosition(checkx, checky)) {
                            if (pixel.PixelAt(xx, yy)) {
                                return true;
                            }
                        }
                    }
                }
            }
            #endregion

            #region Polygon vs Polygon
            else if (first is PolygonCollider && second is PolygonCollider) {
                var p1 = first as PolygonCollider;
                var p2 = second as PolygonCollider;

                // make copies of the polygons with applied offsets for testing
                var poly1 = new Polygon(p1.Polygon);
                var poly2 = new Polygon(p2.Polygon);

                poly1.OffsetPoints(p1.Left, p1.Top);
                poly2.OffsetPoints(p2.Left, p2.Top);

                return poly1.Overlap(poly2);
            }
            #endregion

            #region Polygon vs Box

            else if (first is PolygonCollider && second is BoxCollider || first is BoxCollider && second is PolygonCollider) {
                PolygonCollider poly;
                BoxCollider box;

                if (first is PolygonCollider) {
                    poly = first as PolygonCollider;
                    box = second as BoxCollider;
                }
                else {
                    poly = second as PolygonCollider;
                    box = first as BoxCollider;
                }

                var poly1 = new Polygon(poly.Polygon);
                poly1.OffsetPoints(poly.Left, poly.Top);

                //create poly for box

                var poly2 = new Polygon(box.Left, box.Top, box.Right, box.Top, box.Right, box.Bottom, box.Left, box.Bottom);

                //test polys
                return poly1.Overlap(poly2);
            }

            #endregion

            #region Polygon vs Circle
            else if (first is PolygonCollider && second is CircleCollider || first is CircleCollider && second is PolygonCollider) {
                PolygonCollider poly;
                CircleCollider circ;

                if (first is PolygonCollider) {
                    poly = first as PolygonCollider;
                    circ = second as CircleCollider;
                }
                else {
                    poly = second as PolygonCollider;
                    circ = first as CircleCollider;
                }

                var poly1 = new Polygon(poly.Polygon);
                poly1.OffsetPoints(poly.Left, poly.Top);

                //check if center point is in poly
                if (poly1.ContainsPoint(circ.CenterX, circ.CenterY)) {
                    return true;
                }

                //check each edge for intersection with the circle
                var lines = poly1.GetEdgesAsLines();

                foreach (var l in lines) {
                    if (l.IntersectCircle(new Vector2(circ.CenterX, circ.CenterY), circ.Radius)) {
                        return true;
                    }
                }

                return false;
                
            }
            #endregion

            #region Polygon vs Grid
            else if (first is PolygonCollider && second is GridCollider || first is GridCollider && second is PolygonCollider) {
                PolygonCollider poly;
                GridCollider grid;

                if (first is PolygonCollider) {
                    poly = first as PolygonCollider;
                    grid = second as GridCollider;
                }
                else {
                    poly = second as PolygonCollider;
                    grid = first as GridCollider;
                }

                var poly1 = new Polygon(poly.Polygon);
                poly1.OffsetPoints(poly.Left, poly.Top);

                //test against grid bounding box first
                var bbox = new Polygon(grid.Left, grid.Top, grid.Right, grid.Top, grid.Right, grid.Bottom, grid.Left, grid.Bottom);
                if (!poly1.Overlap(bbox)) {
                    return false;
                }

                //check rect in bounding box where polygon is
                if (!grid.GetRect(poly.Left, poly.Top, poly.Right, poly.Bottom, false)) {
                    return false;
                }

                //check each occupied cell as a box in the bounding box
                int startX = grid.GridX(poly.Left - grid.Left);
                int startY = grid.GridY(poly.Top - grid.Top);

                int endX = grid.GridX(poly.Left - grid.Left + poly.Width) + 1;
                int endY = grid.GridY(poly.Top - grid.Top + poly.Height) + 1;

                //Console.WriteLine("StartX {0} StartY {1} EndX {2} EndY {3}", startX, startY, endX, endY);

                for (var xx = startX; xx < endX; xx++) {
                    for (var yy = startY; yy < endY; yy++) {
                        if (grid.GetTile(xx, yy)) {
                            var realX = xx * grid.TileWidth + grid.Left;
                            var realY = yy * grid.TileHeight + grid.Top;
                            var gridPoly = new Polygon(
                                realX, realY,
                                realX + grid.TileWidth, realY,
                                realX + grid.TileWidth, realY + grid.TileHeight,
                                realX, realY + grid.TileHeight
                                );
                            if (gridPoly.Overlap(poly1)) {
                                //Console.WriteLine("Collision with tile X:{0} Y:{1}", xx, yy);
                                //Console.WriteLine("Poly overlapped with {0}", gridPoly);
                                return true;
                            }
                        }
                    }
                }

                return false;

            }
            #endregion

            #region Polygon vs Line
            else if (first is PolygonCollider && second is LineCollider || first is LineCollider && second is PolygonCollider) {
                PolygonCollider poly;
                LineCollider line;

                if (first is PolygonCollider) {
                    poly = first as PolygonCollider;
                    line = second as LineCollider;
                }
                else {
                    poly = second as PolygonCollider;
                    line = first as LineCollider;
                }

                var poly1 = new Polygon(poly.Polygon);
                poly1.OffsetPoints(poly.Left, poly.Top);

                var poly2 = new Polygon(line.Left, line.Top, line.Right, line.Bottom);
                return poly1.Overlap(poly2);
            }
            #endregion

            #region Polygon vs Pixel
            else if (first is PolygonCollider && second is PixelCollider || first is PixelCollider && second is PolygonCollider) {
                PolygonCollider poly;
                PixelCollider pixel;

                if (first is PolygonCollider) {
                    poly = first as PolygonCollider;
                    pixel = second as PixelCollider;
                }
                else {
                    poly = second as PolygonCollider;
                    pixel = first as PixelCollider;
                }

                var poly1 = new Polygon(poly.Polygon);
                poly1.OffsetPoints(poly.Left, poly.Top);

                // check bounding box of pixel first
                var bbox = new Polygon(pixel.Left, pixel.Top, pixel.Right, pixel.Top, pixel.Right, pixel.Bottom, pixel.Left, pixel.Bottom);
                if (!poly1.Overlap(bbox)) {
                    return false;
                }

                // get intersecting area of the bounding boxes
                float x1 = Math.Max(poly.Left, pixel.Left);
                float x2 = Math.Min(poly.Right, pixel.Right);

                float y1 = Math.Max(poly.Top, pixel.Top);
                float y2 = Math.Min(poly.Bottom, pixel.Bottom);

                // check each pixel in area as point in poly
                for (var i = x1; i < x2; i++) {
                    for (var j = y1; j < y2; j++) {
                        var xx = (int)Math.Floor(i - pixel.Left);
                        var yy = (int)Math.Floor(j - pixel.Top);

                        if (pixel.PixelAt(xx, yy)) {
                            if (poly1.ContainsPoint(xx + pixel.Left, yy + pixel.Top)) {
                                return true;
                            }
                        }
                    }
                }
                return false;
            }
            #endregion

            #region Polygon vs Point
            else if (first is PolygonCollider && second is PointCollider || first is PointCollider && second is PolygonCollider) {
                PolygonCollider poly;
                PointCollider point;

                if (first is PolygonCollider) {
                    poly = first as PolygonCollider;
                    point = second as PointCollider;
                }
                else {
                    poly = second as PolygonCollider;
                    point = first as PointCollider;
                }

                var poly1 = new Polygon(poly.Polygon);
                poly1.OffsetPoints(poly.Left, poly.Top);

                return poly1.ContainsPoint(point.Left, point.Top);
            }
            #endregion

            #region Unknown
            return false;
            #endregion

        }
コード例 #11
0
 public PolygonCollider(Vector2 firstPoint, params Vector2[] points) {
     polygon = new Polygon(firstPoint, points);
 }
コード例 #12
0
 public PolygonCollider(Polygon polygon, Enum tag, params Enum[] tags) : this(polygon) {
     AddTag(tag);
     AddTag(tags);
 }
コード例 #13
0
 public PolygonCollider(Polygon polygon, params int[] tags) {
     this.polygon = polygon;
     AddTag(tags);
 }
コード例 #14
0
ファイル: Polygon.cs プロジェクト: saint11/to-the-depths
 /// <summary>
 /// Create a new Polygon.
 /// </summary>
 /// <param name="copy">The source Polygon to copy.</param>
 public Polygon(Polygon copy)
 {
     Points = new List <Vector2>();
     Points.AddRange(copy.Points);
 }