Daniel Tian’s Professional Blog

Icon

Just another WordPress.com weblog

XNA Tutorial: typewriter text box with proper word wrapping – Part 1

This is Part 1 of 3 and covers how to create a text box for the text to go in.
Go to Part 2
Go to Part 3

Today’s post will be about how to implement a typewriter text box (where the letters appear one after another) with proper word wrapping in XNA. It seems deceptively simple if you’ve never tried it before, but there is a slight issue with text wrapping that you have to account for. Let’s use a tutorial to illustrate what I mean. This tutorial is written for XNA 3.0 but should work on 2.0 also. Also, I assume that you have adequate programming experience.

Creating the text box
Create a new Windows Game project and name it TextBox (or whatever you want to call it), then open up Game1.cs. We’ll begin by creating a text box using a Rectangle. We don’t need to use a Rectangle to display text onto the screen, but we’ll see why this is a good thing later on. First, declare a new instance variable:

Rectangle textBox;

If you don’t know what an instance variable is, it’s a variable that’s defined at the beginning of the class (and inside it) but outside of any methods, so that it’s accessible by any method in the class. Therefore, in Game1.cs, it should be put after the two lines that are already there so that it looks like this:

GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;
Rectangle textBox;

Remember this location because we’ll be creating several more instance variables throughout this tutorial. Ok, now that we declared textBox, we need to set its size and position. Put the following code in the Initialize() method, before base.Initialize():

textBox = new Rectangle(10, 10, 300, 300);

As a side note, this line can be put in the LoadContent() instead of Initialize(). There are some differences between the two methods that you can read more about it in this post but for the purposes of this tutorial let’s leave it in Initialize().

This will put textBox at coordinates (10, 10) set its size to a 300×300 box. If you run the program now, you won’t see anything because we haven’t drawn textBox yet. We will do that next.

Drawing the text box
Drawing the text box requires us to load in a texture. This is because a Rectangle cannot be drawn directly. It only defines a boundary, useful for things such as collision detection and, in our case, the boundary that the texture will be drawn in. If you don’t understand what this means, you should after you draw it. I’ve provided a 1-pixel solid red dot that you can download here (right click and pick Save Image As).

Switch over to Visual C# and import it into your project by right-clicking on Content in the Solution Explorer (by default, the right pane) and select Add -> Existing Item, then add the solidred.png image you downloaded.

Now we need to create a new Texture2D object and load the texture into it. Write the following code:

Instance variable:

Texture2D debugColor;

In the LoadContent() method, under the TODO comment:

debugColor = Content.Load<Texture2D>("solidred");

Now we can draw the text box onto the screen with the debugColor texture in it. Put this code in the Draw() method, under the TODO comment and before base.Draw(gameTime):

spriteBatch.Begin();
spriteBatch.Draw(debugColor, textBox, Color.White);
spriteBatch.End();

Make sure the s in spriteBatch is lower-case or else you’ll be using the SpriteBatch object rather than the spriteBatch variable. Always remember to Begin() and End() your spriteBatch or else nothing will be drawn. The Draw() method works like this: Draw(texture, rectangle, color tint). We tell it to draw the 1-pixel solid red color inside the rectangle boundary with a color of white so it’s not tinted. By default, the texture will tile both horizontally and vertically within the rectangle. If you run the program now, you should see the following image:

textbox1

It doesn’t look very pretty, but this will show us where the text box is located for debugging purposes. This is where using a Rectangle shows its first usefulness. By drawing the red pixel with the Rectangle as its boundary, the pixel will fill the entire Rectangle and we can see what the text box looks like and move it around and resize it easily. When we’re done, we can hide it by either commenting out the Draw() method call (recommended) or by changing the color to Color.TransparentBlack (not recommended because it still draws the box).

Conclusion
This concludes Part 1 of the tutorial. We set up the text box and it’s now ready to get some text drawn in it, which is what we’ll cover in Part 2 of the tutorial.
Go to Part 2

Source code
This is what your Game1.cs should look like at the end of this tutorial. If you’re copying and pasting this code, make sure you import the solidred.png image into your project.

using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;

namespace TextBox
{
    /// <summary>
    /// This is the main type for your game
    /// </summary>
    public class Game1 : Microsoft.Xna.Framework.Game
    {
        GraphicsDeviceManager graphics;
        SpriteBatch spriteBatch;
        Rectangle textBox;
        Texture2D debugColor;

        public Game1()
        {
            graphics = new GraphicsDeviceManager(this);
            Content.RootDirectory = "Content";
        }

        /// <summary>
        /// Allows the game to perform any initialization it needs to before starting to run.
        /// This is where it can query for any required services and load any non-graphic
        /// related content.  Calling base.Initialize will enumerate through any components
        /// and initialize them as well.
        /// </summary>
        protected override void Initialize()
        {
            // TODO: Add your initialization logic here
            textBox = new Rectangle(10, 10, 300, 300);

            base.Initialize();
        }

        /// <summary>
        /// LoadContent will be called once per game and is the place to load
        /// all of your content.
        /// </summary>
        protected override void LoadContent()
        {
            // Create a new SpriteBatch, which can be used to draw textures.
            spriteBatch = new SpriteBatch(GraphicsDevice);

            // TODO: use this.Content to load your game content here
            debugColor = Content.Load<Texture2D>("solidred");
        }

        /// <summary>
        /// UnloadContent will be called once per game and is the place to unload
        /// all content.
        /// </summary>
        protected override void UnloadContent()
        {
            // TODO: Unload any non ContentManager content here
        }

        /// <summary>
        /// Allows the game to run logic such as updating the world,
        /// checking for collisions, gathering input, and playing audio.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        protected override void Update(GameTime gameTime)
        {
            // Allows the game to exit
            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
                this.Exit();

            // TODO: Add your update logic here

            base.Update(gameTime);
        }

        /// <summary>
        /// This is called when the game should draw itself.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        protected override void Draw(GameTime gameTime)
        {
            GraphicsDevice.Clear(Color.CornflowerBlue);

            // TODO: Add your drawing code here
            spriteBatch.Begin();
            spriteBatch.Draw(debugColor, textBox, Color.White);
            spriteBatch.End();

            base.Draw(gameTime);
        }
    }
}
Advertisements

Filed under: XNA Tutorials, , , , , , , , , , , ,

2 Responses

  1. […] XNA Tutorial: typewriter text box with proper word wrapping – Part 1 « Daniel Tian’s Pro… Says: December 24, 2008 at 3:17 pm […]

  2. […] This is Part 3 of 3 and covers how to make the text ‘type out’ letter by letter. Go to Part 1 Go to Part […]

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: