使用XNA绘制矩形

时间:2010-05-08 02:21:52

标签: c# optimization xna

我正在开发游戏。当发生某些事情时,我想在屏幕上突出显示一个位置。

我创建了一个为我做这个的类,并找到了一些绘制矩形的代码:

static private Texture2D CreateRectangle(int width, int height, Color colori)
{
    Texture2D rectangleTexture = new Texture2D(game.GraphicsDevice, width, height, 1, TextureUsage.None,
    SurfaceFormat.Color);// create the rectangle texture, ,but it will have no color! lets fix that
    Color[] color = new Color[width * height];//set the color to the amount of pixels in the textures
    for (int i = 0; i < color.Length; i++)//loop through all the colors setting them to whatever values we want
    {
        color[i] = colori;
    }
    rectangleTexture.SetData(color);//set the color data on the texture
    return rectangleTexture;//return the texture
}

问题在于上面的代码每次更新都会被调用(每秒60次),并且没有考虑优化。它需要非常快(上面的代码冻结游戏,现在只有骨架代码)。

有什么建议吗?

注意:任何新代码都会很棒(WireFrame / Fill都很好)。我希望能够指定颜色。

3 个答案:

答案 0 :(得分:49)

XNA Creators Club网站上的SafeArea demo具有专门用于此的代码。

您不必每隔一帧创建纹理,只需在LoadContent中创建。该演示代码的一个非常精简的版本:

public class RectangleOverlay : DrawableGameComponent
{
    SpriteBatch spriteBatch;
    Texture2D dummyTexture;
    Rectangle dummyRectangle;
    Color Colori;

    public RectangleOverlay(Rectangle rect, Color colori, Game game)
        : base(game)
    {
        // Choose a high number, so we will draw on top of other components.
        DrawOrder = 1000;
        dummyRectangle = rect;
        Colori = colori;
    }

    protected override void LoadContent()
    {
        spriteBatch = new SpriteBatch(GraphicsDevice);
        dummyTexture = new Texture2D(GraphicsDevice, 1, 1);
        dummyTexture.SetData(new Color[] { Color.White });
    }

    public override void Draw(GameTime gameTime)
    {
        spriteBatch.Begin();
        spriteBatch.Draw(dummyTexture, dummyRectangle, Colori);
        spriteBatch.End();
    }
}

答案 1 :(得分:5)

这就是我做的。它可能不是最快或最好的解决方案,但它确实有效。

using System;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace Engine
{
    /// <summary>
    /// An extended version of the SpriteBatch class that supports line and
    /// rectangle drawing.
    /// </summary>
    public class ExtendedSpriteBatch : SpriteBatch
    {
        /// <summary>
        /// The texture used when drawing rectangles, lines and other 
        /// primitives. This is a 1x1 white texture created at runtime.
        /// </summary>
        public Texture2D WhiteTexture { get; protected set; }

        public ExtendedSpriteBatch(GraphicsDevice graphicsDevice)
            : base(graphicsDevice)
        {
            this.WhiteTexture = new Texture2D(this.GraphicsDevice, 1, 1);
            this.WhiteTexture.SetData(new Color[] { Color.White });
        }

        /// <summary>
        /// Draw a line between the two supplied points.
        /// </summary>
        /// <param name="start">Starting point.</param>
        /// <param name="end">End point.</param>
        /// <param name="color">The draw color.</param>
        public void DrawLine(Vector2 start, Vector2 end, Color color)
        {
            float length = (end - start).Length();
            float rotation = (float)Math.Atan2(end.Y - start.Y, end.X - start.X);
            this.Draw(this.WhiteTexture, start, null, color, rotation, Vector2.Zero, new Vector2(length, 1), SpriteEffects.None, 0);
        }

        /// <summary>
        /// Draw a rectangle.
        /// </summary>
        /// <param name="rectangle">The rectangle to draw.</param>
        /// <param name="color">The draw color.</param>
        public void DrawRectangle(Rectangle rectangle, Color color)
        {
            this.Draw(this.WhiteTexture, new Rectangle(rectangle.Left, rectangle.Top, rectangle.Width, 1), color);
            this.Draw(this.WhiteTexture, new Rectangle(rectangle.Left, rectangle.Bottom, rectangle.Width, 1), color);
            this.Draw(this.WhiteTexture, new Rectangle(rectangle.Left, rectangle.Top, 1, rectangle.Height), color);
            this.Draw(this.WhiteTexture, new Rectangle(rectangle.Right, rectangle.Top, 1, rectangle.Height + 1), color);
        }

        /// <summary>
        /// Fill a rectangle.
        /// </summary>
        /// <param name="rectangle">The rectangle to fill.</param>
        /// <param name="color">The fill color.</param>
        public void FillRectangle(Rectangle rectangle, Color color)
        {
            this.Draw(this.WhiteTexture, rectangle, color);
        }
    }
}

答案 2 :(得分:4)

这可能不是最佳解决方案,但您应该能够使用拉伸的1x1像素纹理来适应矩形。