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

1 decade 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&039;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 &039;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&039;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&039;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

1 decade 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.

1 decade 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

1 decade 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?

1 decade 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 »