Jump to content

Common Phaser + CocoonJS issues


Recommended Posts

Last update of this information was 13 August 2014.


Note: As of this writing, CocoonJS (2.0.*) comes in a total of three modes.


[system] WebView creates an instance of the default browser for a platform, loads its own API, and then hands off the code execution. In most cases, it is the same as running the code in a mobile platform's default browser.


WebView+ is often the same as WebView, but adds in Chromium-based libraries.


For Canvas+ mode (previously accelerated, "Canvas 2D/WEBGL") it strips out things like XML and most DOM and CSS support to make running the canvas as fast as possible. Because of this, most common things like getElementById and createElement in JavaScript have reduced functionality. It is designed purely for Canvas-based projects. (For the 2.0 branch, see the changelog from 1.4.7.)


Since there is limited DOM support, make sure to use an empty string for the parent element during the creation of a game object when using the accelerated/Canvas+ mode. (This is to make sure the created canvas element is appended to the document.body object, and not some other element the getElementById function cannot find.)

var game = new Phaser.Game(window.innerWidth, window.innerHeight, Phaser.CANVAS, '', {preload: preload, create: create, update: update});

Issues with Phaser <= 2.0.7 and CocoonJS <= 2.0.2 (Canvas+)




Use of multiple images may introduce disappearing or flickering results.




Single-line text printing works. However, using the newline character will not produce the correct results.

  • Setting anchor.y values do not work correctly.
  • Shadows do not work.




CocoonJS does not have native support for XML. Its XHR does not return responseXML and it does not have a window.DOMParser object.




Generally, you can use window.innerWidth and window.innerHeight to compute the size of the screen in CocoonJS. However, if you know there might be a device pixel ratio issue, the following code works for that.

var width = window.innerWidth * window.devicePixelRatio;var height = window.innerHeight * window.devicePixelRatio;

Depending on your needs, Phaser's built-in scaling manager will often be enough.


However, the following code suggested by Starnut should be helpful for accounting for odd screen sizes as well.

var w = window.innerWidth * window.devicePixelRatio,h = window.innerHeight * window.devicePixelRatio,width = (h > w) ? h : w,height = (h > w) ? w : h;// Hack to avoid iPad Retina and large Android devices. Tell it to scale up.if (window.innerWidth >= 1024 && window.devicePixelRatio >= 2){width = Math.round(width / 2);height = Math.round(height / 2);}// reduce screen size by one 3rd on devices like Nexus 5if (window.devicePixelRatio === 3){width = Math.round(width / 3) * 2;height = Math.round(height / 3) * 2;}var game = new Phaser.Game(width, height, Phaser.CANVAS, '');



Because of the lack of XML support, one solution for BitmapFonts is to convert the XML into JSON and use an alternative loader. This post covers the code needed and what to use to convert the XML into JSON.




Most often, audio problems are related to the device itself, not CocoonJS or Phaser. If you are running on an Android device, make sure you have OGG or WAV (16-bit ONLY) files. Apple devices support MP4, OGG, MP3, WAV (16-bit ONLY), or MPEG. (Remember too that MP3 decoding, depending on the device, can often be slow.)


On some platforms, a user-activated event (like touch) is needed to enable sound. This specifically affects iOS devices, but is not uncommon on other platforms too. Using something like a "Tap to Continue" button or an initial menu works well to signal to the player to tap to enable both the game and sounds.




Filters don't work currently. (As reported here.)




There is currently a problem where image-based buttons can sometimes disappear. It is under investigation.



It is HIGHLY recommended to update to newer versions of Phaser ( >=2.0.7) and CocoonJS ( >=2.0.2). Issues between older versions of both libraries are no longer being actively tracked.

Link to comment
Share on other sites

@jerome: Please do! That's been the one problem with all this, the lack of documentation and general knowledge about getting things working with CocoonJS.


I'm still hunting down some occasional issues with gamepads on Ouya in Phaser, but plan to write a guide on all this at some point soon myself. I've been trying to decide if I should wait for 1.2 or cover adding in all these different patches as part of the guide.

Link to comment
Share on other sites



As a member of the Ludei team, first of all, thank you for your effort on this. Game engines is key for us but being a small startup it is hard to work on all of them to make them fully compatible so your work is much appreciated.


Let me add some comments on some of the issues you have found:


* We are working on adding the window. CanvasRenderingContext2D and WebGLRenderingContext types to CocoonJS. Hopefully, they will be available in the next release.

* screencanvas is a great feature to accelerate performance in many devices (specially Android). It's great you found the way to include it.

* It's true: The latest versions of CocoonJS on Android, do not support MP3.

* navigator.getGamepads is the W3C standard API to access gamepads.


Once again, thank you very much for your hard work. Do not hesitate to provide us with all the feedback you can on how to improve some things.


We hope the Phaser community can benefit from the acceleration and features of CocoonJS.




Link to comment
Share on other sites

@judax: Thank you for posting and confirming these issues!


While the above information covers most of the common issues, I've recently discovered some more problems when running CocoonJS on the Ouya and specifically using the Gamepad API. (I have not been able to confirm these on other hardware and platforms yet.)


As I mentioned in this topic the other day (and is now a question in the Ludei Support Center too), the 'index' property values on gamepads do not seem to be re-used after disconnection events. They always increase by one with each gamepad connected to the system. The Custom Launcher also occasionally remembers index values between sessions, starting the next run project with the last index value used plus one.


I have also had issues with the 'timestamp' values on gamepads not updating at all, no matter the gamepad used.


As of today, I have documented a strange bug with the first indexed gamepad's axes[0] and axes[1] reading very large numbers while at rest as well. As can be seen here with an Ouya gamepad, here with a PS3 gamepad, and here with a Xbox 360 gamepad, whatever gamepad is connected in the first slot will have large numbers as values for its first two axes. If they are moved even the smallest amount, the values produced are in the correct range, -1 to 1, but when at rest, and only with the first gamepad each time, these numbers seem to be appearing.


See the top post for latest information.

Link to comment
Share on other sites



As confirmed in the Ludei Support Center,

  • "timeStamp is always 0, yes.
  • It is true that the gamecontroller indices increase after disconnection."


For the moment, it looks like fixed-rate polling is the best way to go for CocoonJS on the Ouya (and possibly on other Android devices). I'm still working on a plugin and should be done within the next couple of days. At that point, I'm also going to expand out the Text section above, as I have some more solutions for that, and include many more details about what to expect when using the gamepad API.

Link to comment
Share on other sites

Thanks for the information, its very useful.


Yet, there is one thing I can't understand. You recomend avoiding XML, but you also say we should use BitmapText. 

I can't load my BitmapText fonts, because CocoonJS launches an exception (invalid XML given) when trying to load the XML that defines the font, and I don't see any way to load a Bitmap font other than XML.

Link to comment
Share on other sites

@mariogarranz: Confirmed.


I tried the Bitmap font example with Phaser 1.2 and got the exact result you described on my Ouya.


While I was testing my own gamepad polling code with the Gamepad Debug example, I noticed another text problem too, where the text would seem to layer or even disappear if it was updated at all. The more rapid the change, the less likely it would be seen over time.


I was hopeful, since learning CocoonJS supports loading TrueType fonts directly, that the problem would go away when using those, but it seems to be tied to some combination of Pixi and CocoonJS. At least in the code examples I've seen from Ludei, they seem to be writing directly, using fillText calls, to the 'screencanvas' element's drawing context. I'm curious if the solution is in either having Pixi.Text use 'screencanvas' elements (instead of 'canvas' ones), or if all Pixi.Text calls should operate on the 'screencanvas' used by world.stage. I'm not sure.


More testing is needed.

Link to comment
Share on other sites

@rich: I saw your questions right after you posted them, but wanted to make sure I had run several more tests before answering.


Here is what I've tested and documented with screenshots today:

  • The CocoonJS Custom Launcher has TrueType font support. (Search for "TrueType Fonts" for the example on the demo page.)

    Create a "fonts" directory from the root of your project. Place any TTF files you want CocoonJS to use.
    When run, CocoonJS will automatically read and load all TTF files it finds.

    To use these in your project, use the filename before the extension. For example, if the TTF file was "arial.ttf", you need to reference it as "arial".

    However, what is not documented (yet), is that the Custom Launcher will retain these fonts in memory for as long as it is running. If you run another project with those fonts, CocoonJS will report a "Custom font failed to load" message, but still use them -- it doesn't reload them, in other words.
  • Using multiple 'screencanvas' elements seems to confuse CocoonJS. When I tried changing Pixi.Text to use 'screencanvas' instead of 'canvas', it crashed the application after running for a few seconds.
  • Directly writing text to the 'screencanvas' does seem to work. (Note: I have a "arial.ttf" file in a "fonts" directory with this code to guarantee the font exists.)
    (function(window, Phaser) {  var game = new Phaser.Game(window.innerWidth, window.innerHeight, Phaser.CANVAS, '',          {preload: preload, create: create, update: update});  function preload() {}  function create() {}  function update() {    writeText("Updated text");  }  function writeText(string) {    var context = game.canvas.getContext('2d');    context.font = "45px arial";    context.textAlign = "left";    context.fillStyle = "#ffffff";    context.fillText(string, game.world.centerX, game.world.centerY);  }})(window, Phaser);

