Introduction
Well, drawing string in XNA is very easy but to align a text in a rectangle for programmers is a problem. So here we go to solve this problem. In this tip, 9 different aligning are supported:
- Top Left
- Middle Left
- Bottom Left
- Top Center
- Middle Center
- Bottom Center
- Top Right
- Middle Right
- Bottom Right
Using the Code
So here we go.
Well struct
is first. I like them, they are the most wonderful things in programming, a structure of data.
So here we clear our mind about what a text might need. We provide kinds of alignment here in an enum
structure and then we define our aligned Text
features:
public enum TextAlignment
{
TopLeft = 0,
MiddleLeft = 1,
BottomLeft = 2,
TopCenter = 3,
MiddleCenter = 4,
BottomCenter = 5,
TopRight = 6,
MiddleRight = 7,
BottomRight = 8,
}
public struct AlignedText
{
public int key;
public string myText;
public int FontSize;
public Rectangle rect;
public Color mycolor;
public string strplaceOfUse;
public bool ShouldItBeShownInThisScreen;
public int HorizontalMargin;
public string Action;
public TextAlignment Alignment;
public Vector2 FontOrigin;
public float scale;
public Vector2 FinalPos;
}
Now, we create a class to give an aligned text to us:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
namespace Language_Learning_Application
{
public class clsTextAlignment
{
public AlignedText TextHelper(AlignedText myAlignedText,SpriteFont myFont)
{
AlignedText ReturnAlignmentText = new AlignedText();
Vector2 position = new Vector2(myAlignedText.rect.Width, myAlignedText.rect.Height);
SpriteFont font = myFont;
string fontText = myAlignedText.myText;
Vector2 fontPosition = position;
TextAlignment fontAlignment = myAlignedText.Alignment;
float fontScale = myAlignedText.scale;
Color fontColor = myAlignedText.mycolor;
Vector2 fontOrigin = Vector2.Zero;
Vector2 fontSize = font.MeasureString(fontText);
if (fontAlignment == TextAlignment.TopCenter ||
fontAlignment == TextAlignment.MiddleCenter ||
fontAlignment == TextAlignment.BottomCenter)
{
fontOrigin.X = fontSize.X / 2;
}
else if (fontAlignment == TextAlignment.TopRight ||
fontAlignment == TextAlignment.MiddleRight ||
fontAlignment == TextAlignment.BottomRight)
{
fontOrigin.X = fontSize.X;
}
if (fontAlignment == TextAlignment.MiddleLeft ||
fontAlignment == TextAlignment.MiddleCenter ||
fontAlignment == TextAlignment.MiddleRight)
{
fontOrigin.Y = fontSize.Y / 2;
}
else if (fontAlignment == TextAlignment.BottomLeft ||
fontAlignment == TextAlignment.BottomCenter ||
fontAlignment == TextAlignment.BottomRight)
{
fontOrigin.Y = fontSize.Y;
}
ReturnAlignmentText = myAlignedText;
ReturnAlignmentText.FontOrigin = fontOrigin;
if (fontAlignment == TextAlignment.TopLeft)
{
ReturnAlignmentText.FinalPos =
new Vector2(myAlignedText.rect.Left,myAlignedText.rect.Top);
}
if (fontAlignment == TextAlignment.TopRight)
{
ReturnAlignmentText.FinalPos =
new Vector2(myAlignedText.rect.Right, myAlignedText.rect.Top);
}
if (fontAlignment == TextAlignment.TopCenter)
{
ReturnAlignmentText.FinalPos =
new Vector2(myAlignedText.rect.Width / 2 +
myAlignedText.rect.X, myAlignedText.rect.Top);
}
if (fontAlignment == TextAlignment.BottomLeft)
{
ReturnAlignmentText.FinalPos =
new Vector2(myAlignedText.rect.Left, myAlignedText.rect.Bottom);
}
if (fontAlignment == TextAlignment.BottomRight)
{
ReturnAlignmentText.FinalPos =
new Vector2(myAlignedText.rect.Right, myAlignedText.rect.Bottom);
}
if (fontAlignment == TextAlignment.BottomCenter)
{
ReturnAlignmentText.FinalPos =
new Vector2(myAlignedText.rect.Width / 2 +
myAlignedText.rect.X, myAlignedText.rect.Bottom);
}
if (fontAlignment == TextAlignment.MiddleLeft)
{
ReturnAlignmentText.FinalPos =
new Vector2(myAlignedText.rect.Left,
myAlignedText.rect.Height / 2 + myAlignedText.rect.Y);
}
if (fontAlignment == TextAlignment.MiddleRight)
{
ReturnAlignmentText.FinalPos =
new Vector2(myAlignedText.rect.Right,
myAlignedText.rect.Height / 2 + myAlignedText.rect.Y);
}
if (fontAlignment == TextAlignment.MiddleCenter)
{
ReturnAlignmentText.FinalPos =
new Vector2(myAlignedText.rect.Width / 2 +
myAlignedText.rect.X, myAlignedText.rect.Height / 2 + myAlignedText.rect.Y);
}
return ReturnAlignmentText;
}
}
}
So the problem was easily solved, now we go for drawing our text in a rectangle.
Now we define our variables here:
public AlignedText myAlignedText_NumberOfTheWords;
public AlignedText[] myAlignedTexts = new AlignedText[1];
We use array to draw many of these types of text everywhere, here I just want to draw one of them.
Initializing is the most important thing you should learn, here we go:
- Remember that key is needed when you may want to have the trace of things in an arraylist
myText
is the text you want to show in the rectangle Fontsize
is our font size - Horizontal margin is our margin
- Rect here is defined with its margin
strplaceof
use is the state of your program where you may use the text- You can hide the text by "Should it be shown in this Screen" parameter
- Action here says that our text does not do anything except showing a text
- You can set the alignment what you want (there are 9 of them here)
- Font origin is what you should not change, it's just helping to have our modification position data
- The scale is what xna uses to scale things.
myAlignedText_NumberOfTheWords.key=0;
myAlignedText_NumberOfTheWords.myText="hello";
myAlignedText_NumberOfTheWords.FontSize=22;
myAlignedText_NumberOfTheWords.HorizontalMargin=50;
myAlignedText_NumberOfTheWords.rect = new Rectangle
(0 + 10 + myAlignedText_NumberOfTheWords.HorizontalMargin,
0 + 10, 300 -2* myAlignedText_NumberOfTheWords.HorizontalMargin, 200);
myAlignedText_NumberOfTheWords.mycolor=Color.Blue;
myAlignedText_NumberOfTheWords.strplaceOfUse = "AddNewWords_Word";
myAlignedText_NumberOfTheWords.ShouldItBeShownInThisScreen=false;
myAlignedText_NumberOfTheWords.Action="Text";
myAlignedText_NumberOfTheWords.Alignment=TextAlignment.MiddleCenter;
myAlignedText_NumberOfTheWords.FontOrigin=Vector2.Zero;
myAlignedText_NumberOfTheWords.scale=1;
Now that we initialize our text, we should go for drawing it on the screen.
My drawing engine is like this:
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Microsoft.Xna.Framework.Color.Black);
spriteBatch.Begin();
clsMyDefenition.DrawAlignedTexts(spriteBatch);
spriteBatch.End();
base.Draw(gameTime);
}
I use another class "clsMyDefenition
" to draw the alignedText
:
public void DrawAlignedTexts(SpriteBatch mybatch)
{
for (int i = 0; i < myAlignedTexts.Length; i++)
{
if (myAlignedTexts[i].ShouldItBeShownInThisScreen)
{
AlignedText txtToBeDrawn=myclsTextAlignment.TextHelper
(myAlignedTexts[i],fncGivemeFont(myTexts[i].FontSize));
mybatch.DrawString(fncGivemeFont(myTexts[i].FontSize),
myAlignedTexts[i].myText, txtToBeDrawn.FinalPos,
myAlignedTexts[i].mycolor, 0f, txtToBeDrawn.FontOrigin,
myAlignedTexts[i].scale, SpriteEffects.None, 0);
}
}
}
To pass our font, I created a function:
public SpriteFont fncGivemeFont(int fontsize)
{
string BaseDirectory = ".";
SpriteFont myfont=null;
switch (fontsize)
{
case 14:
{
myfont = content.Load<SpriteFont>
(BaseDirectory + "\\Font\\myfont14");
break;
}
case 16:
{
myfont = content.Load<SpriteFont>
(BaseDirectory + "\\Font\\myfont16");
break;
}
case 18:
{
myfont = content.Load<SpriteFont>
(BaseDirectory + "\\Font\\myfont18");
break;
}
case 20:
{
myfont = content.Load<SpriteFont>
(BaseDirectory + "\\Font\\myfont20");
break;
}
case 22:
{
myfont = content.Load<SpriteFont>
(BaseDirectory + "\\Font\\myfont22");
break;
}
default:
{
myfont = content.Load<SpriteFont>
(BaseDirectory + "\\Font\\myfont14");
break;
}
}
return myfont;
}
Points of Interest
So here, we learned how to align our text in a rectangle in 9 forms. Before that, you learnt how to wrap font for using in a textbox
. Cheers, now you know lots of ways to draw your strings on screen.
To hear comments from you may encourage me to put more tutorial on the web. I will be happy to know your ideas about my programming style and if I have some limitations in this tutorial.
History