Dessiner un Rectangle avec XNA

je suis en train de travailler sur le jeu. Je veux mettre en évidence un spot sur l'écran quand quelque chose arrive.

j'ai créé une classe pour faire cela pour moi, et a trouvé un peu de code pour dessiner le rectangle:

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
}

le problème est que le code ci-dessus est appelé chaque mise à jour, (60 fois par seconde), et il n'a pas été écrit avec l'optimisation à l'esprit. Il doit être extrêmement rapide (le code ci-dessus bloque le jeu, qui n'a que du code squelette en ce moment).

tous des suggestions?

Remarque: Tout nouveau code serait génial (Filaire/Remplir sont à la fois fines). Je voudrais pouvoir spécifier la couleur.

25
demandé sur CelticParser 2010-05-08 06:21:51

3 réponses

SafeArea démo sur le site du club des créateurs de XNA a un code pour faire spécifiquement cela.

vous n'avez pas à créer la Texture de chaque image, juste en LoadContent. Un très dépouillé version du code de la démo:

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();
    }
}
49
répondu Bob 2010-05-08 02:39:53

C'est comme ça que je l'ai fait. Ce n'est probablement pas la solution la plus rapide ou la meilleure, mais elle fonctionne.

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);
        }
    }
}
5
répondu wronex 2011-10-23 01:39:53

ce n'est probablement pas la meilleure solution, mais vous devriez pouvoir utiliser une texture 1x1 pixel étirée pour s'adapter au rectangle.

4
répondu Foole 2010-05-08 02:28:06