IDrawableBatch

Introduction

Although the feature set for FlatRedBall is rapidly expanding, it is impossible for the engine to handle every graphical possibility. DrawableBatches are a solution to this problem as they allow custom rendering in the engine. A DrawableBatch is a class that implements the IDrawableBatch interface, which allows user-specified rendering through XNA/MonoGame. For a full API reference of MonoGame, see the MonoGame Class Reference.

Code Example

The following code shows how to create a class that implements IDrawableBatch . This class draws a triangle which uses vertex colors - each point on the triangle is a different color.

public class DrawableBatchExample : PositionedObject, IDrawableBatch
{
    // Even though this IDB doesn't use textures, we'll use a textured vert
    // to make it easier to expand
    VertexPositionColorTexture[] verts;
    BasicEffect effect;

    public bool UpdateEveryFrame
    {
        get
        {
            return true;
        }
    }

    public DrawableBatchExample()
    {
        verts = new VertexPositionColorTexture[3];

        verts[0].Position = new Microsoft.Xna.Framework.Vector3(-200, -200, 0);
        verts[1].Position = new Microsoft.Xna.Framework.Vector3(0, 150, 0);
        verts[2].Position = new Microsoft.Xna.Framework.Vector3(200, -200, 0);

        verts[0].Color = Color.Red;
        verts[1].Color = Color.Green;
        verts[2].Color = Color.Blue;

        effect = new BasicEffect(FlatRedBallServices.GraphicsDevice);
        // The effect controls which properties are considered when DrawUserPrimitives
        // is called below. VertexColorEnabled must be set to true to get the triangle's
        // vertex colors to show up. If this is false, the triangle will be white.
        effect.VertexColorEnabled = true;
    }

    public void Destroy()
    {

    }

    public void Draw(Camera camera)
    {
        var graphicsDevice = FlatRedBallServices.GraphicsDevice;

        // Setting the view and projection makes the IDrawableBatch
        // render using FRB's camera settings. Usually IDrawableBatches
        // should use the argument camera's view and projection matrices
        effect.View = camera.View;
        effect.Projection = camera.Projection;

        foreach (var pass in effect.CurrentTechnique.Passes)
        {
            pass.Apply();

            graphicsDevice.DrawUserPrimitives(
                // Render a triangle:
                PrimitiveType.TriangleList,
                // The array of verts that we want to render
                verts,
                // The offset, which is 0 since we want to start 
                // at the beginning of the verts array
                0,
                // The number of triangles to draw
                1);
        }
    }

    public void Update()
    {

    }
}

The following code shows how the DrawableBatchExample can be used in a screen:

public partial class GameScreen
{
    DrawableBatchExample drawableBatch;
    void CustomInitialize()
    {
        drawableBatch = new DrawableBatchExample();
        SpriteManager.AddDrawableBatch(drawableBatch);
    }

    void CustomActivity(bool firstTimeCalled)
    {

    }

    void CustomDestroy()
    {
        // This calls the IDrawableBatch's Destroy method:
        SpriteManager.RemoveDrawableBatch(drawableBatch);
    }

    static void CustomLoadStaticContent(string contentManagerName)
    {

    }
}

The code above produces the following when the game runs:

Drawing SpriteBatch in FlatRedBall Coordinates

MonoGame's SpriteBatch can be used to draw sprites in FlatRedBall coordinates. For example, the following code considers the Camera's position, resolution, zoom, and the object's position:

public void Draw(Camera camera)
{
    Matrix matrix = Matrix.Identity;
    matrix *= Matrix.CreateTranslation(this.X, -this.Y, 0);
    matrix *= Matrix.CreateTranslation(
        camera.OrthogonalWidth/2.0f, camera.OrthogonalHeight/2, 0);
    matrix *= Matrix.CreateTranslation(-camera.X, camera.Y, 0);
    var scale = camera.DestinationRectangle.Height / camera.OrthogonalHeight;
    matrix *= Matrix.CreateScale(scale, scale, 1);

    spriteBatch.Begin(transformMatrix:matrix);
    spriteBatch.Draw(