My current thinking is to either have a reference to the current canvas in Pixi.Text (which I'm currently working on), or write some code that acts like Pixi.Text, but is custom designed for CocoonJS usage. Maybe something like Pixi.CocoonJSText that is used only when CocoonJS is detected? I don't know. I think I might be able to pass a reference to the canvas via Phaser.Text somehow.

Link to comment
Share on other sites

  • 2 weeks later...

Hi, i have some trouble with image/texture when used in CocoonJS. I dont know why but sometimes images does not appear, specialy when used as button texture but not only.


invisible buttons still work, but when i click on it texture blink.


Everything work fine in the browser. I tried differents textures.


Any idea ?


Edit: i only use Phaser.CANVAS. (images works in WEBGL but not the rest of my game :) )

and it seems to not show only the last image added.

Link to comment
Share on other sites

@mamwalter: Does everything work outside of CocoonJS? When run on a Desktop browser like Chrome or Firefox, does everything appear correctly? Are there differences between the WebView and the Accelerated View with your code in CocoonJS? Does one work better than the other, or are the problems the same in each?


If you can, it is worth trying different combinations of Desktop or mobile browsers before using CocoonJS. Knowing if something works on a mobile platform's default browser, for example, will often let you know if the WebView mode will work for you (as it uses the same software).


Are you using the Custom Launcher or code run through the cloud compiler? If you can, always test using the Custom Launcher before using the cloud compiler. You get access to the console and can often diagnose problems faster. Oftentimes, this will let you know if there are loading problems with resources like images or other files.


Finally, try debugging your code with some calls to console.log. I know I often make small typing errors in my code. I've often found it can helpful to step through some small section line-by-line just to double check values are being set correctly or certain calculations are being made as they should be. Maybe that will help you too with this.

Link to comment
Share on other sites

@videlais: everything works fine when i try in browers ( desktop and mobile ), and in webview  (i use the CocoonJS launcher for the moment).  The problem is only with the canvas.


There is no error in the console. Images are loaded, i can see it in the console.

Like i just explain before only the last added image disappear.


for example i have tried a splash screen state like this:

    Preloader.prototype.preload = function() {        this.game.load.image('splash', 'assets/images/screenshots/splash.jpg');    }    Preloader.prototype.create = function() {        console.log('Preload finished');                this.game.stage.backgroundColor = 0xf3f3f5;        this.bg = this.game.add.button(this.game.world.centerX, this.game.world.centerY, 'splash',this.startGame, this);        this.bg.anchor.setTo(0.5, 0.5);        this.bg.scale.setTo(config.GAME_SCALE, config.GAME_SCALE);    }

and the button doesn't appear but if i tried to put:

var fake = this.game.add.image(0, 0, '');

at the end of the create, then my button will be there.

Link to comment
Share on other sites

@mamwalter: I've confirmed this image issue. As you wrote, it not only affects buttons, but everything that relies on them. (It's showing up in another, emitter, issue too.)


I've started investigating this and will add it to the known issues list until a fix is in place.


In the meantime, if you solve this this, please let me know.

Link to comment
Share on other sites

Reporting some more funkiness - this time with Greensock's Tween libraries. Creating any Tween seems to stop rendering in its tracks.


I made a test scene which should display an image and tween it to the upper-left corner of the stage: http://codepen.io/momothemonster/pen/ukLeb


Cocoon doesn't play nice with codepen, so I've created two versions on my server for testing:


Working: http://mmmlabs.com/s...test/index.html

Non-Working: http://mmmlabs.com/s...stest/gsap.html


If you load these two urls in the browser, index.html will display a non-moving image, and gsap.html will display the image and then move it. If you load them into Cocoon using Webview/Canvas2D, index.html will display a non-moving image, and gsap.html will display nothing at all. The only difference is the tween call. Loading them using WebView works fine.

Link to comment
Share on other sites

@momothemonster: It might not be the tween but the image itself.


For example, the following code will not display anything currently.

var game = new Phaser.Game(800, 600, Phaser.CANVAS, '', {preload: preload, create: create}); function preload() {      game.load.image('diamond', 'diamond.png'); } function create() {     game.add.sprite(150, 150, 'diamond');}

So, it's probably that the images aren't being loaded correctly somehow. (I'm pretty sure now, after hours of testing, Pixi.js is to blame.)

Link to comment
Share on other sites

Weird. If you don't mind, then, could you try that above code with the image loading and displaying? Substitute in any image you want.


It hasn't worked for me all day and I've been trying to track down the reason. Run it using the accelerated mode in CocoonJS and let me know if anything appears at all.

Link to comment
Share on other sites

  • rich unpinned this topic

  • Recently Browsing   0 members

    • No registered users viewing this page.
  • Create New...