Wie kann ich in XNA eine einfache 2D-Linie zeichnen, ohne 3D-Grundelemente und Shder zu verwenden?

7

Ich möchte in meinem Sprite-basierten 2D-XNA-Spiel beliebige Linien zeichnen können. Wie kann ich in XNA eine einfache Linie auf dem Bildschirm zeichnen, ohne mich mit Vertex-Arrays oder Shadern zu befassen?

Ken
quelle
Hey Ken, werfen Sie einen Blick auf meine kleine drawinghelper Bibliothek: drippingflames.com/xna Es verwendet Vertex Arrays im Hintergrund, so dass keine 1x1 weiß Textur.
Luis Estrada
1
@LuisEstrada, ich habe deinen Code heruntergeladen und er funktioniert fantastisch, danke dafür. Als kleine Nebenbemerkung ist die DLL heutzutage jedoch nicht mit dem Standard-Reach-Profil kompatibel. Kein Problem, aber Sie müssen festlegen, dass Inhalte enthalten sind, die die Unterstützung von Windows Mobile (HiDef) beeinträchtigen. Nur damit du es weißt.
Digitalis
@LuisEstrada, Kein Problem, möchten Sie den genauen Fehler und die dev env reproduzieren?
Digitalis
@ Digitalis, senden Sie es sicher an meine E-Mail. Es ist auf der Seite, die ich verlinkt habe.
Luis Estrada

Antworten:

19

Sie können eine Linie mit Sprites zeichnen. Mit SpriteBatch.Draw (...) können wir ein Sprite (Textur) strecken und drehen.

In diesem Code nehmen wir eine 1x1-Pixel-Textur, strecken sie (indem wir ein Rechteck mit der richtigen Form definieren und es so drehen, dass es wie eine Linie aussieht.

    Texture2D t; //base for the line texture


    protected override void LoadContent()
    {
        spriteBatch = new SpriteBatch(GraphicsDevice);
        // create 1x1 texture for line drawing
        t = new Texture2D(GraphicsDevice, 1, 1);
        t.SetData<Color>(
            new Color[] { Color.White });// fill the texture with white
    }


    protected override void Draw(GameTime gameTime)
    {


        GraphicsDevice.Clear(Color.CornflowerBlue);

        spriteBatch.Begin();
        DrawLine(spriteBatch, //draw line
            new Vector2(200, 200), //start of line
            new Vector2(100, 50) //end of line
        );
        spriteBatch.End();



        base.Draw(gameTime);
    }


    void DrawLine(SpriteBatch sb, Vector2 start, Vector2 end)
    {
        Vector2 edge = end - start;
        // calculate angle to rotate line
        float angle =
            (float)Math.Atan2(edge.Y , edge.X);


        sb.Draw(t,
            new Rectangle(// rectangle defines shape of line and position of start of line
                (int)start.X,
                (int)start.Y,
                (int)edge.Length(), //sb will strech the texture to fill this rectangle
                1), //width of line, change this to make thicker line
            null,
            Color.Red, //colour of line
            angle,     //angle of line (calulated above)
            new Vector2(0, 0), // point in line about which to rotate
            SpriteEffects.None,
            0);

    }
Ken
quelle
2
Bei dieser Art von Zeilencode möchte ich darauf hinweisen, dass eine kleine Anpassung erforderlich sein kann, wenn Sie eine Breite größer als eins verwenden. Da wir die Höhe relativ zu den Startkoordinaten definieren, wird bei Verwendung einer Länge von mehr als 1 die Linie nach unten verlängert. Wenn Sie beispielsweise zwei separate 3-Pixel-Linien mit einer um 180 Grad gedrehten Linie haben, wird eine Linie verlängert hoch und eins runter. Um dies zu beheben, können Sie die Start-X-Koordinate basierend auf der Breite der Linie anpassen, wie z. B. start.X - width / 2
ssb