7
\$\begingroup\$

I would like to be able to draw arbitary lines in my sprite based 2D XNA game. How can I draw a simple line on screen in XNA without dealing with vertex arrays or shaders.

\$\endgroup\$
  • \$\begingroup\$ Hey Ken, take a look at my little drawinghelper library: drippingflames.com/xna It uses vertex arrays in the background, so no 1x1 white texture. \$\endgroup\$ – Luis Estrada Nov 19 '12 at 14:05
  • 1
    \$\begingroup\$ @LuisEstrada, I downloaded your code and it works awesome, thank you for that. However, as a small sidenote, the dll isn't compatible with the default Reach Profile nowadays. No biggie, but you have to set it to include stuff that breaks support with Windows Mobile (HiDef). Just so you know. \$\endgroup\$ – Digitalis May 5 '17 at 16:00
  • \$\begingroup\$ @LuisEstrada, No problem, would you like the exact error and dev env to reproduce? \$\endgroup\$ – Digitalis May 5 '17 at 18:32
  • \$\begingroup\$ @Digitalis, sure send it to my email. It is on the page I linked. \$\endgroup\$ – Luis Estrada May 5 '17 at 18:49
19
\$\begingroup\$

You can draw a line using sprites. SpriteBatch.Draw(...) helpfully allows us to strech and rotate a sprite(texture).

In this code, we take a 1x1 pixel texture, strech it (by defining a rectangle of the correct shape and rotate it so it looks like a line.

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

    }
\$\endgroup\$
  • 2
    \$\begingroup\$ Something I want to note about this sort of line code is that it can need a little adjustment if you use a width greater than one. Because we're defining the height relative to the starting coordinates, using a length of more than 1 will make the line extend down, and if you have, for example, two separate 3-pixel lines with one rotated 180 degrees, one will extend up and one down. To fix this you can adjust the starting X coordinate based on the width of the line, like start.X - width / 2 \$\endgroup\$ – ssb Nov 19 '12 at 13:03

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.