Michel (Starnut) Posted May 6, 2014 Share Posted May 6, 2014 Hey guys, I'm a bit confused: I thought since the pixi guys apparently didn't merge the above fix, yet, I'd just go and throw it in myself. But I tried to locate the PIXI.BitmapFontLoader within the pixi.js (not minified) that comes with Phaser (2.0.4) or even within the phaser.js file but couldn't find anything. What am I missing? Or rather: How would I have to approach this? I thought I'd be less hassle than converting XMLs to JSONs and stuff. Link to comment Share on other sites More sharing options...
Rex Rhino Posted May 6, 2014 Author Share Posted May 6, 2014 I don't know if that fixed was merged in or not, but I am using the latest dev version of pixi, with the latest version of cocoonjs, and I am able to use xml bitmap fonts without any issues. I have not made any fixes or changes or workarounds, it just seems to work OK now. My guess is that Ludei have fixed the problem on their end. Edit: Oops, this is an old thread, and I wasn't paying attention close enough when I received this in my email... it works with pixi and cocoonjs, but I haven't yet tested with phaser. I apologize for posting erroneous information. Sorry guys! Link to comment Share on other sites More sharing options...
rich Posted May 6, 2014 Share Posted May 6, 2014 I'm a bit confused: I thought since the pixi guys apparently didn't merge the above fix, yet, I'd just go and throw it in myself. But I tried to locate the PIXI.BitmapFontLoader within the pixi.js (not minified) that comes with Phaser (2.0.4) or even within the phaser.js file but couldn't find anything. What am I missing? Or rather: How would I have to approach this? I thought I'd be less hassle than converting XMLs to JSONs and stuff. They're not included because Phaser doesn't use any of the Pixi asset loading methods at all. Link to comment Share on other sites More sharing options...
Michel (Starnut) Posted May 6, 2014 Share Posted May 6, 2014 @Rex Rhino no worries. That's good to know! @rich: That's unfortunate. Since this topic is filed under "Phaser" I was hoping the fixes were all Phaser related. But now I'm pretty stuck: I tried to apply the DOMishParser approach and it doesn't seem to work with 2.0.4 anymore. It blew up in my face trying to execute a getAttribute() call on the "info" object. I used the data provided by @GregP but still it wouldn't even finish parsing. I attempted to fix it but without any luck so far. Is anything in the works to allow loading JSON data with bitmap fonts for Phaser? Link to comment Share on other sites More sharing options...
Hsaka Posted May 6, 2014 Share Posted May 6, 2014 Hey @Starnut, I use a modified version of the DOMishParser:(function (cocoonjsphaser) { cocoonjsphaser.utils = { fixDOMParser: function () { window.DOMParser = DOMishParser; } }; function DOMishParser() { } DOMishParser.prototype.parseFromString = function (data) { return new DOMishObject(JSON.parse(data)); }; function DOMishAttributes() { } DOMishAttributes.prototype.getNamedItem = function (name) { return { nodeValue: this[name] || null }; }; function makeDOMishObject(data) { return new DOMishObject(data); } function DOMishObject(data) { this.attributes = this.convertContent(data); this.length = Object.keys(this.attributes).length; } DOMishObject.prototype.documentElement = document; DOMishObject.prototype.convertContent = function (obj) { var attributes = new DOMishAttributes(), prop; for (prop in obj) { if (obj[prop] !== null && typeof obj[prop] === 'object') { attributes[prop] = Array.isArray(obj[prop]) ? obj[prop].map(makeDOMishObject) : new DOMishObject(obj[prop]); } else { attributes[prop] = obj[prop]; } } return attributes; }; DOMishObject.prototype.getElementsByTagName = function (name) { return this.attributes[name] ? Array.isArray(this.attributes[name]) ? this.attributes[name] : [this.attributes[name]] : []; }; DOMishObject.prototype.getAttribute = function (name) { return this.attributes.getNamedItem(name).nodeValue; };}(window.cocoonjsphaser = window.cocoonjsphaser || {}));if (navigator.isCocoonJS) { cocoonjsphaser.utils.fixDOMParser();} Link to comment Share on other sites More sharing options...
Michel (Starnut) Posted May 7, 2014 Share Posted May 7, 2014 @Hsaka Thanks for sharing, that really saved me a lot of time. Now all the JS errors are gone, but seems it doesn't like the converted Littera output. Which font tool are you using? BMFont / BMGlyph / GlyphDesigner? I'm on OSX. Link to comment Share on other sites More sharing options...
Hsaka Posted May 7, 2014 Share Posted May 7, 2014 I'm using BMFont and generating the JSON using haden's nodejs script: http://www.html5gamedevs.com/topic/2312-ludei-cocoonjs-xml-bitmap-font-workaround/?p=17263 Link to comment Share on other sites More sharing options...
Michel (Starnut) Posted May 9, 2014 Share Posted May 9, 2014 Hey everyone, it all works perfectly for me, now (Phaser 2.0.4, CocoonJS 2.0, iOS 7.1.1). Since I found it a bit hard to collect all of the pieces from across the forum and the web, here's a quick guide with an improved conversion script that might help anyone still dealing with this issue: 1. Create the bitmap font with any tool that provides XML based BMFont output. Personally I used bmGlyph for Mac, but it should work fine with Littera (free web service) or GlyphDesigner as well. Angel Code's Bitmap Font Generator for Windows. 2. I use the modified DOMish parser suggested by @Hsaka in my index.html right before I create the Phaser game instance. 3. I pick the file-format within the preloader depending on whether it runs under CocoonJS or not and attach it to the file names like so:var fileFormat = (this.game.device.cocoonJS) ? '.json' : '.xml';this.load.bitmapFont('titleFont', 'assets/fonts/title-font.png', 'assets/fonts/title-font' + fileFormat);4. I rename the font data files from .fnt to .xml and convert them using a modified version of @Hadan's nodejs script (you need nodejs installed for this). I improved it so it converts all .xml files within a given folder to .json files. The command line call now looks like this (assuming it lies at the top level of your project):$ node fontConverter.js assets/fonts/If you don't pass a folder, it converts all files within the folder the script lies in. Moreover, you can now pass it a string to filter for, if you don't want all of the files in the given folder to be converted. The following call converts all XML files in the folder assets/fonts/ that have 'title' in their names:$ node fontConverter.js assets/fonts/ titleAnd here is the above mentioned script from the fontConverter.js file:var fs = require('fs'), xml2js = require('xml2js');// init the file parservar parser = new xml2js.Parser({ explicitRoot: false, mergeAttrs: true, explicitArray: false });// init the target directoryvar targetDir = __dirname + "/";// check if a target directory was passedtargetDir += (process.argv.length > 2) ? process.argv[2] : '';// check if a file filter was passedvar fileFilter = (process.argv.length > 3) ?process.argv[3] : null;console.log('\nLooking for files in', targetDir);if (fileFilter) console.log("... the names of which contain the string '"+fileFilter+"'\n");var parseNextFile = function(files){ if (files && files.length > 0) { // get the first file in the list var file = files.shift(); // split off pure file name without format ending var fileName = file.substr(0, file.indexOf(".")); // read the file fs.readFile(targetDir + file, function(err, data) { // parse the file's content parser.parseString(data, function(err, result) { // keep only the relevant information result.char = result.chars.char; delete result.chars; // turn it into a JSON string and write it into to a .json file with the same name as the XML fs.writeFile(targetDir + fileName + ".json", JSON.stringify(result), function(err) { if (err) { console.log(err); } else { console.log("Converted file", file, "to", fileName + ".json"); // parse the next file parseNextFile(files); } }); }); }); } else { console.log("Conversion complete...\n"); }};// check if the target directory existsif (!fs.existsSync(targetDir)){ console.log(targetDir, "does not exist!");}else{ // read all files from the target directory var files = fs.readdirSync(targetDir); var n = files.length, i; for (i = n; --i >= 0;) { var file = files[i]; var index = file.indexOf(".xml"); // only process XML files that match the given filter if (index === -1 || (fileFilter && file.indexOf(fileFilter) === -1)) { // delete the file entry files.splice(i, 1); } } if (!files || files.length === 0) { console.log("No files found!"); } else { // parse all found files parseNextFile(files); }}It's a mix of synchronous and asynchronous calls, cause I didn't manage to let it all asynchronously and I'm a little short on time. Not perfect but it does the trick. Thanks to everyone who shared information on this. You're awesome!Without you guys, I would've lost days and most probably my mind. EDIT: Just noted there was some duplicate check in the code and cleaned it all up a bit more. kidos, avewells, patmood and 3 others 6 Link to comment Share on other sites More sharing options...
villetou Posted June 2, 2014 Share Posted June 2, 2014 Here's also a solution which works with the original XML font files: https://github.com/videlais/xml-for-cocoonjs Here's the script file which I tried in my project: https://raw.githubusercontent.com/videlais/xml-for-cocoonjs/master/src/xml-for-cocoonjs.js Worked like magic ...Although, a JSON bitmap loader in Phaser/PIXI itself would still be pretty sweet. Rorian 1 Link to comment Share on other sites More sharing options...
Toknos Posted July 22, 2014 Share Posted July 22, 2014 Hi, I'm sorry if this is a stupid question, I'm pretty new to this whole thing... but where do I write the fixed DOMishParser?I've currently written it in it's own file and then I've done this in index.html: if (navigator.isCocoonJS) { cocoonjsphaser.utils.fixDOMParser();}and then in my preload: var fileFormat = (this.game.device.cocoonJS) ? '.json' : '.xml';this.load.bitmapFont('bitFont', 'fonts/bitFont.png', 'fonts/bitFont' + fileFormat);but I get an error when I run it in the launcher:"JavaScript Exception (line:13 Tag: 'load'): Error:Phaser.Loader.Invalid XML given"What have I done wrong? Does that mean I haven't probably changed the loader or hasn't it been converted to json correctly? Link to comment Share on other sites More sharing options...
Toknos Posted July 24, 2014 Share Posted July 24, 2014 Anybody knows what's wrong? Link to comment Share on other sites More sharing options...
Hsaka Posted July 24, 2014 Share Posted July 24, 2014 Hey Toknos, did you use the nodejs script (http://www.html5gamedevs.com/topic/2312-ludei-cocoonjs-xml-bitmap-font-workaround/?p=17263) to convert your bitmap font to json? Did you use BMFont to create your bitmap font? Link to comment Share on other sites More sharing options...
Michel (Starnut) Posted July 24, 2014 Share Posted July 24, 2014 @Toknos I pasted the DOMish parser code right before creating the game instance within the index. I didn't put it into a file of it's own. It looks like this:<script type="text/javascript">(function (cocoonjsphaser) { cocoonjsphaser.utils = { fixDOMParser: function () { window.DOMParser = DOMishParser; } }; //... rest of the implementation}(window.cocoonjsphaser = window.cocoonjsphaser || {}));(function () { // I use this HTML file for CocoonJS only, so no extra check necessary. cocoonjsphaser.utils.fixDOMParser(); //... check for width and height. var game = new Phaser.Game(width, height, Phaser.CANVAS, ''); //... declare states and start Boot state.})();</script>Both scripts (haden's and my adaption) only work with XMLs in BMFont format. So either use the BMFont tool (Windows) directly to create them or use a tool that produces equivalent (e.g. bmGlyph on Mac) output. Then run the script to convert the XMLs. I'm not sure but I think I remember Littera output to not be compatible. Also: make sure, your cocoonJS checks works and returns "true" under CocoonJS. If you don't use Phaser.States in your project, but instead have all the code in one file, you may have to omit 'this.' in 'this.game.device.cocoonJS' in order to make it work - but then again your load call shouldn't work either, so maybe you are using states - but I thought I'd just mention it. Let us know if any of this helped. Link to comment Share on other sites More sharing options...
San4er Posted July 27, 2014 Share Posted July 27, 2014 I use Phaser 2.0.7Is there any solution for Literra fonts?When I try to use it with CocoonJS I get error:JavaScript Exception ( Tag: 'load'): Error:Phaser.Loader. Invalid XML givenat Phaser.Loader.xmlLoadComplete (script/phaser.js:48365:19)at XMLHttpRequest._xhr.onload (script/phaser.js:48047:33)And if not, what the easiest way to use custom fonts without any hacks? Link to comment Share on other sites More sharing options...
Toknos Posted July 28, 2014 Share Posted July 28, 2014 Hey, I got it to work, thanks!@San4er: make sure the file is correctly converted, that was the problem I had. I used Literra too for the xml output and eventually converted it with the nodeJS script mentioned earlier. Link to comment Share on other sites More sharing options...
zablockijj Posted July 29, 2014 Share Posted July 29, 2014 I still am unable to get the workaround to work posted here: http://www.html5gamedevs.com/topic/2312-ludei-cocoonjs-xml-bitmap-font-workaround/?p=37671 I am using Phaser 2.0.7 and testing with Cocoon 2.0.2 and 1.4.7. I test on my Note II. I run the code using the DOMishParser no matter what and it works in Chrome browser on my computer and on phone's browser (also Chrome). However, when I run the code in Cocoon's launcher, no text shows up. I changed the code toif (navigator.isCocoonJS || 1 == 1) { cocoonjsphaser.utils.fixDOMParser();}var fileFormat = (navigator.isCocoonJS || 1 == 1) ? '.json' : '.xml';in order to force the game to always use the DOM parser fix. I use fontConverter.js to convert the xml file produced by bmGlyph and it works fine in browsers. No errors are shown in the Cocoon debugger, no text shows up however. Link to comment Share on other sites More sharing options...
patmood Posted July 30, 2014 Share Posted July 30, 2014 @Starnut THANK YOU This thread was tricky to find but your implementation worked perfectly! Link to comment Share on other sites More sharing options...
Michel (Starnut) Posted July 30, 2014 Share Posted July 30, 2014 @zablockijj Hard to tell what's wrong if the debug console remains silent. If it failed to parse the JSON files you'd for sure get an error. Maybe the problem lies elsewhere?I have to admin that I haven't tried Phaser 2.0.7, yet, but either way I'd stick with CocoonJS 2.0.2 (not 1.4.7). And I would make sure to avoid building potential traps with complicated checks that are supposed to return true anyways. Keep it simple and remove all potential trouble makers until it works ...//if (navigator.isCocoonJS) { cocoonjsphaser.utils.fixDOMParser();//}var fileFormat = '.json';//(navigator.isCocoonJS) ? '.json' : '.xml';... and then slowly start commenting in the code again until it breaks. @patmood thanks for the feedback. Glad I could help Link to comment Share on other sites More sharing options...
Hsaka Posted July 30, 2014 Share Posted July 30, 2014 @zablockijj I've attached a bitmap font which works for me. It was created using bmfont. You could probably swap your font for this one and see if it works for you. If it works, you can compare the json and see if there are any differences. (Not allowed to upload json files so rename mecha.txt to mecha.json)mecha.xmlmecha.txt Link to comment Share on other sites More sharing options...
zablockijj Posted July 30, 2014 Share Posted July 30, 2014 EDIT: I solved my disappearing sprite and text problem. For whatever reason in Cocoon, adding the following line:this.game.add.sprite(-200, -200, '');fixed the problem. ORIGINAL: @Hsaka, you're bitmap font worked amazingly!! Thank you. I am running into the problem, however, where, in Cocoon only (not in my browser), the text is disappearing after a few seconds until a collision event between two entities occurs and updates the score. What I find throughout my game is that depending on the order that I create sprites, text, etc in the create functions, those created in the latter portion of the create function for a game state will fail to be visible in Cocoon when I test. The sprite (or text) will exist and have its touch events and all, however, I cannot see them on the screen (i.e. they are invisible). THIS DOES NOT HAPPEN IN MY BROWSER. Here is where I call the text:create: function() { ...stuff, other sprites are made... scoreText = game.add.bitmapText(20, 20, 'mecha','Score: '+score, 30); livesText = game.add.bitmapText(20, 50, 'mecha','Lives: '+lives, 30);},update: function() { scoreText.setText('Score: '+score); livesText.setText('Lives: '+lives); // if a collision happens then call function that increments score of decrements lives}I don't know why some sprites and text is disappearing after a few seconds of visibility. Link to comment Share on other sites More sharing options...
San4er Posted July 31, 2014 Share Posted July 31, 2014 Thanx all of you - now it works using DOMishParser and nodejs converting script. But I hope it will work by default without any of this hacks soon Link to comment Share on other sites More sharing options...
iLKke Posted August 19, 2014 Share Posted August 19, 2014 Sorry if this is a silly idea, but I thought it might be simpler for some cases than converting the font data to JSON. How about loading the font as a spritesheet?With fixed width fonts (for example pixel fonts) all you'd need is a text string with the order of characters like "abcdefghijklmnopqrstuvwxyz0123456789,.!?;:'()-+" to act as a lookup table, and of course you'd need a custom function to convert any string of text into a block of graphics on the screen. Again apologies if this only makes sense to myself Link to comment Share on other sites More sharing options...
lukaszwojciak Posted October 18, 2014 Share Posted October 18, 2014 And I'm still using this in all my projects: https://github.com/GoodBoyDigital/pixi.js/pull/565nobody loves this piece of code so I'm the only happy one, sitting alone in my fork.. Link to comment Share on other sites More sharing options...
BdR Posted December 9, 2014 Share Posted December 9, 2014 EDIT: solved this one, see next post Hey @Starnut, I use a modified version of the DOMishParser: Hey everyone, it all works perfectly for me, now (Phaser 2.0.4, CocoonJS 2.0, iOS 7.1.1). Since I found it a bit hard to collect all of the pieces from across the forum and the web, here's a quick guide with an improved conversion script that might help anyone still dealing with this issue: Thank you both for sharing your solutions I would have never figured this out by myself.. However, I've implemented it, get no errors but the texts are not displayed. I've added the DOMishParser from Hsaka and I've converted the .xml file to .json with this online tool (with "Prefix attributes " set to empty, and "JSON output indentation" to tab delimited) which as far as I can see gives the same result as the nodejs script, the resulting json file gives no errors when loading. I've whittled it down to the bare minimum, all that my example code does (see github link below) is replace the DOMParser, replace .xml with .json in the preloader and display some texts. I've added my own test variable TEST_FONT_JSON which replaces the "if (navigator.isCocoonJS)" just so that I can test the code example in the Chrome desktop browser. When I set TEST_FONT_JSON=false it loads normally with the xml file and the texts are displayed fine. But when I set TEST_FONT_JSON=true then it loads the json file without any errors in the console but no text is displayed.. What am I doing wrong here? github code example:https://github.com/BdR76/phaserbitmapfont Link to comment Share on other sites More sharing options...
BdR Posted December 9, 2014 Share Posted December 9, 2014 @zablockijj I've attached a bitmap font which works for me. It was created using bmfont. You could probably swap your font for this one and see if it works for you. If it works, you can compare the json and see if there are any differences. (Not allowed to upload json files so rename mecha.txt to mecha.json) I've taken a look at your mecha.txt as a reference and I've found the error in my example, it was in the json file structure. Apparently the json converter handled the char-section slightly different than the nodejs script. My chars section in the json file looked like this:"chars": { "count": "91", "char": [ { "id": "97", etcInstead of just this (so without an extra chars container): "char": [ { "id": "97", etc.I've changed this manually and now it works Btw I also removed my whole kernings section, it doesn't seem to be used at all, at least I don't see any difference without it. The "pages" section in your mecha.txt is also a little different, but I've left my section as pages-page and that also seems to work. But I hope it will work by default without any of this hacks soon Amen to that.. Link to comment Share on other sites More sharing options...
Recommended Posts