Drawing Shapes
Believe it or not, MonoGame doesn't include any methods for drawing shapes. But you can still use one of many techniques to draw shapes:
Contents
Install a Library - Primitives2d
The correct and most efficient way to draw shapes in monogame is to use draw primitives, this more difficult than using textures below: https://bitbucket.org/C3/2d-xna-primitives/wiki/Home
Using Textures
We can use a texture to draw each point of the shape, the texture is generated using 1 x 1 pixels:
Filled Rectangle
// Make a 1x1 texture named pixel.
Texture2D pixel = new Texture2D(graphicsDeviceReferenceHere, 1, 1);
// Create a 1D array of color data to fill the pixel texture with.
Color[] colorData = {
Color.White,
};
// Set the texture data with our color information.
pixel.SetData<Color>(colorData);
// Draw a fancy purple rectangle.
spriteBatch.Draw(pixel, new Rectangle(0, 0, 300, 300), Color.Purple);
Outline Only
// In LoadContent()
Texture2D pixel = new Texture2D(GraphicsDevice, 1, 1, false, SurfaceFormat.Color);
pixel.SetData(new[] { Color.White }); // so that we can draw whatever color we want on top of it
// In Draw()
spriteBatch.Begin();
Rectangle titleSafeRectangle = GraphicsDevice.Viewport.TitleSafeArea;
DrawBorder(titleSafeRectangle, 5, Color.Red); // can draw any rectangle here
spriteBatch.End();
private void DrawBorder(Rectangle rectangleToDraw, int thicknessOfBorder, Color borderColor)
{
// Draw top line
spriteBatch.Draw(_pixel, new Rectangle(rectangleToDraw.X, rectangleToDraw.Y, rectangleToDraw.Width, thicknessOfBorder), borderColor);
// Draw left line
spriteBatch.Draw(pixel, new Rectangle(rectangleToDraw.X, rectangleToDraw.Y, thicknessOfBorder, rectangleToDraw.Height), borderColor);
// Draw right line
spriteBatch.Draw(pixel, new Rectangle((rectangleToDraw.X + rectangleToDraw.Width - thicknessOfBorder),
rectangleToDraw.Y,
thicknessOfBorder,
rectangleToDraw.Height), borderColor);
// Draw bottom line
spriteBatch.Draw(pixel, new Rectangle(rectangleToDraw.X,
rectangleToDraw.Y + rectangleToDraw.Height - thicknessOfBorder,
rectangleToDraw.Width,
thicknessOfBorder), borderColor);
}
Adding new methods
You need to have a working MonoGame project, so from the project tab choose new class. Give the class a name and copy the code below (remember to keep the same namespace as your project):
using System;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
namespace DrawingShapes
{
public static class DrawShapes
{
private static Texture2D _blankTexture;
public static void LoadContent(GraphicsDevice graphicsDevice)
{
_blankTexture = new Texture2D(graphicsDevice, 1, 1, false, SurfaceFormat.Color);
_blankTexture.SetData(new[] { Color.White });
}
public static void LoadContent(Texture2D blankTexture)
{
_blankTexture = blankTexture;
}
public static void DrawLineSegment(this SpriteBatch spriteBatch, Vector2 point1, Vector2 point2, Color color, int lineWidth)
{
float angle = (float)Math.Atan2(point2.Y - point1.Y, point2.X - point1.X);
float length = Vector2.Distance(point1, point2);
spriteBatch.Draw(_blankTexture, point1, null, color,
angle, Vector2.Zero, new Vector2(length, lineWidth),
SpriteEffects.None, 0);
}
public static void DrawPolygon(this SpriteBatch spriteBatch, Vector2[] vertex, int count, Color color, int lineWidth)
{
if (count > 0)
{
for (int i = 0; i < count - 1; i++)
{
DrawLineSegment(spriteBatch, vertex[i], vertex[i + 1], color, lineWidth);
}
DrawLineSegment(spriteBatch, vertex[count - 1], vertex[0], color, lineWidth);
}
}
public static void DrawRectangle(this SpriteBatch spriteBatch, Rectangle rectangle, Color color, int lineWidth)
{
Vector2[] vertex = new Vector2[4];
vertex[0] = new Vector2(rectangle.Left, rectangle.Top);
vertex[1] = new Vector2(rectangle.Right, rectangle.Top);
vertex[2] = new Vector2(rectangle.Right, rectangle.Bottom);
vertex[3] = new Vector2(rectangle.Left, rectangle.Bottom);
DrawPolygon(spriteBatch, vertex, 4, color, lineWidth);
}
public static void DrawCircle(this SpriteBatch spritbatch, Vector2 center, float radius, Color color, int lineWidth, int segments = 16)
{
Vector2[] vertex = new Vector2[segments];
double increment = Math.PI * 2.0 / segments;
double theta = 0.0;
for (int i = 0; i < segments; i++)
{
vertex[i] = center + radius * new Vector2((float)Math.Cos(theta), (float)Math.Sin(theta));
theta += increment;
}
DrawPolygon(spritbatch, vertex, segments, color, lineWidth);
}
}
}
Now in your Game1.cs, you need to add the code below into the Initialize method:
DrawShapes.LoadContent(GraphicsDevice);
Now in the Draw method you can use the methods to draw a shape, for example:
spriteBatch.Begin();
spriteBatch.DrawRectangle(new Rectangle(0, 0, 200, 200), Color.White, 5);
spriteBatch.End();
Remember DrawRectangle, DrawPolygon, DrawCircle, and DrawLineSegment methods can be used to draw the appropriate shapes.