示例#1
0
 // Tells whether this intersects another rectangle at offset
 public override bool intersects(GameRectangle other, double[] offset)
 {
     if (Math.Abs(offset[0]) >= (this.getWidth() + other.getWidth()) / 2)
     {
         return(false);
     }
     if (Math.Abs(offset[1]) >= (this.getHeight() + other.getHeight()) / 2)
     {
         return(false);
     }
     return(true);
 }
示例#2
0
 private void InitializeField()
 {
     outsideRecArr = new GameRectangle[3, 3];
     insideRecArr  = new GameRectangleInside[3, 3][, ];
     for (int i = 0; i < 3; i++)
     {
         for (int j = 0; j < 3; j++)
         {
             Rectangle temp = new Rectangle()
             {
                 Fill   = new SolidColorBrush(Color.FromArgb(150, 0, 0, 0)),
                 Height = BIG_REC_SIZE,
                 Width  = BIG_REC_SIZE,
                 Margin = new Thickness((i + 1) * 10 + i * BIG_REC_SIZE, (j + 1) * 10 + j * BIG_REC_SIZE, 0, 0)
             };
             outsideRecArr[i, j] = new GameRectangle(temp, i, j);
             canvas_play.Children.Add(temp);
             insideRecArr[i, j] = new GameRectangleInside[3, 3];
             for (int m = 0; m < 3; m++)
             {
                 for (int n = 0; n < 3; n++)
                 {
                     Rectangle temp1 = new Rectangle()
                     {
                         Fill   = new SolidColorBrush(Color.FromArgb(255, 150, 150, 150)),
                         Height = SMALL_REC_SIZE,
                         Width  = SMALL_REC_SIZE,
                         Margin = new Thickness(
                             (i + 1) * 10 + i * BIG_REC_SIZE + 10 + (m + 1) * 10 + m * SMALL_REC_SIZE,
                             (j + 1) * 10 + j * BIG_REC_SIZE + 10 + (n + 1) * 10 + n * SMALL_REC_SIZE,
                             0, 0)
                     };
                     temp1.MouseUp           += Cell_Click;
                     insideRecArr[i, j][m, n] = new GameRectangleInside(temp1, i, j, m, n);
                     canvas_play.Children.Add(temp1);
                 }
             }
         }
     }
 }
示例#3
0
    // Tells whether a GameCircle would intersect a GameRectangle at offset
    public override bool intersects(GameRectangle other, double[] offset)
    {
        double deltaX = Math.Abs(offset[0]) - other.getWidth() / 2;

        if (deltaX < 0)
        {
            deltaX = 0;
        }
        double deltaY = Math.Abs(offset[1]) - other.getHeight() / 2;

        if (deltaY < 0)
        {
            deltaY = 0;
        }
        if (deltaX * deltaX + deltaY * deltaY < this.radius * this.radius)
        {
            return(true);
        }
        else
        {
            return(false);
        }
    }
