2012-06-27 3 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은 두 번째 줄이 끝나는 곳입니다. 빌더는 .Remove 명령 앞에 다음과 같습니다 : " 을 : 이

하고는 다음과 같습니다 실행 한 후"이 \ 여러 라인으로 분할하는 \ nhas r에 긴 연설의 예입니다 C " 이것은 여러 줄로 나눌 긴 연설의 예입니다 "

세 번째 줄은 i = 123 및 lastSpace = 120에서 크기 제한을 초과합니다. .Remove : "이것은 여러 줄로 \ r \ n 여러 줄로 나뉘는 긴 연설의 한 예입니다. 몇 줄이고 길이가 여러 줄입니다."

이후 : "이 말은 \ r \ n 여러 줄로 \ r \ n 제대로 나눌 긴 연설의 한 예입니다. 그것은 몇 줄의 길이입니다 "

문자에서 볼 수 있듯이, 문자 80이 그 공간에서 제거를 시작해야하는 곳이라 할지라도, 내가 읽은 부분에서. 단일 매개 변수를 사용하여 주어진 인덱스를 포함하여 모든 것을 제거합니다. 그러나 i = 79도 역시 삭제됩니다! lastSpace를 추가하거나 빼기는 쉽지만, 인덱스 범위 밖으로 "오류 또는 더 많은 문자를 잘라냅니다. 내가 시도한 .Remove (lastSpace, i-lastSpace) 및 그 중 하나가 작동하지 않습니다. lastSpace에서 더하거나 뺍니다. 다른 방법으로 해체하려고 시도했지만 그 중 아무 것도 효과가 없었습니다.

나는 이것을 보면서 지겨워서 어떤 도움을 주신다면 감사하겠습니다.

답변

1

StringBuilderEnvironment.NewLine을 추가하면 제거를 시작할 색인을 지정할 때 고려해야합니다.

Environment.NewLine의 값은 시스템에 따라 다릅니다. "\r\n", "\n" 또는 "\r" (또는 처음 두 개 중 하나만 according to MSDN) 중 하나 일 수 있습니다.
귀하의 경우는 "\r\n"입니다. 즉, 한 칸을 지우려면 다른 두자를 추가해야합니다.한 줄의 텍스트를 추가 할 때 다음

int additionalChars = 0; 

이, 당신이 이런 식으로 코드를 변경해야합니다 : :이 -1

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

첫째, 당신은 새 변수를 선언 할 필요가 이미 공간을 제거 했으므로 (이 코드를 시스템 정의 Environment.NewLine과 독립적으로 만들어야합니다.)

업데이트 : 줄 제한보다 긴 단어도 고려해야합니다. 당신은 (도움이되지만 시도가 없습니다) 어쨌든 휴식해야합니다

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을 호출합니다. 단어가 들어갈 때 Append 인 StringBuilder를 사용하거나 적합하지 않아서 줄 바꿈을 추가해야하는 경우 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());