Compensating for word wrap whilst typing out text on labels?

Started by Scavenger, Tue 25/03/2014 22:37:56

Previous topic - Next topic

Scavenger

I'm currently working with a few applications of typing out text letter by letter, similar to how old console RPGs did it, and it's working pretty well - except for one thing. When a word is too long for the label text area, it types out as much as it can on one line and then shunts the entire word to the line below, which is very jarring to look at. I'm not sure what the solution is called, so I didn't know what to search for, but does anyone know any tricks/code to make typing out a label compensate for this behaviour? In Heatwave I just did it manually with whitespace and [[, but I don't want to rely on that for the amount of text I need to create.

Any suggestions? I'm not quite sure how to make it type out all the letters in the locations they're going to end up in.

Crimson Wizard

#1
I have this old project scripted for one guy, but later I lost contact with him. It features auto-typed text box with any amount of lines etc.
I thought I should just give this away so that it won't become wasted time.
Maybe it will be useful to you. Feel free to use any code for reference or directly.
Full project (14 MB): http://www.mediafire.com/download/05wdfuqrti830qt/ToT.7z
Demo game (1 MB): http://www.mediafire.com/download/th9nn8e5domd9jm/ToT_indev_2012_04_17.zip

Sorry for not being more specific, it was a while since I looked into how it works, and I didn't have time to write any instructions.
I remember that the functionality is divided between "base" auto-typing text box class and "extended" child class that adds a sprite caret and overrides some methods. But the code should not be very difficult.
EDIT: Also, after having a quick look, its a WIP and those classes were not completely incapsulated, and external code have to tweak some parts in couple of cases, but this may be fixed more or less easily.

E: my aplogizes, the previous link was a compiled application, now uploaded a full project.

Scavenger

I looked over the code, and tried to replicate it on my own, but I'm having a bit of trouble with it. It splits up the first line perfectly, but the second line just gets written over and over, even though the Substring would never be over the width of the label area.

Code: AGS
 
function SplitString (String formattedspeech)
{
  String speechlines [20];
  int width = lblMVText.Width;
  int start = 0;
  int end = 1;
  int linenum = 0;
  int i;
  int j;
    while (j < formattedspeech.Length)
    {
      end = j;
      if (GetTextWidth (formattedspeech.Substring (start, end), eFontPDA) > width)
      {
        bool rewinding = true;
        while (rewinding)
        {
          if (formattedspeech.Chars [end] != ' ' || formattedspeech.Chars [end] != ',' || formattedspeech.Chars [end] != '.' || formattedspeech.Chars [end] != '!' || formattedspeech.Chars [end] != '?') rewinding = false;
          else end--;
        }
        speechlines [linenum] = formattedspeech.Substring (start, end);
        Display ("%d,%d,%d,%s",start, end,linenum, speechlines[linenum]);
        linenum ++;
        start = end;
        j = end;
      }
      else j++;
    }
  String testcase = "";
  i = 0;
  while (i < linenum)
  {
    testcase = testcase.Append (speechlines[i]);
    testcase = testcase.Append ("[");
    i++;
  }
  Display(testcase);
}


Any ideas?

Khris

I cleaned up code of mine for Chicky once, here's the PM I sent him:

I went over the RPG and removed all the stuff you won't need. Here are the source files: https://www.dropbox.com/s/2o97t6fwg8f90g3/RPG_Textbox.rar

What you need is two GUIs, one for the background and one for the foreground. Add a button to the latter one. Make them all featureless, and set their visibility to "Normal, initially off".
Set the transparency of the background one to the desired value.

Then you'll need sprites, four black background corners and 8 foreground border sprites, and two button sprites. You can rip mine if you want.
I left it all in there and added the stuff at the beginning of textbox.asc where you can set all the slots and names.

Just import the textbox script into your game, set all the values, and it should work.

Scavenger

Great! It had just the functions I needed! I gutted them and made them into a general purpose function:

Code: AGS

String FormatIntoLines(this String*, int width, FontType font) {
  int words, lines;
  String word[50], line[15];
  int wc, sp;
  String message = this;
  while (message.IndexOf(" ") > -1) {
    sp = message.IndexOf(" ");
    word[wc] = message.Substring(0, sp);
    message = message.RemoveFirst(sp+1);
    if (!String.IsNullOrEmpty(word[wc])) wc++;
  }
  word[wc] = message;
  words = wc+1;
  
  String cline = "";
  int cl; // current line dex
  int nw;
  while(nw < words) {
    // end line at [ or line width > width-16
    if (word[nw] == "[" || GetTextWidth(cline.Append(String.Format(" %s", word[nw])), font) + 32 > width) {
      line[cl] = cline;
      cline = "";
      cl++;
      if (word[nw] == "[") nw++;
    }
    else {
      if (cline == "") cline = word[nw];
      else cline = cline.Append(String.Format(" %s", word[nw]));
      nw++;
    }
  }
  line[cl] = cline;
  lines = cl + 1;
  String finaltext = "";
  int i;
  while (i < lines)
  {
    String temp = String.Format ("%s[",line[i]);
    finaltext = finaltext.Append (temp);
    i++;
  }
  return finaltext;
}


Inputting the width of a label lets you truncate lines down to the width, so it never oversteps the boundaries of the label. But without both sets of code, I don't think I would have been able to do it.

Thanks, everyone! I think I can mark this one as solved, barring some terrible mistakes on my part.

SMF spam blocked by CleanTalk