Adding New Base Classes


That's all the changes you need to make to the existing classes you got from the Blockers game, but now you should add a new control, something that you haven't done before but that is commonthe text box. This object is actually pretty simple, so go ahead and add the class in Listing 12.5 to your gui.cs code file (might as well keep all the base classes together).

Listing 12.5. The Text Box
 public class UiTextBox {     private Texture textureSource = null;     private Rectangle textureRect;     private Rectangle textRectangle;     private Point renderLocation;     private Direct3D.Font textFont = null;     private string currentText = string.Empty;     private bool enabled = false;     /// <summary>     /// Create a new text box     /// </summary>     public UiTextBox(Device device, Texture background, Rectangle source,       Point loc, GameEngine parent)     {         // Store the information         textureSource = background;         textureRect = source;         renderLocation = loc;         textRectangle = new Rectangle(loc.X + 20, loc.Y + 15,             source.Width-40, source.Height - 30);         // Create the font         textFont = new Direct3D.Font(device, new System.Drawing.Font(             parent.Font.Name, 20.0f));         // Hook the device events to handle fonts         device.DeviceLost += new EventHandler(OnDeviceLost);         device.DeviceReset += new EventHandler(OnDeviceRest);         // Hook the keyboard         parent.KeyPress += new KeyPressEventHandler(OnKeyPress);     } } 

Here, the "background" of the text box is stored as a texture, much like the background of the user screens and buttons. Because the texture might contain more than just the text-box background, you need to store the source rectangle. You also want a separate rectangle to do clipping on the text that you will be drawing. (It will be slightly smaller than the rectangle for the texture.) You also need to know exactly where on the screen you should be drawing this text box. The renderLocation variable is the upper-left corner of this position. You need something to actually render the text currently being held (and the text itself), and as with the buttons, you want to make sure that you know when you're enabled.

The constructor mainly stores the information being passed in for later rendering; however; it does do a few new things. First, it calculates the rectangle to be used for rendering the text by "shrinking" the rectangle size of the source texture. It creates a new font that is pretty much a duplicate of the main font the window is using, just with a larger size. Remember from earlier chapters, you need to ensure that the font is handled during a device lost and reset event, so those events are hooked now. Because this is a text box, hooking the KeyPress event is probably a good idea as well. You can find the event handlers in Listing 12.6.

Listing 12.6. Text Box Event Handlers
 private void OnDeviceLost(object sender, EventArgs e) {     System.Diagnostics.Debug.Assert(textFont != null, "Font cannot be null.");     textFont.OnLostDevice(); } private void OnDeviceRest(object sender, EventArgs e) {     System.Diagnostics.Debug.Assert(textFont != null, "Font cannot be null.");     textFont.OnResetDevice(); } private void OnKeyPress(object sender, KeyPressEventArgs e) {     if (!enabled)     {         // Nothing to do         return;     }     if (e.KeyChar == (char)8)     {         if (currentText.Length > 0)         {             // Remove a char             currentText = currentText.Substring(0, currentText.Length - 1);         }     }     else     {         currentText += e.KeyChar;     } }v 

The two device events are short because they only need to call the appropriate method on the font. The key-press event handler is a little more complex because it has a couple of things to do. First, if the text box isn't enabled, just exit the handler because there's nothing for it to do. You're probably wondering where the check against (char)8 comes from. This key character is the magic code for a backspace, so when that key is pressed, the current text string is shortened by one character (assuming it has any characters in it). Otherwise, the new character is simply appended to the string you're storing.

You haven't yet added any properties to access the text that has been entered or a way to enable or disable the text box, so you should add these two properties to your class now:

 public bool IsEnabled {     get { return enabled; }     set { enabled = value; } } public string Text {     get { return currentText; } } 

The only thing you have left to do before you're finished is actually render the text box. Add the method in Listing 12.7 to your class to handle this.

Listing 12.7. Rendering a Text Box
 public virtual void Draw(Sprite renderSprite, int color) {     // Render the element if it exists     if (textureSource != null)     {         // Render to the screen centered         renderSprite.Draw(textureSource, textureRect,             UiScreen.ObjectCenter, new Vector3(renderLocation.X,             renderLocation.Y, 1.0f), UiScreen.SpriteColor);         // Render text         textFont.DrawText(renderSprite, currentText, textRectangle,             DrawTextFormat.None, color);     } } 

Nothing complex: you simply use the passed-in sprite and render the background of the text box on it. Then, you call DrawText with the font you created earlier and draw that text directly on the sprite that was passed in. Did you notice that the DrawTextFormat.None flag is passed in? This causes the font object to automatically clip the text so it doesn't go beyond the rectangle you have defined. You also draw the text in any color you want (based on what the user passes in).



Beginning 3D Game Programming
Beginning 3D Game Programming
ISBN: 0672326612
EAN: 2147483647
Year: 2003
Pages: 191
Authors: Tom Miller

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net