示例#4
0
    // Returns the maximum amount of distance that this can move in the move direction, given a rectangle at offset
    public override double[] moveTo(GameRectangle other, double[] offset, double[] move)
    {
        GameCircle    c = this;
        GameRectangle r = other;

        double[] mirroredMove   = new double[move.Length];
        double[] mirroredOffset = new double[move.Length];
        int      i;

        // flip the coordinate system so that the offset is positive in all dimensions
        for (i = 0; i < move.Length; i++)
        {
            if (offset[i] >= 0)
            {
                mirroredOffset[i] = offset[i];
                mirroredMove[i]   = move[i];
            }
            else
            {
                mirroredOffset[i] = -offset[i];
                mirroredMove[i]   = -move[i];
            }
        }
        //System.Collections.Generic.List<double[]> intersections;
        //double[] tempIntersection;
        // figure out where it may intersect the left/right wall
        double width = r.getWidth() / 2 + c.getRadius();

        if (mirroredMove[0] > 0 && mirroredOffset[0] >= width)
        {
            // calculate where it will intersect this line
            double[] allowedMove = new double[2];
            allowedMove[0] = mirroredOffset[0] - width;
            // check that it will go far enough to collide
            if (allowedMove[0] < mirroredMove[0])
            {
                allowedMove[1] = allowedMove[0] * mirroredMove[1] / mirroredMove[0];
                // make sure that it actually intersects the line segment and not just the line
                if (Math.Abs(mirroredOffset[1] - allowedMove[1]) <= r.getHeight() / 2)
                {
                    // reflect it back correctly and return
                    if (offset[0] < 0)
                    {
                        allowedMove[0] *= -1;
                    }
                    if (offset[1] < 0)
                    {
                        allowedMove[1] *= -1;
                    }
                    return(allowedMove);
                }
            }
        }
        double height = r.getHeight() / 2 + c.getRadius();

        if (mirroredMove[1] > 0 && mirroredOffset[1] >= height)
        {
            // calculate where it will intersect this line
            double[] allowedMove = new double[2];
            allowedMove[1] = mirroredOffset[1] - height;
            // check that it will go far enough to collide
            if (allowedMove[1] < mirroredMove[1])
            {
                allowedMove[0] = allowedMove[1] * mirroredMove[0] / mirroredMove[1];
                // make sure that it actually intersects the line segment and not just the line
                if (Math.Abs(mirroredOffset[0] - allowedMove[0]) <= r.getWidth() / 2)
                {
                    // reflect it back correctly and return
                    if (offset[0] < 0)
                    {
                        allowedMove[0] *= -1;
                    }
                    if (offset[1] < 0)
                    {
                        allowedMove[1] *= -1;
                    }
                    return(allowedMove);
                }
            }
        }
        // figure out where it may intersect the corner arc
        double length       = Math.Sqrt(move[0] * move[0] + move[1] * move[1]);
        double signedWidth  = r.getWidth() / 2;
        double signedHeight = r.getHeight() / 2;

        for (i = 0; i < 2; i++)
        {
            double lateralOffset = (mirroredOffset[0] - signedWidth) * mirroredMove[1] / length - (mirroredOffset[1] - signedHeight) * mirroredMove[0] / length;
            // first check that the movement line will reach the arc
            if (Math.Abs(lateralOffset) <= c.getRadius())
            {
                double forwardOffset = (mirroredOffset[0] - signedWidth) * mirroredMove[0] / length + (mirroredOffset[1] - signedHeight) * mirroredMove[1] / length;
                // Next check that the movement line is facing the right direction
                if (forwardOffset >= 0)
                {
                    double collisionDist = forwardOffset - Math.Sqrt(c.getRadius() * c.getRadius() - lateralOffset * lateralOffset);
                    // Make sure that it is hitting the outside of the arc
                    if ((Math.Abs(mirroredOffset[0] - mirroredMove[0] * collisionDist / length) >= r.getWidth() / 2) &&
                        (Math.Abs(mirroredOffset[1] - mirroredMove[1] * collisionDist / length) >= r.getHeight() / 2))
                    {
                        // If we get here then it is, in fact, moving toward the corner of the rectangle from the outside. Now decide if it wants to move that far
                        // if it doesn't want to move that far, then it can just keep going
                        if (collisionDist >= length)
                        {
                            return(move);
                        }
                        else
                        {
                            // If we get here, it means is would collide with the arc and we need to shorten the length
                            double[] allowedMove = new double[2];
                            allowedMove[0] = move[0] * collisionDist / length;
                            allowedMove[1] = move[1] * collisionDist / length;
                            return(allowedMove);
                        }
                    }
                }
            }
            // Now alter the coordinates to check the other corner, and repeat
            if ((mirroredOffset[0] - signedWidth) * mirroredMove[0] >= (mirroredOffset[1] - signedHeight) * mirroredMove[1])
            {
                // switch vertically because we're closer to the left/right edge
                signedHeight *= -1;
            }
            else
            {
                // switch vertically because we're closer to the left/right edge
                signedWidth *= -1;
            }
        }
        // If we get here, there are no collisions and so any move is fine
        return(move);
    }
