I ran into this problem and decided to create a LineBatch class. LineBatch will draw lines without the need for spriteBatch or dots. Class below.
public class LineBatch { bool cares_about_begin_without_end; bool began; GraphicsDevice GraphicsDevice; List<VertexPositionColor> verticies = new List<VertexPositionColor>(); BasicEffect effect; public LineBatch(GraphicsDevice graphics) { GraphicsDevice = graphics; effect = new BasicEffect(GraphicsDevice); Matrix world = Matrix.Identity; Matrix view = Matrix.CreateTranslation(-GraphicsDevice.Viewport.Width / 2, -GraphicsDevice.Viewport.Height / 2, 0); Matrix projection = Matrix.CreateOrthographic(GraphicsDevice.Viewport.Width, -GraphicsDevice.Viewport.Height, -10, 10); effect.World = world; effect.View = view; effect.VertexColorEnabled = true; effect.Projection = projection; effect.DiffuseColor = Color.White.ToVector3(); cares_about_begin_without_end = true; } public LineBatch(GraphicsDevice graphics, bool cares_about_begin_without_end) { this.cares_about_begin_without_end = cares_about_begin_without_end; GraphicsDevice = graphics; effect = new BasicEffect(GraphicsDevice); Matrix world = Matrix.Identity; Matrix view = Matrix.CreateTranslation(-GraphicsDevice.Viewport.Width / 2, -GraphicsDevice.Viewport.Height / 2, 0); Matrix projection = Matrix.CreateOrthographic(GraphicsDevice.Viewport.Width, -GraphicsDevice.Viewport.Height, -10, 10); effect.World = world; effect.View = view; effect.VertexColorEnabled = true; effect.Projection = projection; effect.DiffuseColor = Color.White.ToVector3(); } public void DrawAngledLineWithRadians(Vector2 start, float length, float radians, Color color) { Vector2 offset = new Vector2( (float)Math.Sin(radians) * length, //x -(float)Math.Cos(radians) * length //y ); Draw(start, start + offset, color); } public void DrawOutLineOfRectangle(Rectangle rectangle, Color color) { Draw(new Vector2(rectangle.X, rectangle.Y), new Vector2(rectangle.X + rectangle.Width, rectangle.Y), color); Draw(new Vector2(rectangle.X, rectangle.Y), new Vector2(rectangle.X, rectangle.Y + rectangle.Height), color); Draw(new Vector2(rectangle.X + rectangle.Width, rectangle.Y), new Vector2(rectangle.X + rectangle.Width, rectangle.Y + rectangle.Height), color); Draw(new Vector2(rectangle.X, rectangle.Y + rectangle.Height), new Vector2(rectangle.X + rectangle.Width, rectangle.Y + rectangle.Height), color); } public void DrawOutLineOfTriangle(Vector2 point_1, Vector2 point_2, Vector2 point_3, Color color) { Draw(point_1, point_2, color); Draw(point_1, point_3, color); Draw(point_2, point_3, color); } float GetRadians(float angleDegrees) { return angleDegrees * ((float)Math.PI) / 180.0f; } public void DrawAngledLine(Vector2 start, float length, float angleDegrees, Color color) { DrawAngledLineWithRadians(start, length, GetRadians(angleDegrees), color); } public void Draw(Vector2 start, Vector2 end, Color color) { verticies.Add(new VertexPositionColor(new Vector3(start, 0f), color)); verticies.Add(new VertexPositionColor(new Vector3(end, 0f), color)); } public void Draw(Vector3 start, Vector3 end, Color color) { verticies.Add(new VertexPositionColor(start, color)); verticies.Add(new VertexPositionColor(end, color)); } public void End() { if (!began) if (cares_about_begin_without_end) throw new ArgumentException("Please add begin before end!"); else Begin(); if (verticies.Count > 0) { VertexBuffer vb = new VertexBuffer(GraphicsDevice, typeof(VertexPositionColor), verticies.Count, BufferUsage.WriteOnly); vb.SetData<VertexPositionColor>(verticies.ToArray()); GraphicsDevice.SetVertexBuffer(vb); foreach (EffectPass pass in effect.CurrentTechnique.Passes) { pass.Apply(); GraphicsDevice.DrawPrimitives(PrimitiveType.LineList, 0, verticies.Count / 2); } } began = false; } public void Begin() { if (began) if (cares_about_begin_without_end) throw new ArgumentException("You forgot end."); else End(); verticies.Clear(); began = true; } }