Impact

This forum is read only and just serves as an archive. If you have any questions, please post them on github.com/phoboslab/impact

8 years ago by riceje7

so i needed a way to dynamically display text within certain boundaries, and as there is no current built-in word-wrap functionality or much in the way of formatting text at all i decided to create a small plugin to auto-wrap text instead of having to manually insert line breaks into the text to be displayed.
my problem is that the string returned by the wrapper doesn't execute line breaks in the displayed font (##font.draw()##). it does however display them correctly in the console when the string is logged. here is what i have for the plugin in so far:

CODE:
ig.module('game.plugins.WordWrapper').requires('impact.font').defines(function() {
	WordWrapper = ig.Class.extend({
		font: null,
		box: null,
		init: function(f, b) {
			this.font = f;
			this.box = b;
		},
		wrapMessage: function(message) {
			var words = message.split(" ");
			var wordWidths = this.getWordWidths(words);
			var width = this.box.w;
			var newLine = "\n";
			var space = " ";
			var spaceWidth = this.font.widthForString(" ");
			var widthCounter = 0;
			var newMessage = "";
			for (var i = 0; i < wordWidths.length; i++) {
				if (widthCounter + wordWidths[i] + spaceWidth <= width) {
					widthCounter += wordWidths[i] + spaceWidth;
					newMessage += words[i] + space;
				} else {
					widthCounter = 0;
					widthCounter += wordWidths[i] + spaceWidth;
					newMessage += newLine + words[i] + space;
				}
			}
			return newMessage;
		},
		getWordWidths: function(wordsArr) {
			var arr = new Array();
			for (var i = 0; i < wordsArr.length; i++) {
				arr.push(this.font.widthForString(wordsArr[i]));
			}
			return arr;
		}
	});
});

it works by passing a user defined font and a 'box' object which has at least a value for the key w ({w: 100}) for the width of the bounding box. and then in the ##wrapMessage(message)## function the message parameter is split into words delimited by spaces, then an array of the lengths of each word is created. then using ##font.widthForString(text)## and a counter words and spaces are added to a string to be returned in succession until the counter + word + space is greater than the bounding box's width at which point the counter is reset, a line break is added to the string followed by the word + space that would have made the counter greater than the box's width. and the process continues until the words array has been fully traversed.

I'm not sure what is being lost in translation, because like i said the returned string's line breaks display correctly in the console, just not when using ##font.draw(text, x, y)## and i know that line breaks are working in impact because if i hard code the line breaks into the string and don't process it through the WordWrapper then they display correctly. so i know it is something to do with my code just not sure what exactly i'm doing wrong. any help would be greatly appreciated. thanks

8 years ago by jizaymes

Check out https://github.com/Joncom/pokemon-chat/blob/master/client/lib/game/entities/chat-bubble.js as it may give you some ideas on this. particularly the process() function.

8 years ago by riceje7

I'm currently at work so I'll take a look when i get a break, thanks, I'll let you know how it goes

8 years ago by riceje7

@ jizaymes - while the link you provided is a cleaner, more stream-lined version of what I already had, I am still running into the same problem. has anyone else implemented a word-wrap method that successfully executes line breaks?

8 years ago by riceje7

okay so i figured it out...I was calling ## this.parent(x, y, settings) ## at the end of the init method where i was making the call to ## WordWrapper.wrapMessage(msg) ## all i needed to do was move it to the top of the init() method. so I modified and merged the code from the link @jizaymes provided into my own and this is what i came up with. This solution will (currently) wrap text around a given max line width through the box parameter. In the future I envision some sort of overflow setting, to contain the text in a vertical manner as well (possibly through the use of a custom scroll bar) anyways here is the code

CODE:
ig.module('game.plugins.WordWrapper').requires('impact.font').defines(function() {
	WordWrapper = ig.Class.extend({
		font: null,
		box: null,
		init: function(f, b) {
			this.font = f;
			this.box = b;
		},
		wrapMessage: function(msg) {
			var maxLineWidth = this.box.w;
			var newMessage = '';
			var words = msg.split(' ');
			var lines = new Array();
			var line = '';
			for (var i = 0; i < words.length; i++) {
				var space = (i == 0) ? '' : ' ';
				var str = currentLine + space + words[i];
				if (this.font.widthForString(str) <= maxLineWidth) {
					line = str;
				} else {
					lines.push(line);
					line = words[i];
				}
			}
			if (line != '') {
				lines.push(line);
			}
			for (var i = 0; i < lines.length; i++) {
				if (i != 0) {
					newMessage += "\n";
				}
				newMessage += lines[i];
			}
			return newMessage;
		}
	});
});

if anyone has any constructive criticisms, tips, or ideas for improvements please don't hesitate to comment. Hope this will help make some of your lives a little easier.
Page 1 of 1
« first « previous next › last »