示例#5
0
    // Returns the maximum amount of distance that this can move in the move direction, given another rectangle at offset
    public override double[] moveTo(GameRectangle other, double[] offset, double[] move)
    {
        GameRectangle r1 = this;
        GameRectangle r2 = other;
        //double length = Math.Sqrt(move[0] * move[0] + move[1] * move[1]);
        double width  = (r1.getWidth() + r2.getWidth()) / 2;
        double height = (r1.getHeight() + r2.getHeight()) / 2;

        // if they can't collide in this direction then any length is okay
        if ((Math.Abs(offset[0]) >= width) && (offset[0] * move[0] <= 0))
        {
            return(move);
        }
        if ((Math.Abs(offset[1]) >= height) && (offset[1] * move[1] <= 0))
        {
            return(move);
        }

        // figure out if any edges do collide in this direction
        double dir1 = (width - offset[0]) * move[1] - (height - offset[1]) * move[0];
        double dir2 = (width - offset[0]) * move[1] - (-height - offset[1]) * move[0];
        double dir3 = (-width - offset[0]) * move[1] - (height - offset[1]) * move[0];
        double dir4 = (-width - offset[0]) * move[1] - (-height - offset[1]) * move[0];

        // If no edges collide then any length is okay
        if ((dir1 >= 0) && (dir2 >= 0) && (dir3 >= 0) && (dir4 >= 0))
        {
            return(move);
        }
        if ((dir1 <= 0) && (dir2 <= 0) && (dir3 <= 0) && (dir4 <= 0))
        {
            return(move);
        }

        double[] allowedMove = new double[2];
        // figure out whether the top/bottom edges, or the left/right edges will collide
        if ((Math.Abs(offset[0]) - width) * Math.Abs(move[1]) <= (Math.Abs(offset[1]) - height) * Math.Abs(move[0]))
        {
            // check the top/bottom edges and find the closer collision
            if (offset[1] > 0)
            {
                // make sure it is stable with respect to rounding error
                allowedMove[1] = Math.Min(offset[1] - height, move[1]);
            }
            else
            {
                // make sure it is stable with respect to rounding error
                allowedMove[1] = Math.Max(offset[1] + height, move[1]);
            }
            // don't force them to move further than desired
            if (Math.Abs(allowedMove[1]) >= Math.Abs(move[1]))
            {
                return(move);
            }
            // The reason for the following check is to make it stable with respect to rounding error. The condition should be always true but in reality may not be
            if ((Math.Abs(offset[0]) >= width) || (Math.Abs(offset[1]) >= height))
            {
                allowedMove[0] = allowedMove[1] * move[0] / move[1];
            }
            else
            {
                allowedMove[0] = -allowedMove[1] * move[0] / move[1];
            }
        }
        else
        {
            // check the left/right edges and find the closer collision
            if (offset[0] > 0)
            {
                // make sure it is stable with respect to rounding error
                allowedMove[0] = Math.Min(offset[0] - width, move[0]);
            }
            else
            {
                // make sure it is stable with respect to rounding error
                allowedMove[0] = Math.Max(offset[0] + width, move[0]);
            }
            // don't force them to move further than desired
            if (Math.Abs(allowedMove[0]) >= Math.Abs(move[0]))
            {
                return(move);
            }
            // The reason for the following check is to make it stable with respect to rounding error. The condition should be always true but in reality may not be
            if ((Math.Abs(offset[0]) >= width) || (Math.Abs(offset[1]) >= height))
            {
                allowedMove[1] = allowedMove[0] * move[1] / move[0];
            }
            else
            {
                allowedMove[1] = -allowedMove[0] * move[1] / move[0];
            }
        }
        return(allowedMove);
    }
示例#6
0
 public virtual bool intersects(GameRectangle other, double[] offset)
 {
     return(false);
 }
示例#7
0
 public virtual double[] moveTo(GameRectangle other, double[] offset, double[] move)
 {
     return(null);
 }