DIY: PIXI.Text pt. 1 - visuals

Poryg

Dark Lord of the Castle of Javascreeps
Veteran
Joined
Mar 23, 2017
Messages
4,065
Reaction score
10,364
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:

mlogan

Global Moderators
Global Mod
Joined
Mar 18, 2012
Messages
14,662
Reaction score
8,092
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.
 

Poryg

Dark Lord of the Castle of Javascreeps
Veteran
Joined
Mar 23, 2017
Messages
4,065
Reaction score
10,364
First Language
Czech
Primarily Uses
RMMV
No problem, I am in no rush anywhere
Thank you for the change :)
 

Jonforum

Veteran
Veteran
Joined
Mar 28, 2016
Messages
1,615
Reaction score
1,417
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 = [32, 32]; // 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 i = 0, x = 0, y = 0; i < _lenght; i++, x++) {
            var rectangle = new Rectangle(iconSize[0] * x, iconSize[1] * y, iconSize[0], iconSize[1]);
            var texture = new PIXI.Texture(textureCache, rectangle);
            that.txtTextureIcon.push(texture);
            if (!((i + 1) % _lineLimit)) { x = -1, y++ };
        };
    };
};

var Gamefall = Gamefall || {};
Gamefall.PixiText = Gamefall.PixiText || new Gamefall_PixiText();
Gamefall_PixiText.prototype.create = function(id, text, style, x, y, isMultiStyle, debugMode) {
    var pixiText = new MVPixi_Text(id, text, style, x, y, isMultiStyle, debugMode); //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(id, newText, newStyle) { // 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(this, arguments);
    
};
MVPixi_Text.prototype.initialize = function(id, text, style, x, y, isMultiStyle, debugMode) {
    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._text, this._style);
    pixiText = this.configuAnchor(pixiText); // set Anchor by align type
    //variable
    pixiText._pixiId = this._id;
    pixiText.x = this._x;
    pixiText.y = 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.x = this._x;
    pixiText.y = 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.x = alignType==='center' && 0.5 || alignType==='right' && 1 || 0;
        pixiText.anchor.y = 0.5;  } //TODO:
        
    else{ // if is multitext
        var alignType = pixiText._style.primary.pictureAlign;
        var w = pixiText._limitLineMax;
        if(alignType===1){ pixiText.x -= (w/2)}
        else if(alignType===2){pixiText.x -= w};
    };
    return pixiText;
};

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

MVPixi_Text.prototype.initSetupMultiStyle = function(pixiText) {
    
    var txt = pixiText._text, style = 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>/, match, n, textBefore;
    while ((match = re.exec(txt)) !== null) {
        textBefore = match.input.slice(0, match.index);
        n = 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;
};
 

Poryg

Dark Lord of the Castle of Javascreeps
Veteran
Joined
Mar 23, 2017
Messages
4,065
Reaction score
10,364
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.
 

Jonforum

Veteran
Veteran
Joined
Mar 28, 2016
Messages
1,615
Reaction score
1,417
First Language
French
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.
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();
 

DavidFoxfire

Veteran
Veteran
Joined
Feb 28, 2014
Messages
224
Reaction score
44
Primarily Uses
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.
 

Poryg

Dark Lord of the Castle of Javascreeps
Veteran
Joined
Mar 23, 2017
Messages
4,065
Reaction score
10,364
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.
 

Seth-Rah

professional amateur
Member
Joined
Oct 29, 2017
Messages
22
Reaction score
7
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?
 

Poryg

Dark Lord of the Castle of Javascreeps
Veteran
Joined
Mar 23, 2017
Messages
4,065
Reaction score
10,364
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.
 

Jonforum

Veteran
Veteran
Joined
Mar 28, 2016
Messages
1,615
Reaction score
1,417
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.
 

Poryg

Dark Lord of the Castle of Javascreeps
Veteran
Joined
Mar 23, 2017
Messages
4,065
Reaction score
10,364
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.
 

soup2400

Warper
Member
Joined
Dec 14, 2018
Messages
1
Reaction score
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.
 

Users Who Are Viewing This Thread (Users: 0, Guests: 1)

Latest Threads

Latest Posts

Latest Profile Posts

Are there any vocalists on RPG Maker Forums that would want to sing together in a group, duet or make a whole channel together?
Here it is in all its leggy glory! I apologize in advance.
Suggestion for the name for the new RM, RPG Maker Re-MV (Re-Mastered Version)
A guide on Furry Potatoes.

Forum statistics

Threads
98,175
Messages
950,087
Members
129,473
Latest member
Soulbanana
Top