RPG Dialogue Boxes

Hi friends,

I’ve been using the Slick2D engine to get into java game development, and I have been trying to develop an RPG. I’ve encountered an issue with trying to properly handle text/dialogue boxes. An example of what I’m essentially trying to do (click on the little application at the top of the article):

I’d follow this tutorial, but it’s in Flash and I’m not quite sure how to pull whatever algorithm that’s being used to my situation. So, any suggestions as to how I could approach this? Any help would be fantastic :slight_smile:

EDIT: I believe the term here I’m looking for is “text wrapping,” and essentially I just want to wrap the text to the text line when it no longer fits the box.

This is how I handle text wrapping in my Font.java class.

public String[] split(String fLine, float maxWidthInPixels, float scale){
		String[] lines = new String[10];
		int lineArrayIndex = 0;
		float curWidth = 0;
		int lastSpaceIndex = 0;
		int startIndex = 0;
		for(int i = 0;i < fLine.length();i++){
			String temp = fLine.substring(i, i + 1);// letter
			if(temp.equals(" ")) lastSpaceIndex = i + 1; // the + 1 accounts for the space, so that the space isn't place at the beginning of the next line.
			curWidth += getLength(temp) * scale;
			
			if(curWidth >= maxWidthInPixels){
				i = lastSpaceIndex;
				lines[lineArrayIndex] = fLine.substring(startIndex, lastSpaceIndex);
				startIndex = lastSpaceIndex;
				curWidth = 0;
				lineArrayIndex ++;
				
			}
		}
		lines[lineArrayIndex] = fLine.substring(startIndex, fLine.length());
		return lines;
	}

Another variant that I used from many helpers here at JGO.

	public static ArrayList<Map.Entry<String, Boolean>> toLines(String all, final int regex) {
		ArrayList<Map.Entry<String, Boolean>> lines = new ArrayList<>();
		String[] words = all.split("\\s");
		String line = "";
		int length = 0;
		for (String w : words) {
			if (length + w.length() + 1 > regex) {
				if (w.length() >= regex) {
					line += w;
					lines.add(new AbstractMap.SimpleEntry<String, Boolean>(line, false));
					line = "";
					continue;
				}
				lines.add(new AbstractMap.SimpleEntry<String, Boolean>(line, false));
				line = "";
				length = 0;
			}
			if (length > 0) {
				line += " ";
				length += 1;
			}
			line += w;
			length += w.length();
		}
		if (line.length() > 0)
			lines.add(new AbstractMap.SimpleEntry<String, Boolean>(line, false));
		return lines;
	}

Full source code.

@cubemaster21: I like your implementation, I’ll take a look and see if I can do my own like yours.

@tom_mai78101: Your implementation looks pretty neat, but would you mind explaining it a little? with the abstract maps and what not?

thanks guys :slight_smile:

The AbstractMap is a class object that isn’t used most of the time. I used the SimpleEntry class object that is inside AbstractMap to create a Map.Entry<K, V> object to pass it to my array. This is usually used for holding double data together.

See here for AbstractMap.SimpleEntry usages:



And more on why to use AbstractMap.SimpleEntry:



The code above takes two parameters, one full String sentence, and the regex value. The full String sentence may be something like:


String str = "Can I have a piece of pie for my little sister? She is very hungry.";

It must not be something like this:


String str1 = "Cam I have a piece of pie for my little sister?";
String str2 = "She is very hungry";

The regex value determines how many letters it can fit in one dialogue line before it wraps the sentence to the next line. In my case, I have the max length set to 18, which means in one dialogue line, the most a sentence can be placed in there must be 18 letters or less. Anything more than 18 will have the word that exceeds the limit be wrapped to the next line.

For example,


String str = "ABCDE FGHIJ KLMNO PQRST";  //20 letters + 3 whitespaces = 23 letters > 18-letters limit.

Once this sentence is passed into the method, it will result in something like this:


//Note the white space at the end of this sentence.
String str1 = "ABCDE FGHIJ KLMNO ";  //15 letters + 3 whitespaces = 18 letters.
String str2 = "PQRST"; //5 letters + 0 whitespaces.

So in the dialogue box, it will show up something like this:


//  '_' means whitespace. It is explicitly shown for clarity.

ABCDE_FGHIJ_KLMNO_
PQRST

If you need more explanations, please leave a reply.