Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / game / XBox

XNA Batched Text Output

4.58/5 (6 votes)
2 Jul 20073 min read 1   269  
A batched text output component that is useful for debugging XNA projects.

Introduction

Note: This will be the first in a series of beginning XNA articles.

When starting an XNA project, you quickly discover that hard things are easy, and easy things are hard. One of the first things you want to do is to output some text. The TextOutput component presented here is an XNA drawable component that can output that text for you in an efficient batched manner. It was developed mainly for use as a debugging aid.

Screenshot - TextOutputDemo.png

Background

XNA is a set of software tools that make developing games and multimedia applications a lot easier. XNA is built on top of the .NET 2.0 Framework, but it includes its own environment and additional libraries. Currently only C# is officially supported by XNA, but technically any .NET language should be able to work under it. The neat part is that programs written to XNA can be compiled to run under both Windows and XBox-360.

  • You can get the latest XNA Game Studio Express from Microsoft here.
  • You will also need Microsoft's Visual C# Express. (You can create XNA projects in the pro versions of VS, but you still need Express to install Express and to compile some of the content.)

Believe it or not, the first few versions of XNA had no built in support for displaying text what-so-ever. The development community quickly came up with several solutions. But most of them involved having to run a separate program to compile your own fonts to bitmap, having to copy that bitmap file to your project and then using a library to load that bitmap into a spriteBatch so that it could be rendered onto the screen. Luckily, Microsoft decided to include a built-in solution in the latest version of XNA that simplifies things a little by having the font automatically converted by XNA's built in content management system.

Once you have the latest version of XNA GSE installed, you can go under Help to learn how to draw text on the screen. In the current version it is under:
"Help:Contents:XNA Game Studio Express:Programming Guide:How to: Draw Text."

The code example from that help is:

C#
ForegroundBatch.Begin();

// Draw Hello World
string output = "Hello World";

// Find the center of the string
Vector2 FontOrigin = CourierNew.MeasureString( output ) / 2;
// Draw the string
ForegroundBatch.DrawString( CourierNew, output, FontPos, Color.LightGreen,
    FontRotation, FontOrigin, 1.0f, SpriteEffects.None, 0.5f );
...

ForegroundBatch.End();

That is not that bad, but it is a little cumbersome. Plus, it can be slow calling the sprite batch many times.

Using the code

To use the TextOutput component, add the TextOutput.cs file to your project. Note, you will also have to create a file called Arial.SpriteFont (just copy it from the sample project).

Add a using statement to the following namespace:

C#
using UTM.CSIS.Xedge;

Add a member variable for the new object inside of your main game class:

C#
TextOutput textOutput;

Add the component to your game in its constructor:

C#
// Do this in the game's constructor
this.Components.Add(textOutput = new TextOutput(this));

Now we can easily output text to anywhere on the screen by using the WriteAt method, or we can output text that follows the mouse around by using the writeAtMouse method:

C#
textOutput.WriteAt(50, 50, "Hello World!");
textOutput.writeAtMouse("Mouse is\r\n here");

The text will be stored in a list and when the component draws itself, it will automatically draw all of the text you have submitted.

Points of Interest

You can also output text in different colors or at different rotations.

C#
textOutput.WriteAt(100, 100, "This will be red.", Color.Red);

How the Code Works

This is a component that inherits from DrawableGameComponent. Because of this, once you add this component to your main game, it will automatically Load and Draw itself.

Here is a class diagram that shows how the class is setup. By the way, did you know you can generate these neat diagrams right from Visual Studio just by right-clicking on the class?

Screenshot - TextOutputClassDiagram.png

The most important method is the WriteAt method. It simply adds the text and attributes to a list as shown below. It is overloaded so that you can call it with or without the color parameter.

C#
public void WriteAt(int x, int y, string s, Color c)
{
     //create a new textNode
     textNode n = new textNode();
     //populate x pos
     n.X = x;
     //populate y pos
     n.Y = y;
     //populate string
     n.Text = s;
     //set color
     n.FontColor = c;
     //set rotation
     n.Rotation = m_FontRotation;
     //add to the batch list
     m_List.Add(n);
}

The WriteAt method uses the following struct to hold the text and attributes:

C#
struct textNode
{
     public int X, Y;
     public string Text;
     public Color FontColor;
     public float Rotation;
}

Now, when it comes time to draw, the code simply loops though the list and outputs all of the text in one fast sprite batch.

C#
public override void Draw(GameTime gameTime)
{
     base.Draw(gameTime);
     if (m_Enabled)//if we want text rendered
     {
          m_SpriteBatch.Begin(SpriteBlendMode.AlphaBlend, 
                SpriteSortMode.FrontToBack, SaveStateMode.SaveState);
          //foregBatch.Begin();  
          // This is quicker, but may cause side-effects

          foreach (textNode n in m_List)
          {
               m_SpriteBatch.DrawString(m_SpriteFont, n.Text, 
                            new Vector2(n.X, n.Y), n.FontColor,
               n.Rotation, new Vector2(0, 0), 1.0f, SpriteEffects.None, 0.5f);
          }
          m_SpriteBatch.End();
          m_List.Clear();
     }//end if (m_Enabled)
}

Note, the Draw method will be called for us automatically, since we inherited the class from the DrawableGameComponent base class.

History

  • Version 1.0 - July 2, 2007

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here