DIY: PIXI.Text pt. 1 - visuals

Discussion in 'RPG Maker MV Tutorials' started by Poryg, Sep 6, 2017.

  1. Poryg

    Poryg Pixie of the Emvee kingdom, Ham of a Hamster Veteran

    Messages:
    3,785
    Likes Received:
    9,463
    Location:
    Czech Republic
    First Language:
    Czech
    Primarily Uses:
    RMMV
    PIXI.Text part 1: Visuals

    First video of hopefully much more from Poryg's Do It Yourself series: Series that will focus on coding with as little amount of plugins as possible with practical tips, examples and even print screens from my own work!

    This in particular is a quick video tutorial on PIXI.Text with a step by step "coding guide".
    PIXI.Text is a viable way to show all sorts of texts from dialogues through other things, you can even use it to build a nice custom menu!
    Second part covering the practical side of PIXI.Text coming soon!

    Requirements: A text editor, rpg maker mv and knowledge how to apply practical examples on different situations. Javascript knowledge helps, but I would say even javascript isn't necessary for at least the basics, since I'm pretty much showing step by step how to write the code.

     
    Last edited: Sep 7, 2017
    #1
  2. mlogan

    mlogan Global Moderators Global Mod

    Messages:
    13,667
    Likes Received:
    7,536
    Location:
    Texas
    First Language:
    English
    Primarily Uses:
    RMMV
    @Poryg Just FYI, I changed the title, but I don't have time to look through this right now. I probably won't be able to until tomorrow, so unless someone else can before then, it probably won't be approved until then. Thanks for your patience.
     
    #2
    Poryg likes this.
  3. Poryg

    Poryg Pixie of the Emvee kingdom, Ham of a Hamster Veteran

    Messages:
    3,785
    Likes Received:
    9,463
    Location:
    Czech Republic
    First Language:
    Czech
    Primarily Uses:
    RMMV
    No problem, I am in no rush anywhere
    Thank you for the change :)
     
    #3
    Jeremiah Eastman likes this.
  4. Jonforum

    Jonforum Veteran Veteran

    Messages:
    1,575
    Likes Received:
    1,344
    Location:
    Canada / Québec
    First Language:
    French
    Primarily Uses:
    RMMV
    I remember having had a lot of fun to integrate pixi.text into rmmv.
    For those who wish to study are integration, here is my script 100% functional.

    PHP:
    // PLUGIN □────────────────────────────────-GAMEFALL_GTP_JONFORUM_SimplePixiText-─────────────────────────────────────────┐
    // ¦AUTOR □ DJMISTERJON(JONFORUM) □ Gamefall Team
    // └───────────────────────────────────────────────□□□□□□□□──────────────────────────────────────────────────────┘
    /*
    //□▼↓▼□═══════════════════════════════════════════════════□□═══════════════════════════════════════════════════□↓↓↓
     Here is the list of possible styles, with default values:
        align: 'center',   // 'left'||'center'||'right' //primary
        breakWords: false, //Break words between any two letters on wordWrap //primary
        dropShadow: false,
        dropShadowAngle: Math.PI / 6,
        dropShadowBlur: 0,
        dropShadowColor: '#000000',
        dropShadowDistance: 5,
        fill: 'black',
        fillGradientType: TEXT_GRADIENT.LINEAR_VERTICAL,
        fontFamily: 'Arial',
        fontSize: 26,
        fontStyle: 'normal', //normal|italic|oblique|initial|inherit
        fontVariant: 'normal', //normal|small-caps|initial|inherit
        fontWeight: 'lighter', //normal|bold|bolder|lighter|number|initial|inherit|900|600|400
        letterSpacing: 0,
        lineHeight: 0, //primary
        lineJoin: 'miter', //"bevel|round|miter"
        miterLimit: 10,
        padding: 0,
        stroke: 'black',
        strokeThickness: 0,
        textBaseline: 'alphabetic', //"alphabetic|top|hanging|middle|ideographic|bottom"
        wordWrap: false, //primary
        wordWrapWidth: 100, //primary
        lineStyle:'middle', //'top'||'middle'||'bottom' //primary
        pictureAlign:1 // 0||1||2  [1:alignCenter to pictureAnchor] [2:alignLeft to pictureAnchor] // PRIMARY
    //□▲↑▲□═══════════════════════════════════════════════════□□═══════════════════════════════════════════════════□↑↑↑
    //□▼↓▼□═══════════════════════════════════════════════════□□═══════════════════════════════════════════════════□↓↓↓
     Here is the list of possible MULTIstyles, with default values:
        font: 'bold 20pt Arial',
        fill: 'black',
        stroke: 'black',
        strokeThickness: 0,
        dropShadow: false,
        dropShadowAngle: Math.PI / 6,
        dropShadowDistance: 4,
        dropShadowColor: 'black'
    //□▲↑▲□═══════════════════════════════════════════════════□□═══════════════════════════════════════════════════□↑↑↑
    // INFO □───────────────────────────────────────-singleStyle-─────────────────────────────────────────────────────┐
        var txt = 'Am a text rendering by pixi !'
        Gamefall.PixiText.create(5, txt, $dataStyles[1], 120, 250).bindPicture(true);
    // └──────────────────────────────────────────────□□□□□□□□────────────────────────────────────────────────────────┘
    // INFO □───────────────────────────────────────-multiStyle-──────────────────────────────────────────────────────┐
        var styles = {
            "primary":{lineStyle:'middle',align: 'left', lineHeight: 0,wordWrap:true,wordWrapWidth:600,}, // add here:primary, (see upperList)
            "def": {strokeThickness: 4,fill: "#ffffff"}, // default no tag txt
            "s0": {fontSize: "28px",fill: "#ff8742",strokeThickness: 10, letterSpacing:20,fontWeight:900}, // tag id txt
            "s1": {fontSize: "18px",fill: "#f4415e",strokeThickness: 5, letterSpacing:4}, // tag id txt
            };
        var txt = '<s0>Hello world!</s0>{i3}\\n\\n\\n I am a simple amazing <s1>PIXI</s1> MULTISTYLE TEXT With a <s0>debugMode</s0> and work with linebreak with a wordWrap! ';
        Gamefall.PixiText.create(1, txt, styles, 400, 250, true,true);
    // └─────────────────────────────────────────────□□□□□□□□□□───────────────────────────────────────────────────────┘
    // INFO □─────────────────────────────────────────────-icon-──────────────────────────────────────────────────────┐
        var styles = {"default": {fontSize: "14px"},"s0": {fontSize: "16px",fontStyle: "italic","icon": true};
        var txt = '<s0>Hello world!</s0>//n//n//n//n I am a simple {i24}amazing PIXI MULTISTYLE TEXT{i1}';
    // └────────────────────────────────────────────────□□□□□□□□□□────────────────────────────────────────────────────┘
    // METHODS □───────────────────────────────────────-GAMEFALL-─────────────────────────────────────────────────────┐
    // ¦ □ Gamefall.PixiText □ .create □ .remove □ .changeTxt □ .moveChildToPicture □ .BindToMap □ .bindPicture
    // └────────────────────────────────────────────────□□□□□□□□──────────────────────────────────────────────────────┘
    // ACCESS □────────────────────────────────────────────────────────┐
    // ¦ □ $gamePixiBank □ $gameSaveBank □ Gamefall.PixiText.txtIcon
    // └───────────────────────────────────────────────────────────────┘
    */
    // PLUGIN BOOT CONSTRUCTOR (PREBUILD ICONs sprites texture)
    Gamefall_PixiText = function() {
        var 
    that this;
        var 
    txtIcon_DirFileName = ['sheetTxtIcons''img/system/IconSet.png']; //accesName,+ spriteSheet filename (full dir)
        
    var iconSize = [3232]; // size icon in spritSheets
        
    this.txtTextureIcon = []; // container of all preCache texture icons for pixiTextMultipleStyles
        // LOADING AND BUILD ICONS CACHE
        
    var loader PIXI.loader.add(txtIcon_DirFileName[0], txtIcon_DirFileName[1]).load(setup); // callback=>(setup) when loader has cached the spriteSheets
        
    function setup() { // the callback setup
            
    var textureCache PIXI.utils.BaseTextureCache.sheetTxtIcons// accesCache by Name to spritsheets texture
            // make Data based on spriteSheet textureCache
            
    var _Width textureCache.width,_Height textureCache.height;
            var 
    _lineLimit _Width iconSize[0]; // when reach, jump next line Y
            
    var _lenght = (_Width iconSize[0]) * (_Height iconSize[1]);
            
    // prebuild all icon from spritesheet and add it to Gamefall.PixiText.txtIcon[]
            
    for (var 000_lenghti++, x++) {
                var 
    rectangle = new Rectangle(iconSize[0] * xiconSize[1] * yiconSize[0], iconSize[1]);
                var 
    texture = new PIXI.Texture(textureCacherectangle);
                
    that.txtTextureIcon.push(texture);
                if (!((
    1) % _lineLimit)) { = -1y++ };
            };
        };
    };

    var 
    Gamefall Gamefall || {};
    Gamefall.PixiText Gamefall.PixiText || new Gamefall_PixiText();
    Gamefall_PixiText.prototype.create = function(idtextstylexyisMultiStyledebugMode) {
        var 
    pixiText = new MVPixi_Text(idtextstylexyisMultiStyledebugMode); //Pre_initialize MVPIXI_TEXT
        
    var AddTXT isMultiStyle && pixiText.addMultiText() || !isMultiStyle && pixiText.addText(); //Add Text+Style And Return full objectChild for save in gamePixiBank
        
    $gamePixiBank.addPixi(AddTXT); // Store objectChild in gamePixiBank
        
    $gameSaveBank.addPixi(pixiText);
        
    //$gameCacheBank.addCacheData(id, text, style, x, y, isMultiStyle); //-------------------- BY GAMEFALL: Stroring information in the cache; -----------------------
        
    this.BindToMap = function(NeedToBind) { //.BindToMap(true);
            
    $gamePixiBank._data[id]._BindToMap NeedToBind;
            
    $gameSaveBank._saveData[id]._BindToMap NeedToBind;
            
    //$gameCacheBank.addBindData(id, 'map', NeedToBind); // IF BIND STORES IN ARRAY;
        
    };
        
    this.bindPicture = function(bindToPicture) { //.bindPicture(true);
            
    $gamePixiBank._data[id]._bindToPicture bindToPicture;
            
    $gameSaveBank._saveData[id]._bindToPicture bindToPicture;
            
    //$gameCacheBank.addBindData(id, 'picture', bindToPicture); // IF BIND STORE IN ARRAY
            
    Gamefall.PixiText.moveChildToPicture(id);
        };
        return 
    this;
    };

    Gamefall_PixiText.prototype.remove = function(id) { //Gamefall.PixiText.remove(id);
        
    $gamePixiBank.removePixi(id);
        
    $gameSaveBank.removePixi(id);
        
    //$gameCacheBank.removePixi(id); // --------------------REMOVING FROM CACHE
    };

    Gamefall_PixiText.prototype.changeTxt = function(idnewTextnewStyle) { // Gamefall.PixiText.changeTxt(1,'aaaa',{fontSize: 15})
        
    if(!$gamePixiBank._data[id]._isMultiStyle){ // IF A SINGLESTYLE TEXT
            
    $gamePixiBank._data[id].text newText || $gamePixiBank._data[id]._text;
            
    $gameSaveBank._saveData[id]._text newText || $gameSaveBank._data[id]._text;
            
    //$gameCacheBank._cacheData[id][1] = newText || $gameCacheBank._cacheData[id][1]; //-----------------------------CHANGE CACHE TEXT --> GAMEFALL
            
    if (newStyle) {
                for (var 
    styleName in newStyle) {
                    
    $gamePixiBank._data[id]._style[styleName] = newStyle[styleName];
                    
    $gameSaveBank._saveData[id]._style[styleName] = newStyle[styleName];
                    
    //$gameCacheBank._cacheData[id][2][styleName] = newStyle[styleName]; //------------------------------CHANGE CACHE STYLE --> GAMEFALL
                
    };
            };
        }else{ 
    // IF A MULTISTYLE TEXT
            
    $gamePixiBank._data[id].removeChildren();
            
    $gamePixiBank._data[id]._result = [];
            
    $gamePixiBank._data[id]._resultLine = [[]];
            
    $gamePixiBank._data[id]._dataLH = [0];
            
    $gamePixiBank._data[id]._dataLW = [0];
            
    $gamePixiBank._data[id]._text newText;
            
    $gamePixiBank._data[id] = $gameSaveBank._saveData[id].initSetupMultiStyle($gamePixiBank._data[id]);
            
    $gamePixiBank._data[id] = $gameSaveBank._saveData[id].configuAnchor($gamePixiBank._data[id],true);
            
    //Gamefall.PixiText.create(id, newText, style, 0, 0,true,debug).bindPicture(true);
        
    };
    };
    // MOVE CHILD PIXI TO CHILD Sprite_Picture
    Gamefall_PixiText.prototype.moveChildToPicture = function(id) { // Gamefall.PixiText.moveChildToPicture(5)
        
    var parentPicture SceneManager._scene._spriteset._pictureContainer.children[id-1];
        
    parentPicture.addChild($gamePixiBank._data[id]);
    };

    //□▼↓▼□════════════════════════════════════════□□═══════════════════════════════════════════════════════════□↓↓↓
    // MVPIXI_TEXT □──────────────────────────-CONSTRUCTOR-───────────────────────────────────────────────────┐
    // ¦ □ initialize □ .addText □ .addMultiText □ .configuAnchor
    // └────────────────────────────────────────□□□□□□□□──────────────────────────────────────────────────────┘

    function MVPixi_Text() {
        
    this.initialize.apply(thisarguments);
        
    };
    MVPixi_Text.prototype.initialize = function(idtextstylexyisMultiStyledebugMode) {
        
    this._id id;
        
    this._text text;
        
    this._style style;
        
    this._x x;
        
    this._y y;
        
    this.Map_X x;
        
    this.Map_Y y;
        
    this._BindToMap false;
        
    this._bindToPicture false;
        
    this._isMultiStyle isMultiStyle || false// true or default false
        
    this.result = []; // storing result for match FOR MULTYSTYLE ONLY
        
    this.resultLine = [[]]; // storing result by line
        
    this.dataLH = [0];
        
    this.dataLW = [0];
        
    this._debugMode debugMode;
    };

    MVPixi_Text.prototype.addText = function() {
        var 
    pixiText = new PIXI.Text(this._textthis._style);
        
    pixiText this.configuAnchor(pixiText); // set Anchor by align type
        //variable
        
    pixiText._pixiId this._id;
        
    pixiText.this._x;
        
    pixiText.this._y
        pixiText
    .Map_X this.Map_X;
        
    pixiText.Map_Y this.Map_Y;
        
    //pixiText._events.constructor.name = 'Event';
        //status
        
    pixiText._BindToMap this._BindToMap;
        
    pixiText._bindToPicture this._bindToPicture;
        
    pixiText._isMultiStyle this._isMultiStyle;
        return 
    SceneManager._scene._textContainer.addChild(pixiText); // add and return the objChid
    };

    MVPixi_Text.prototype.addMultiText = function() {
        var 
    pixiText = new PIXI.Container(); // ALPHA CONTAINER FOR MULTISTYLES (storing ALL CHILDREN TXT&STYLES)
        // put configu in the master container (will affect all child Setup)
        
    pixiText._text this._text;
        
    pixiText._style this._style;
        
    //variable
        
    pixiText._pixiId this._id;
        
    pixiText.this._x;
        
    pixiText.this._y;
        
    pixiText.Map_X this.Map_X;
        
    pixiText.Map_Y this.Map_Y;
        
    //status
        
    pixiText._BindToMap this._BindToMap;
        
    pixiText._bindToPicture this._bindToPicture;
        
    pixiText._isMultiStyle this._isMultiStyle;
        
    // add the data for multiStyles Only
        
    pixiText._result this.result;
        
    pixiText._resultLine this.resultLine;
        
    pixiText._dataLH this.dataLH;
        
    pixiText._dataLW this.dataLW;
        
    pixiText.debugMode this._debugMode;
        
    pixiText this.initSetupMultiStyle(pixiText); // SETUP a multiStyles
        
    return SceneManager._scene._textContainer.addChild(pixiText); // add and return the objChid
    };
    MVPixi_Text.prototype.configuAnchor = function(pixiText,isMultistyle) {
        var 
    alignType pixiText._style._align||pixiText._style.primary.align// get info about align
        
    if(!isMultistyle){
            
    pixiText.anchor.alignType==='center' && 0.5 || alignType==='right' && || 0;
            
    pixiText.anchor.0.5;  } //TODO:
            
        
    else{ // if is multitext
            
    var alignType pixiText._style.primary.pictureAlign;
            var 
    pixiText._limitLineMax;
            if(
    alignType===1){ pixiText.-= (w/2)}
            else if(
    alignType===2){pixiText.-= w};
        };
        return 
    pixiText;
    };

    //□▼↓▼□═════════════════════════════════════□□═════════════════════════════════════════════════════════□↓↓↓
    // MULTISTYLES □──────────────────────────-PROTOTYPE-───────────────────────────────────────────────┐
    // ¦ □ initSetupMultiStyle □ build_dataChild □ outLimitCalculation □ positioningChild
    // └─────────────────────────────────────────□□□□□□□□───────────────────────────────────────────────┘

    MVPixi_Text.prototype.initSetupMultiStyle = function(pixiText) {
        
        var 
    txt pixiText._textstyle pixiText._style;
        
        
    style.primary.hasIcon txt.match(/{i+(\d+?)\}/) && true || false// txt has icon ?
        
    style.primary.hasLineBreak txt.match(/\\n/) && true || false// has custom //n ?
        
    for (var tag in style) { if(tag !== 'primary'){ style[tag] = new PIXI.TextStyle(style[tag]) }; }; // new pixi.Style for each Tag !primary
        //STEP:1 INITIALISE MATCHING STYLES TAG ↓↓↓ ////
        
    var re = /<s+\d\>(.*?)<\/s+\d>/, matchntextBefore;
        while ((
    match re.exec(txt)) !== null) {
            
    textBefore match.input.slice(0match.index);
            
    match[0].match(/\d+/)[0]; // get tagReference <s?n?>
            if(textBefore){ pixiText._result.push({ txt: textBefore, style: style.def, tag:'def' });}; // push the text beforeMatch (not TAGED)
            pixiText._result.push({ txt: match[1], style: style['s' + n], tag: 's' + n }); // push text from Match (<>TAGED)
            txt = txt.slice(match.index + match[0].length); // slice current txt for loop again Match
        };
        if(txt){pixiText._result.push({ txt: txt, style: style.def, tag:'def' });} // push the text beforeMatch (not TAGED)
        //STEP:1 INITIALISE MATCHING STYLES TAG END ↑↑↑ ////
        //STEP:2 INITIALISE MATCHING ICONS ↓↓↓ ////
        if (style.primary.hasIcon) {
            var re = /{i+(\d+?)\}/; // regex dinamic: note:(\d?) permit to get the id
            for (var r = 0; r < pixiText._result.length; r++) { // check inside all result[?].txt if we have a icon tag ?
                var txt = pixiText._result[r].txt;
                var match = re.exec(pixiText._result[r].txt); // find if iconTag {i(ID)}, in this arrResult?
                if (match) { // we find icon in pixiText._result[r]
                    var iconTxt = { isIcon: true, iconID: match[1], tag: pixiText._result[r].tag }; // create icon obj
                    var textAfter = match.input.slice(match.index + match[0].length); // get text after icon tag >
                    var afterIcon =  { txt: textAfter, style: pixiText._result[r].style, tag: pixiText._result[r].tag };
                    pixiText._result[r].txt = match.input.slice(0, match.index); // redefine current (pixiText._result[?]) with sliced txt befor icon tag <
                    pixiText._result.splice(++r, 0, iconTxt, afterIcon); // add after current _result[r], new array [iconTxt],[afterIcon]
                };
            };
        };
        //STEP:2 INITIALISE MATCHING ICONS END ↑↑↑ ////
        //STEP:3 INITIALISE MATCHING CUSTOM LINEBREAK ↓↓↓ ////
        if(style.primary.hasLineBreak){
            var re = /(\\n)+/; // regex
            for (var r = 0; r < pixiText._result.length; r++) {
                var match = re.exec(pixiText._result[r].txt);
                if(match){
                    var textAfter = match.input.slice(match.index + match[0].length); // get text after \\n break >
                    var textNewLine =  { txt: textAfter, style: pixiText._result[r].style, tag: pixiText._result[r].tag, jumpLine:true };
                    var jmpHeigth =  { txt: '    ', style: pixiText._result[r].style, tag: pixiText._result[r].tag, jmpFactor:(match[0].length/2) };
                    pixiText._result[r].txt = match.input.slice(0, match.index); // redefine current txt, before jmp line
                    if(!pixiText._result[r].txt){ pixiText._result.splice(r--, 1); };
                    if(textAfter){ pixiText._result.splice(++r, 0, jmpHeigth,textNewLine); } // ADD AFTER this.result A NEW ARRAY jmpHeigth+ TXT
                    else{
                        pixiText._result[r+1].jumpLine = true;
                        pixiText._result.splice(++r, 0, jmpHeigth); // ADD AFTER this.result A NEW ARRAY jmpHeigth
                    };
                };
            };
        };
        //STEP:3 INITIALISE MATCHING CUSTOM LINEBREAK END ↑↑↑ ////
        pixiText = this.build_dataChild(pixiText,style);// CREATE CHILD RESULT **(ALSO DATA FOR SAVE BANK)**
        pixiText = this.positioningChild(pixiText);// SET XY POSITION OF ALL CHILD TXT BY RESULT DATA
        pixiText = this.configuAnchor(pixiText,true); // configure pivot of container
        if(pixiText.debugMode){pixiText = this.debugModeCanvasLimit(pixiText);} // IF DEBUGMODE MAKE CANVAS line limit
        return pixiText; // return pixiText (final pixi container)
    };

    MVPixi_Text.prototype.build_dataChild = function(pixiText,style) {
        var lineIndex = 0, inScopeWidth = 0;
        var wordWrap = style.primary.wordWrap && true || false;
        var wrapLimit = style.primary.wordWrapWidth;
        var debugMode = pixiText.debugMode || false;
        for(var r=0;r<pixiText._result.length;r++){
            var data = pixiText._result[r];
            if(data.jumpLine){inScopeWidth = 0; lineIndex++; pixiText._resultLine[lineIndex]=[]; pixiText._dataLH[lineIndex] = 0; };
            var childTxt = !data.isIcon && new PIXI.Text(data.txt,data.style) || new PIXI.Sprite(Gamefall.PixiText.txtTextureIcon[data.iconID]);
            var childWidth = childTxt.width, childHeight = childTxt.height;
            if(data.jmpFactor) { // factor heigth * (\\n) + f\\n + f\\n + f\\n + ....
                var maxFactorH = pixiText._dataLH[lineIndex], addJmpFactor = maxFactorH/4;
                childTxt.height = maxFactorH + (addJmpFactor*(data.jmpFactor-1));
                childWidth = 0, childHeight = childTxt.height;
            };       
            if(wordWrap && (inScopeWidth+childWidth) > wrapLimit){ // if WORDWRAP ONLY
                if(data.isIcon){// jump icon to new line
                    inScopeWidth = 0; lineIndex++; pixiText._resultLine[lineIndex]=[]; pixiText._dataLH[lineIndex] = 0;
                }else{ // need split and return the word exeed limit
                    var exceedTXT = this.outLimitCalculation(childTxt,inScopeWidth,wrapLimit,data);
                    childWidth = childTxt.width, childHeight = childTxt.height; // get new valur
                    pixiText._result.splice(r+1, 0, exceedTXT); // ADD AFTER this.result A NEW ARRAY TXT
                };
            };
            data._width = childWidth, data._height = childHeight;
            data._x = inScopeWidth, data._line = lineIndex;
            pixiText._resultLine[lineIndex].push(data); // add to resulLine
            if(debugMode){childTxt = this.debugModeCanvasTxt(childTxt,data);} // IF DEBUGMODE MAKE CANVAS rec
            pixiText.addChild(childTxt);
            inScopeWidth+=childWidth;
            pixiText._dataLW[lineIndex] = inScopeWidth;
            var maxHeight = pixiText._dataLH[lineIndex];
            pixiText._dataLH[lineIndex] = childHeight>maxHeight && childHeight || maxHeight;
        };
        return pixiText;
    };

    MVPixi_Text.prototype.outLimitCalculation = function(childTxt,inScopeWidth,wrapLimit,data) {
        var letterWidth = childTxt.width / childTxt._text.length; // calculate width of all letter
        var afterLineResult = { txt: '', style: data.style, tag: data.tag, jumpLine:true };
        var re = /\w+\W+|\w+/g; //regexr (match all word + any ,')
        var match; var inLineTxt = '';
        while ((match = re.exec(childTxt._text)) !== null) {
            var resultWidh = inScopeWidth+(match[0].length+inLineTxt.length)*letterWidth;
            if (resultWidh > wrapLimit) {
                afterLineResult.txt = match.input.slice(match.index); break;}
            else { inLineTxt += match[0]; };
        };
        inLineTxt = inLineTxt.replace(/[\s]+$/,''); // remove endSpace
        childTxt.text = inLineTxt; data.txt = inLineTxt;
        return afterLineResult;
    };

    MVPixi_Text.prototype.positioningChild = function(pixiText) {
        var data = pixiText._resultLine;
        var pixiChild = pixiText.children;
        var lS = pixiText._style.primary.lineStyle;
        var lA = pixiText._style.primary.align;
        var lH = pixiText._style.primary.lineHeight || 0;
        lS = lS==='middle'&& 0.5 || lS==='bottom'&& 1 || 0; // lineStyle
        lA = lA==='center'&& 0.5 || lA==='right'&& 1 || 0;  // lineAlign
        var limit = pixiText._style.primary.wordWrapWidth || Math.max.apply(Math, pixiText._dataLW);
        pixiText._limitLineMax = limit; // asign because alignBypicture work with limit and not
        for (var R=0, id=0, lineMaxH=0, Y=0, alignX=0, LEN=data.length; R<LEN; R++) {
            if(lA){ alignX = (limit-pixiText._dataLW[R])*lA; };
            for (var r=0, len=data[R].length; r<len; r++, id++) {
                pixiChild[id].anchor.y = lS;
                pixiChild[id].x = data[R][r]._x+alignX;
                pixiChild[id].y = Y;
            };
            Y+=pixiText._dataLH[R]+lH;
        };
    return pixiText
    };

    //□▼↓▼□═════════════════════════════════════□□═════════════════════════════════════════════════════════□↓↓↓
    // SCENE_MAP □──────────────────────────-PROTOTYPE-───────────────────────────────────────────────────┐
    // ¦ □ createDisplayObjects □ .createTextContainer □ .checkText □ .updateMain
    // └──────────────────────────────────────□□□□□□□□────────────────────────────────────────────────────┘

    // When scene map, create  all Display Object, (map transfer)
    _Pixitxt_old_Scene_Map_Prototype_createDisplayObjects = Scene_Map.prototype.createDisplayObjects;
    Scene_Map.prototype.createDisplayObjects = function() {
        _Pixitxt_old_Scene_Map_Prototype_createDisplayObjects.call(this);
        //$gamePixiBank.clear(); // ???
        this.createTextContainer();
        this.checkText();
        //this.cacheText(); // CHECKING THE GAME CACHE
    };

    Scene_Map.prototype.createTextContainer = function() {
        // ajoute le conteneur des child pixi dans la scene map
        this._textContainer = new Sprite();
        //this._spriteset.addChild(this._textContainer); // inutile de mettre dans la _spriteset
    };

    Scene_Map.prototype.checkText = function() {
        //check if pixitext need to replace on new scene refresh ?
        var PixiBank = $gamePixiBank._data;
        if (PixiBank.length > 0) { //._pixiId
            for(id in PixiBank){
                id=Number(id);
                if(PixiBank[id]._bindToPicture){
                    SceneManager._scene._spriteset._pictureContainer.children[id-1].addChild(PixiBank[id]);
                }else{
                    //SceneManager._scene._textContainer.addChild(PixiBank[id]); // activer si on veut affciher text sans bindpicture
                };
            };
        };
    };

    alias_Pixi_Scene_Map_Prototype_updateMain = Scene_Map.prototype.updateMain;
    Scene_Map.prototype.updateMain = function() {
        alias_Pixi_Scene_Map_Prototype_updateMain.call(this);
        this._textContainer.children.forEach(function(pixiTxt) {
            if (pixiTxt._BindToMap) {
                pixiTxt.x = pixiTxt.Map_X - $gameMap._displayX * 48;
                pixiTxt.y = pixiTxt.Map_Y - $gameMap._displayY * 48;
            };
        })
    };

    //□▼↓▼□════════════════════════════════════════□□═════════════════════════════════════════════════════□↓↓↓
    // DATA_MANAGER □──────────────────────────-FUNCTION-─────────────────────────────────────────────────┐
    // ¦ □ _databaseFiles □ .createGameObjects □ .makeSaveContents □ .extractSaveContents
    // └──────────────────────────────────────□□□□□□□□────────────────────────────────────────────────────┘
    // create new variable $ in window
    var $gamePixiBank = null;
    var $gameSaveBank = null;
    var $gameCacheBank = null;
    var $dataStyles = null;
    DataManager._databaseFiles = [
        { name: '$dataActors', src: 'Actors.json' },
        { name: '$dataClasses', src: 'Classes.json' },
        { name: '$dataSkills', src: 'Skills.json' },
        { name: '$dataItems', src: 'Items.json' },
        { name: '$dataWeapons', src: 'Weapons.json' },
        { name: '$dataArmors', src: 'Armors.json' },
        { name: '$dataEnemies', src: 'Enemies.json' },
        { name: '$dataTroops', src: 'Troops.json' },
        { name: '$dataStates', src: 'States.json' },
        { name: '$dataAnimations', src: 'Animations.json' },
        { name: '$dataTilesets', src: 'Tilesets.json' },
        { name: '$dataCommonEvents', src: 'CommonEvents.json' },
        { name: '$dataSystem', src: 'System.json' },
        { name: '$dataMapInfos', src: 'MapInfos.json' },
        { name: '$dataStyles', src: 'PixiStyle.json' }
    ];

    Gamefall.oldCreateGameObjects = DataManager.createGameObjects;
    DataManager.createGameObjects = function() {
        Gamefall.oldCreateGameObjects.apply(this, arguments);
        $gamePixiBank = new Game_PixiBank();
        $gameSaveBank = new Game_SaveBank();
        //$gameCacheBank = new Game_CacheBank();
    };

    DataManager.makeSaveContents = function() {
        // A save data does not contain $gameTemp, $gameMessage, and $gameTroop.
        var contents = {};
        contents.system = $gameSystem;
        contents.screen = $gameScreen;
        contents.timer = $gameTimer;
        contents.switches = $gameSwitches;
        contents.variables = $gameVariables;
        contents.selfSwitches = $gameSelfSwitches;
        contents.actors = $gameActors;
        contents.party = $gameParty;
        contents.map = $gameMap;
        contents.player = $gamePlayer;
        //contents.pixiSave = $gameCacheBank;
        return contents;
    };

    Gamefall.oldExtractSaveContents = DataManager.extractSaveContents;
    DataManager.extractSaveContents = function(contents) {
        Gamefall.oldExtractSaveContents.apply(this, arguments);
        $gameCacheBank = contents.pixiSave;
    };

    //□▼↓▼□═════════════════════════════════════════□□═════════════════════════════════════════════════════□↓↓↓
    // GAME_PIXIBANK □──────────────────────────-PROTOTYPE-───────────────────────────────────────────────┐
    // ¦ □ $gamePixiBank □ .initialize □ .clear □ .pixiBank □ .addPixi □ .removePixi □ .txtObj
    // └─────────────────────────────────────────□□□□□□□□─────────────────────────────────────────────────┘
    function Game_PixiBank() {
        this.initialize.apply(this, arguments);
    };

    Game_PixiBank.prototype.initialize = function() {
        this._data = [];
    };

    Game_PixiBank.prototype.clear = function() {
        return this._data = [];
    };

    Game_PixiBank.prototype.pixiBank = function() {
        return this._data;
    };

    Game_PixiBank.prototype.addPixi = function(AddTXT) {
        this._data[AddTXT._pixiId] = AddTXT;
    };

    Game_PixiBank.prototype.removePixi = function(id) { //$gamePixiBank.removePixi
        this._data[id]=[]; // keep array index for easy id
    };

    Game_PixiBank.prototype.txtObj = function(id) { // $gamePixiBank.txtObj(id);
        return this._data[id];
    };

    //□▼↓▼□═════════════════════════════════════════□□═════════════════════════════════════════════════════□↓↓↓
    // GAME_SAVEBANK □──────────────────────────-PROTOTYPE-───────────────────────────────────────────────┐
    // ¦ □ $gameSaveBank  □ .initialize □ .clear □ .saveBank □ .addPixi □ .removePixi
    // └─────────────────────────────────────────□□□□□□□□─────────────────────────────────────────────────┘
    function Game_SaveBank() {
        this.initialize.apply(this, arguments);
    };

    Game_SaveBank.prototype.initialize = function() {
        this._saveData = [];
    };

    Game_SaveBank.prototype.clear = function() {
        return this._saveData = [];
    };

    Game_SaveBank.prototype.saveBank = function() {
        return this._saveData;
    };

    Game_SaveBank.prototype.addPixi = function(pixi, multi) {
        this._saveData[pixi._id] = pixi;
    };

    Game_SaveBank.prototype.removePixi = function(id) {
        this._saveData[id] = null;
    };

    //□▼↓▼□═════════════════════════════════════════□□═════════════════════════════════════════════════════□↓↓↓
    // GAME_CACHEBANK □──────────────────────────-PROTOTYPE-───────────────────────────────────────────────┐
    // ¦ □ $gameSaveBank  □ .initialize □ .clear □ .cacheBank □ .addCacheData □ .addBindData  □ .remove
    // └─────────────────────────────────────────□□□□□□□□─────────────────────────────────────────────────┘
    /*function Game_CacheBank() {
        this.initialize.apply(this, arguments);
    };

    Game_CacheBank.prototype.initialize = function() {
        this._cacheData = [];
    };

    Game_CacheBank.prototype.clear = function() {
        return this._saveData = [];
    };

    Game_CacheBank.prototype.cacheBank = function() {
        return this._cacheData;
    };

    Game_CacheBank.prototype.addCacheData = function(id, text, style, x, y, isMultiStyle) {
        return this._cacheData[id] = [id, text, style, x, y, isMultiStyle, []];
    };

    Game_CacheBank.prototype.addBindData = function(id, bind, data) {
        var binding = data || false;
        if (bind == 'map') this._cacheData[id][6][0] = binding;
        else if (bind == 'picture') this._cacheData[id][6][1] = binding;
    };

    Game_CacheBank.prototype.remove = function(id) {
        return this._cacheData[id] = null;
    };
    */
    //□▼↓▼□═════════════════════════════════════════□□═════════════════════════════════════════════════════□↓↓↓
    // DEBUGMODE □──────────────────────────-FUNCTION-───────────────────────────────────────────┐
    // ¦ □ debugModeCanvasTxt □ debugModeCanvasLimit
    // └─────────────────────────────────────□□□□□□□□────────────────────────────────────────────┘
    MVPixi_Text.prototype.debugModeCanvasTxt = function(childTxt,data) {
        if (childTxt instanceof PIXI.Text) {
            var ctx = childTxt.canvas.getContext('2d');
            if (data.jmpFactor) { // if is a jmp indicator
                ctx.globalAlpha = 0.8;ctx.fillStyle = "#000000";
                ctx.fillRect(0, 0, childTxt.width, childTxt.height);
                ctx.globalAlpha = 1;ctx.font = "600 16px Arial";ctx.fillStyle = "#ffffff";
                ctx.fillText('↙J', 8, 12);
                ctx.font = "300 14px Arial";
                ctx.fillText(childTxt.height, 9, 25);
            } else {
                ctx.globalAlpha = 0.4;
                ctx.fillRect(0, 0, childTxt.width, childTxt.height);
                ctx.strokeStyle = "#000000";
                ctx.strokeRect(0, 0, childTxt.width, childTxt.height);
                ctx.fill();
                ctx.globalAlpha = 1;ctx.font = "800 13px Arial";ctx.lineWidth = 2;ctx.strokeStyle = '#ffffff';
                if (childTxt.width > 60) {
                    ctx.strokeText(childTxt.width + '*' + childTxt.height, 0, 10);
                    ctx.fillStyle = "#000000";
                    ctx.fillText(childTxt.width + '*' + childTxt.height, 0, 10);
                    if (childTxt.width > 90) {
                        ctx.font = "700 13px Arial";
                        ctx.strokeText(data.tag, 60, 10);ctx.fillText(data.tag, 60, 10);
                    }
                } else {
                    if (childTxt.width < 19) {
                        ctx.font = "800 10px Arial";
                    }
                    ctx.strokeText(childTxt.width, 0, 10);ctx.strokeText(childTxt.height, 0, 23);
                    ctx.fillStyle = "#000000";
                    ctx.fillText(childTxt.width, 0, 10);ctx.fillText(childTxt.height, 0, 23);
                };
            };
        };
            return childTxt;
    };

    MVPixi_Text.prototype.debugModeCanvasLimit = function(pixiText) {
        //new PIXI.Text(data.txt,data.style) || new PIXI.Sprite(Gamefall.PixiText.txtTextureIcon[data.iconID]);
        var child = new PIXI.Text(' ');
        var wordWrapW = pixiText._style.primary.wordWrap&&pixiText._style.primary.wordWrapWidth||null;
        var lineStyle = pixiText._style.primary.lineStyle;
        var lineStyleFix =  lineStyle==='bottom'&&pixiText._dataLH[0]||lineStyle==='middle'&&pixiText._dataLH[0]/2||0
        child.y -= pixiText._dataLH[0]; // fix box Y with lineStyle
        child.width=pixiText._limitLineMax; // wordwrape or not is same
        child.height = pixiText.height+20;// +20 for add txt info
        child.canvas.width = child.width;
        child.canvas.height =  child.height;
        var ctx = child.canvas.getContext('2d');
        ctx.globalAlpha = 0.5;ctx.lineWidth = 6;ctx.strokeStyle = "#cd0000";
        ctx.strokeRect(0, 0, child.width,  child.height-20);
        // txt info
        ctx.globalAlpha = 1;ctx.font = "700 15px sans-serif";ctx.lineWidth = 1;ctx.strokeStyle = '#ffffff'; ctx.fillStyle = "#cd0000";
        var txt = 'wordWrap:'+(pixiText._style.primary.wordWrap||false)+' wrapWidth:'+pixiText._style.primary.wordWrapWidth+' lineStyle:'+lineStyle+' HW:'+child.width+':'+(child.height-20);
        ctx.strokeText(txt, 0, child.canvas.height-5);
        ctx.fillText(txt, 0, child.canvas.height-5);

        pixiText.addChild(child);
        return pixiText;
    };
     
    #4
    Poryg likes this.
  5. Poryg

    Poryg Pixie of the Emvee kingdom, Ham of a Hamster Veteran

    Messages:
    3,785
    Likes Received:
    9,463
    Location:
    Czech Republic
    First Language:
    Czech
    Primarily Uses:
    RMMV
    @Jonforum this is very nice! I'll definitely take a look at it :) although it should be noted that it isn't "plug and play" if someone wants to test it, because the rmmv default pixi doesn't have a loader for some reason, as well as some other important functions.
     
    #5
    Jeremiah Eastman likes this.
  6. Jonforum

    Jonforum Veteran Veteran

    Messages:
    1,575
    Likes Received:
    1,344
    Location:
    Canada / Québec
    First Language:
    French
    Primarily Uses:
    RMMV
    he is not plug and play.
    But you can find some interesting code snippet to inspire you.
    for the loader, I have to replace it, because it had a lot of change with the new pixi loader.
    at the same time we can add several Loaders to synchronize them in diferents plugins.
    PHP:
    new PIXI.loaders.Loader();
     
    #6
  7. DavidFoxfire

    DavidFoxfire Veteran Veteran

    Messages:
    224
    Likes Received:
    44
    Location:
    St. Louis, MO
    I'd like to have a Web Page/Text/Non Video version of this above tutorial, since I prefer to have the instructions next to me when I actually try my hand at some new code. I'm very interested in using PIXI to create text effects.
     
    #7
  8. Poryg

    Poryg Pixie of the Emvee kingdom, Ham of a Hamster Veteran

    Messages:
    3,785
    Likes Received:
    9,463
    Location:
    Czech Republic
    First Language:
    Czech
    Primarily Uses:
    RMMV
    I'll see what I can do about it, @DavidFoxfire :) There is an ongoing reconstruction of the roads in front of our apartment, so I can'T really focus on it right now, but I'll get to it once it frees up a bit.
     
    #8
    Jeremiah Eastman likes this.
  9. Seth-Rah

    Seth-Rah professional amateur Member

    Messages:
    22
    Likes Received:
    7
    Location:
    South Africa
    First Language:
    English
    Primarily Uses:
    RMMV
    I noticed that you are not removing the text elements from the scene and rather just setting their alpha to 0.

    Do you think it's possible to remove the element from the scene completely or is the alpha the only solution?
     
    #9
    Jeremiah Eastman likes this.
  10. Poryg

    Poryg Pixie of the Emvee kingdom, Ham of a Hamster Veteran

    Messages:
    3,785
    Likes Received:
    9,463
    Location:
    Czech Republic
    First Language:
    Czech
    Primarily Uses:
    RMMV
    SceneManager._scene.removeChild (child).
    I don't remove them, because changing maps eliminates all children anyway. And since PIXI doesn't render children with zero alpha, it doesn't make too much of a difference in lightweight projects.
     
    #10
    Jeremiah Eastman and Seth-Rah like this.
  11. Jonforum

    Jonforum Veteran Veteran

    Messages:
    1,575
    Likes Received:
    1,344
    Location:
    Canada / Québec
    First Language:
    French
    Primarily Uses:
    RMMV
    it is better to avoid using alpha: 0 to make a pixi element disappear, for performance issus.
    better use .renderable = false;
    This proprety STOP the rendering of the element in the core of pixi and also in the parent layer calculation.
    Alpha 0 are alway calcul in the parent.
     
    #11
    Seth-Rah, Jeremiah Eastman and Poryg like this.
  12. Poryg

    Poryg Pixie of the Emvee kingdom, Ham of a Hamster Veteran

    Messages:
    3,785
    Likes Received:
    9,463
    Location:
    Czech Republic
    First Language:
    Czech
    Primarily Uses:
    RMMV
    @Jonforum is right. renderable = false is the most efficient way if you don't intend to render the thing anytime soon. If you indend to use it often, it might be better to use alpha. But as I said, in lightweight projects using alpha is completely fine, because upon changing scenes all children disappear.
     
    #12
    Jeremiah Eastman likes this.
  13. soup2400

    soup2400 Warper Member

    Messages:
    1
    Likes Received:
    0
    First Language:
    english
    Primarily Uses:
    RMMV
    Thanks so much for this. I love having a better understanding at the base level. Thanks again and I can't wait to go through more of your stuff.
     
    #13

Share This Page