I’m making a game, and I read dialogue text from an XML file. I’m trying to make a routine to add in newlines automatically as needed, so that it fits in the text box. It just won’t work right, though. Here’s the code as it currently is:
SpriteFont dialogueFont = font31Adelon;
int lastSpace = 0;
string builder = "";
string newestLine = "";
float maxWidth = 921.6f;
float stringLength = 0;
for (int i = 0; i <= speech.Length - 1; i++) //each char in the string
{
if (speech[i] == ' ') //record the index of the most recent space
{
lastSpace = i;
}
builder += speech[i];
newestLine += speech[i];
stringLength = dialogueFont.MeasureString(newestLine).X;
if (stringLength > maxWidth) //longer than allowed
{
builder = builder.Remove(lastSpace); //cut off from last space
builder += Environment.NewLine;
i = lastSpace; //start back from the cutoff
newestLine = "";
}
}
speech = builder;
My test string is “This is an example of a long speech that has to be broken up into multiple lines correctly. It is several lines long and doesn’t really say anything of importance because it’s just example text.”
This is how speech ends up looking:
http://www.iaza.com/work/120627C/iaza11394935036400.png
The first line works because it happens to be a space that brings it over the limit, I think.
i = 81 and lastSpace = 80 is where the second line ends. builder looks like this before the .Remove command:
“This is an example of a long speech that\r\nhas to be broken up into multiple lines c”
and after it is run it looks like this:
“This is an example of a long speech that\r\nhas to be broken up into multiple line”
The third line goes over the size limit at i = 123 and lastSpace = 120. It looks like this before the .Remove:
“This is an example of a long speech that\r\nhas to be broken up into multiple line\r\ncorrectly. It is several lines long and doe”
and after:
“This is an example of a long speech that\r\nhas to be broken up into multiple line\r\ncorrectly. It is several lines long an”
As you can see, it cuts off an extra character, even though character 80, that space, is where it’s supposed to start removing. From what I’ve read .Remove, when called with a single parameter, cuts out everything including and after the given index. It’s cutting out i = 79 too, though! It seems like it should be easy enough to add or subtract from lastSpace to make up for this, but I either get “index out of bounds” errors, or I cut off even more characters. I’ve tried doing .Remove(lastSpace, i-lastSpace), and that doesn’t work either. I’ve tried handling “ends with a space” cases differently than others, by adding or subtracting from lastSpace. I’ve tried breaking things up in different ways, and none of it has worked.
I’m so tired of looking at this, any help would be appreciated.
You add
Environment.NewLineto yourStringBuilder, you need to consider that when you specify the index where to start removing.Environment.NewLine‘s value is System dependent. It can be"\r\n","\n"or"\r"(or, only one of the first two according to MSDN).In your case it’s
"\r\n", that means for removing one space, you added two other characters.First, you need to declare a new variable:
Then, when adding a line of text, you should change your code to something like this:
The
-1is because you already removed a space (should make this code independent of the system’s definition ofEnvironment.NewLine).UPDATE: You should also account for words that are longer than the line limit. You should break them anyway (couldn’t help but have a try):