【问题标题】:Draw Rectangle with XNA使用 XNA 绘制矩形
【发布时间】:2011-02-17 01:45:47
【问题描述】:

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

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

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 都可以)。我希望能够指定颜色。

【问题讨论】:

    标签: c# optimization xna


    【解决方案1】:

    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();
        }
    }
    

    【讨论】:

      【解决方案2】:

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

      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);
              }
          }
      }
      

      【讨论】:

        【解决方案3】:

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

        【讨论】:

          猜你喜欢
          • 2011-08-10
          • 1970-01-01
          • 2014-01-14
          • 2014-03-20
          • 2020-11-25
          • 2021-08-08
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多