Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/271.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何画正方形的边界?_C#_Xna_Rectangles_Monogame - Fatal编程技术网

C# 如何画正方形的边界?

C# 如何画正方形的边界?,c#,xna,rectangles,monogame,C#,Xna,Rectangles,Monogame,我正在使用monogame(它使用XNAAPI接口)来编写我的游戏。到目前为止,这是伟大的,但我遇到了一个障碍,在一些应该是简单的 我需要画一个二维正方形。但我只想要边界(不填充) 我已经看到了很多例子,展示了如何做一个填充的。但没有一个只显示边界 我想我可以制作一个图像并使用它。但我怀疑它是否能很好地调整大小 我刚刚为Texture2D创建了一个扩展方法: static class Utilities { public static void CreateBorder( this Te

我正在使用monogame(它使用XNAAPI接口)来编写我的游戏。到目前为止,这是伟大的,但我遇到了一个障碍,在一些应该是简单的

我需要画一个二维正方形。但我只想要边界(不填充)

我已经看到了很多例子,展示了如何做一个填充的。但没有一个只显示边界


我想我可以制作一个图像并使用它。但我怀疑它是否能很好地调整大小

我刚刚为
Texture2D
创建了一个扩展方法:

static class Utilities {
    public static void CreateBorder( this Texture2D texture,  int borderWidth, Color borderColor ) {
        Color[] colors = new Color[ texture.Width * texture.Height ];

        for ( int x = 0; x < texture.Width; x++ ) {
            for ( int y = 0; y < texture.Height; y++ ) {
                bool colored = false;
                for ( int i = 0; i <= borderWidth; i++ ) {
                    if ( x == i || y == i || x == texture.Width - 1 - i || y == texture.Height - 1 - i ) {
                        colors[x + y * texture.Width] = borderColor;
                        colored = true;
                        break;
                    }
                }

                if(colored == false)
                    colors[ x + y * texture.Width ] = Color.Transparent;
            }
        }

        texture.SetData( colors );
    }
}
结果如下:


也许您可以使用1x1像素纹理使用精灵批绘制单个边。在XNA中,您可以执行以下操作:

class RectangleSprite
{
    static Texture2D _pointTexture;
    public static void DrawRectangle(SpriteBatch spriteBatch, Rectangle rectangle, Color color, int lineWidth)
    {
        if (_pointTexture == null)
        {
            _pointTexture = new Texture2D(spriteBatch.GraphicsDevice, 1, 1);
            _pointTexture.SetData<Color>(new Color[]{Color.White});
        }

        spriteBatch.Draw(_pointTexture, new Rectangle(rectangle.X, rectangle.Y, lineWidth, rectangle.Height + lineWidth), color);
        spriteBatch.Draw(_pointTexture, new Rectangle(rectangle.X, rectangle.Y, rectangle.Width + lineWidth, lineWidth), color);
        spriteBatch.Draw(_pointTexture, new Rectangle(rectangle.X + rectangle.Width, rectangle.Y, lineWidth, rectangle.Height + lineWidth), color);
        spriteBatch.Draw(_pointTexture, new Rectangle(rectangle.X, rectangle.Y + rectangle.Height, rectangle.Width + lineWidth, lineWidth), color);
    }     
}

我为绘图原语创建了一个实用类。你可能会发现它很有用

