2012-06-27 12 views
1

我在製作遊戲,並從XML文件讀取對話文本。我試圖按照需要自動添加新行,以便它適合文本框。儘管如此,它不會正常工作。下面的代碼,因爲它目前是:試圖製作一個文本解析器,在需要的地方插入換行符,但它並不工作

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; 

我的測試字符串是「這是一個長期的講話中指出,必須正確地劃分爲多個行的一個例子,是幾行長並沒有真正說任何重要的東西,因爲它只是示例文本。「

這是怎麼講話結束了尋找: http://www.iaza.com/work/120627C/iaza11394935036400.png

第一線工作,因爲它正好是它帶來了超過限制的空間,我想。

i = 81且lastSpace = 80是第二行結束的地方。助洗劑看起來像這樣的卸下襬臂命令之前: 「這是一個長的語音即\ r \ n已被分解成多行的一個實施例C」

並且運行它看起來像這樣後: 「這是一個很長的演講的例子,它必須分成多行「

第三行超出了i = 123和lastSpace = 120的大小限制。它看起來像這樣.Remove : 「這是一個很長的演講的例子,它必須正確地分成多行,它有幾行,並且」

和之後: 「這是一個長時間演講的例子,它必須正確地分解成多行。它是幾行長的「

正如你所看到的,即使字符80,該空格是它應該開始刪除的地方,它會切斷一個額外的字符。從我讀的東西中刪除。只用一個參數就可以刪除包括給定索引在內的所有內容,但它也會刪除i = 79,看起來它應該很容易從lastSpace中加上或減去以彌補這一點,但是我可以得到「索引越界「的錯誤,或者我截斷了更多的字符,我試着去做.Remove(lastSpace,i-lastSpace),這也是行不通的。與其他人不同,通過增加或減少lastSpace。我試圖以不同的方式分解東西,並且它們都沒有工作。我很厭煩看這個,任何幫助將不勝感激。

回答

1

您將Environment.NewLine添加到您的StringBuilder,您需要考慮當您指定索引從何處開始移除。

Environment.NewLine的值取決於系統。它可以是"\r\n""\n""\r"(或者只有前兩個according to MSDN之一)。
在你的情況下,它是"\r\n",這意味着要刪除一個空間,你添加了兩個其他字符。

首先,你需要聲明一個新的變量:

int additionalChars = 0; 

然後,添加一行文本的時候,你應該更改您的代碼是這樣的:

builder = builder.Remove(lastSpace + additionalChars); //cut off from last space 
builder += Environment.NewLine; 
additionalChars += Environment.NewLine.Length - 1; 

-1是因爲您已經刪除了一個空格(應使此代碼獨立於系統的Environment.NewLine定義)。

UPDATE:您還應該考慮長度超過限制的單詞。無論如何,你應該打破他們(忍不住試試):

if (stringLength > maxWidth) //longer than allowed 
{ 
    // Cut off only if there was a space to cut off at 
    if (lastSpace >= 0) { 
     builder = builder.Remove(lastSpace + additionalChars); //cut off from last space 
     i = lastSpace; //start back from the cutoff 
    } 
    builder += Environment.NewLine; 
    // If there was no space that we cut off, there is also no need to subtract it here 
    additionalChars += Environment.NewLine.Length - (lastSpace >= 0 ? 1 : 0); 
    lastSpace = -1; // Means: No space found yet 
    newestLine = ""; 
} 
+0

好吧,這使我現在。我想我一直在想換行符是「不是真的嗎」?現在感覺有點傻,但是非常感謝。 –

1

作爲一種替代方法,您可以使用.split將句子分解爲數組,然後填充您的框,直到下一個工作沒有空間,然後添加換行符並開始下一行。

0

你能做些像下面的代碼。優點是雙重的。首先,它跳到下一個空間來衡量並決定是否添加整個單詞,而不是一個接一個地逐字。其次,它只爲字符串中的每個單詞調用一次MeasureString,而不是添加到字符串中的每個字母。它使用的StringBuilder與Append當單詞將適合,或AppendLine當它不適合和需要添加一個新行。

 int lastSpace = 0; 
     int nextSpace = s.IndexOf(' ', lastSpace + 1); 
     float width = 0; 
     float totalWidth = 0; 
     float maxWidth = 200; 
     while (nextSpace >= 0) 
     { 
      string piece = s.Substring(lastSpace, nextSpace - lastSpace); 
      width = g.MeasureString(piece, this.Font).Width; 
      if (totalWidth + width < maxWidth) 
      { 
       sb.Append(piece); 
       totalWidth += width; 
      } 
      else 
      { 
       sb.AppendLine(piece); 
       totalWidth = 0; 
      } 
      lastSpace = nextSpace; 
      nextSpace = s.IndexOf(' ', lastSpace + 1); 
     } 
     MessageBox.Show(sb.ToString()); 
相關問題