2010-05-08 13 views
25

Ich arbeite am Spiel. Ich möchte einen Punkt auf dem Bildschirm markieren, wenn etwas passiert.Draw Rectangle mit XNA

habe ich eine Klasse für mich zu tun, und fand ein Stück Code, um das Rechteck zu zeichnen: über jedes Update

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 
} 

Das Problem ist, dass der Code, genannt wird (60-mal pro Sekunde) und es wurde nicht mit optimierter Optimierung geschrieben. Es muss extrem schnell sein (der obige Code friert das Spiel ein, das gerade nur einen Skeleton-Code hat).

Irgendwelche Vorschläge?

Hinweis: Jeder neue Code wäre großartig (WireFrame/Fill sind beide in Ordnung). Ich möchte gerne Farbe angeben können.

Antwort

49

Die SafeArea demo auf der XNA Creators Club-Website hat Code, um genau das zu tun.

Sie müssen die Textur nicht für jeden Frame erstellen, nur in LoadContent. Eine sehr abgespeckte Version des Codes dieser Demo:

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

Danke! klappt wunderbar. – Ben

4

Dies ist wahrscheinlich nicht die beste Lösung, aber Sie sollten in der Lage sein, eine 1x1-Pixel-Textur gestreckt zu verwenden, um zum Rechteck zu passen.

+0

das ist Mittel welches? – vnshetty

5

So habe ich es gemacht. Es ist wahrscheinlich nicht die schnellste oder die beste Lösung, aber es funktioniert.

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