static public class PrimiviteDrawing
{
    static public void DrawRectangle(Texture2D whitePixel, SpriteBatch batch, Rectangle area, int width, Color color)
    {
        batch.Draw(whitePixel, new Rectangle(area.X, area.Y, area.Width, width), color);
        batch.Draw(whitePixel, new Rectangle(area.X, area.Y, width, area.Height), color);
        batch.Draw(whitePixel, new Rectangle(area.X + area.Width - width, area.Y, width, area.Height), color);
        batch.Draw(whitePixel, new Rectangle(area.X, area.Y + area.Height - width, area.Width, width), color);
    }
    static public void DrawRectangle(Texture2D whitePixel, SpriteBatch batch, Rectangle area)
    {
        DrawRectangle(whitePixel, batch, area, 1, Color.White);
    }
    public static void DrawCircle(Texture2D whitePixel, SpriteBatch spritbatch, IntegerVector2 center, float radius, Color color, int lineWidth = 2, int segments = 16)
    {
        Vector2[] vertex = new Vector2[segments];

        double increment = Math.PI * 2.0 / segments;
        double theta = 0.0;

        for (int i = 0; i < segments; i++)
        {
            vertex[i] = center.ToVector2() + radius * new Vector2((float)Math.Cos(theta), (float)Math.Sin(theta));
            theta += increment;
        }

        DrawPolygon(whitePixel, spritbatch, vertex, segments, color, lineWidth);
    }
    public static void DrawPolygon(Texture2D whitePixel, SpriteBatch spriteBatch, Vector2[] vertex, int count, Color color, int lineWidth)
    {
        if (count > 0)
        {
            for (int i = 0; i < count - 1; i++)
            {
                DrawLineSegment(whitePixel, spriteBatch, vertex[i], vertex[i + 1], color, lineWidth);
            }
            DrawLineSegment(whitePixel, spriteBatch, vertex[count - 1], vertex[0], color, lineWidth);
        }
    }
    public static void DrawLineSegment(Texture2D whitePixel, SpriteBatch spriteBatch, Vector2 point1, Vector2 point2, Color color, int lineWidth)
    {
        float angle = (float)Math.Atan2(point2.Y - point1.Y, point2.X - point1.X);
        float length = Vector2.Distance(point1, point2);

        spriteBatch.Draw(whitePixel, point1, null, color,
        angle, Vector2.Zero, new Vector2(length, lineWidth),
        SpriteEffects.None, 0f);
    }
}
静态公共类原始绘图
{
静态公共空白DrawRectangle(Texture2D whitePixel、SpriteBatch批处理、矩形区域、int宽度、颜色)
{
批处理绘制(白像素,新矩形(area.X,area.Y,area.Width,Width),颜色);
批处理绘制(白像素,新矩形(面积.X,面积.Y,宽度,面积.高度),颜色);
批处理绘制(白色像素,新矩形(面积.X+面积.宽度-宽度,面积.Y,宽度,面积.高度),颜色);
绘制(白色像素,新矩形(面积.X,面积.Y+面积.高度-宽度,面积.宽度),颜色);
}
静态公共空白DrawRectangle(Texture2D whitePixel、SpriteBatch批处理、矩形区域)
{
DrawRectangle(白色像素、批次、面积、1、颜色、白色);
}
公共静态空白绘制圆(纹理2D白色像素、SpriteBatch spritbatch、IntegerVector2中心、浮动半径、颜色、int线宽=2、int段=16)
{
Vector2[]顶点=新的Vector2[段];
双增量=Math.PI*2.0/段;
双θ=0.0;
对于(int i=0;i0)
{
对于(int i=0;i
以下是我的做法:

    private void OutLine_Box(SpriteBatch sbatch, Rectangle rect)
    {
        List<Vector2> pixels = new List<Vector2>();
        for (int x = rect.X; x < rect.X + rect.Width; x++)
        {
            for (int y = rect.Y; y < rect.Y + rect.Height; y++)
            {
                if (y == rect.Y || y == rect.Y + rect.Height - 1)
                    pixels.Add(new Vector2(x, y));
                if (x == rect.X || x == rect.X + rect.Width - 1)
                    pixels.Add(new Vector2(x, y));
            }
        }

        foreach (Vector2 v in pixels)
            sbatch.Draw(PixelTexture, v, OutLineColor);
    }
private void OutLine_框(SpriteBatch sbatch,Rectangle rect)
{
列表像素=新列表();
对于(intx=rect.x;x
这确实有效,但它覆盖了我的纹理绘制。所以+1,因为它起作用了,但我试图找到一些东西,在我的纹理周围/上方画一个方框,这样我就可以看到我的边界在哪里。为了避免纹理覆盖,只需先画正方形。它应该可以工作,让我知道。@Fuex:Sam在游戏开发SE上找到了你的代码,发现了一个问题。我还没有安装XNA,所以我不能玩它,但是如果你有时间,你能看一下吗?@Anko Pixel color addresing不好,应该是x+y*宽度。它可以在正方形上工作,但不能在正方形上工作rectangle@Blau对于正方形,它不会产生问题,因为高度和宽度相等。尽管如此,还是把它改成了长方形,谢谢。
static public class PrimiviteDrawing
{
    static public void DrawRectangle(Texture2D whitePixel, SpriteBatch batch, Rectangle area, int width, Color color)
    {
        batch.Draw(whitePixel, new Rectangle(area.X, area.Y, area.Width, width), color);
        batch.Draw(whitePixel, new Rectangle(area.X, area.Y, width, area.Height), color);
        batch.Draw(whitePixel, new Rectangle(area.X + area.Width - width, area.Y, width, area.Height), color);
        batch.Draw(whitePixel, new Rectangle(area.X, area.Y + area.Height - width, area.Width, width), color);
    }
    static public void DrawRectangle(Texture2D whitePixel, SpriteBatch batch, Rectangle area)
    {
        DrawRectangle(whitePixel, batch, area, 1, Color.White);
    }
    public static void DrawCircle(Texture2D whitePixel, SpriteBatch spritbatch, IntegerVector2 center, float radius, Color color, int lineWidth = 2, int segments = 16)
    {
        Vector2[] vertex = new Vector2[segments];

        double increment = Math.PI * 2.0 / segments;
        double theta = 0.0;

        for (int i = 0; i < segments; i++)
        {
            vertex[i] = center.ToVector2() + radius * new Vector2((float)Math.Cos(theta), (float)Math.Sin(theta));
            theta += increment;
        }

        DrawPolygon(whitePixel, spritbatch, vertex, segments, color, lineWidth);
    }
    public static void DrawPolygon(Texture2D whitePixel, SpriteBatch spriteBatch, Vector2[] vertex, int count, Color color, int lineWidth)
    {
        if (count > 0)
        {
            for (int i = 0; i < count - 1; i++)
            {
                DrawLineSegment(whitePixel, spriteBatch, vertex[i], vertex[i + 1], color, lineWidth);
            }
            DrawLineSegment(whitePixel, spriteBatch, vertex[count - 1], vertex[0], color, lineWidth);
        }
    }
    public static void DrawLineSegment(Texture2D whitePixel, SpriteBatch spriteBatch, Vector2 point1, Vector2 point2, Color color, int lineWidth)
    {
        float angle = (float)Math.Atan2(point2.Y - point1.Y, point2.X - point1.X);
        float length = Vector2.Distance(point1, point2);

        spriteBatch.Draw(whitePixel, point1, null, color,
        angle, Vector2.Zero, new Vector2(length, lineWidth),
        SpriteEffects.None, 0f);
    }
}
    private void OutLine_Box(SpriteBatch sbatch, Rectangle rect)
    {
        List<Vector2> pixels = new List<Vector2>();
        for (int x = rect.X; x < rect.X + rect.Width; x++)
        {
            for (int y = rect.Y; y < rect.Y + rect.Height; y++)
            {
                if (y == rect.Y || y == rect.Y + rect.Height - 1)
                    pixels.Add(new Vector2(x, y));
                if (x == rect.X || x == rect.X + rect.Width - 1)
                    pixels.Add(new Vector2(x, y));
            }
        }

        foreach (Vector2 v in pixels)
            sbatch.Draw(PixelTexture, v, OutLineColor);
    }