This Issue is about a bug in the API (v3.3.0):
I have tried wrapping a Phaser app in Cordova/ React Native.
It mostly worked but there are issues with loading files. Neither images nor json can be loaded, they fail without a proper error.
After close debugging I noticed that the "Request Type" comes up as XHR whereas with Phaser 2.x it's image/ json like it should be.
I have set up a very basic example textures/sprite sheet.js and a more complex project, both fail.
Could this be related to #2670 or #2485? Did this fix get lost in 3.x?
Any help is very appreciated, did anybody manage to wrap a Phaser 3 project with Cordova?
Cheers!
p.s.: www.zip the content of www within the Cordova app

UPDATE 29.03:
I have looked into this more. It seems like the issue has to do with the Phaser 3 loader not being able loading resources from file://. When I open the basic texture examples from Phaser 2 without being served from a server they work just fine, the Phaser 3 ones don't. Seems the loader does something differently so CORS becomes an issue.
There is a $50 open bounty on this issue. Add to the bounty at Bountysource.
Hello, I am able to load from file:// resources just fine in electron. Perhaps this is an issue with the browser that your game is running in?
I'm having the same issue on my application that I tried to run under Cordova/PhoneGap.
The images do not show up, that's a big blocker for Mobile development.
@Mikurox have you tried moving your assets in a folder relative to your index.html and instead of a file:// path, just using relative imports? E.g. ./images/player.png (if images is a folder in the same directory as your game)
It works when I use images in the index.html or reference them in css file.
The issue I'm seeing is that they are not loaded (I see green lines) when I try to load an image in "preload" and use it in "create" functions, e.g.
this.load.image('starfield', 'assets/images/starfield.png');
...
this.bg = this.add.tileSprite(0, 0, this.game.width, this.game.height, 'starfield');
It's working when using the "browser" platform but not "android"
Exactly what @Mikurox said. Using the built-in Phaser function this.load.image('starfield', 'assets/images/starfield.png') it depends which "server" is serving the files.
When using a server that deals with proper serving of files all is fine, when just opening the .html in the browser although using relative path the images don't load.
The same issue is happening with Cordova apps as it seems it does not serve the files as a "server" but just accesses them through their path from the filesystem.
Phaser 2.x didn't have an issue but something must have changed in the Phaser 3.x Loader.
Yes, the v3 loader uses xhr for all files to get per-byte download feedback, per-file. I have posted a bounty on this issue as I don't have Cordova / PhoneGap set-up, so it would take a while to debug here.
I might be able to take a look at this, this weekend. If you provide a example where this happens I'll save some time and might be able to do it :-)
I've tested it just in few platforms but a possible solution is to use url-loader with blobs. In your webpack.config.js
{
test: /\.(png|jpg)$/,
use: [
{
loader: 'url-loader',
options: {
limit: 0,
},
},
],
}
Then import of your static file will return b64 string import sprite1png from '../../../assets/sprite1.png';
This needs to be further converted to blobs to create the link;
`const b64toBlobUrl = (data, sliceSize = 512) => {
const parts = data.split(',');
const b64Data = parts[1];
const typeAndBase = parts[0].split('data:')[1];
const contentType = typeAndBase.split(';')[0];
const byteCharacters = atob(b64Data);
const byteArrays = [];
for (let offset = 0; offset < byteCharacters.length; offset += sliceSize) {
const slice = byteCharacters.slice(offset, offset + sliceSize);
const byteNumbers = new Array(slice.length);
for (let i = 0; i < slice.length; i++) {
byteNumbers[i] = slice.charCodeAt(i);
}
const byteArray = new Uint8Array(byteNumbers);
byteArrays.push(byteArray);
}
const blob = new Blob(byteArrays, { type: contentType });
return URL.createObjectURL(blob);
};`
and use it this.load.image('sprite1', b64toBlobUrl(sprite1png))
Cheers for all the feeback and ideas. Will look into this more after the weekend!
@Saturate just try opening a basic Phaser 3 example directly from a folder in your browser. The error will happen as it can鈥檛 load the files through xhr. Use Chrome so you get an error message in the console.
Not sure this helps. I haven't had a chance to try it, but there is a tutorial on line.
https://gamedevacademy.org/creating-mobile-games-with-phaser-3-and-cordova/
Never mind, I tried the tutorial and the graphics don't show up
Hi,
@sftsk: incompatibility of Phaser 3 with direct loading through file:// protocol looks to be a design choice, as explained in the Getting Started tutorial part 1: https://phaser.io/tutorials/getting-started-phaser3
As described the solution for desktop browsers is to serve files through a server, which is a very standard practice nowadays, even for development.
As for Cordova in iOS, which is OP's described situation, the above solution is more complex to implement, but it is still a known and widely used practice as well.
There are many Cordova plugins that patch the Webview, for example:
While @Huararanga's workaround is probably valid, a drawback is that all files are now base64 strings in your code, making it much heavier.
Furthermore, browsers and Webview cache files loaded the standard way, so rendering multiple instances of them is no problem. On the contrary, performance degrades when using base64 data multiple times.
Hope this helps.
As I mentioned above v3 uses xhr for all files, including images. v2 used the Image tag itself to load them, however it still used xhr for all json, xml, etc. I believe under Cordova in v2 you were still able to load things like texture atlases and bitmap fonts without any issue, so xhr must have been working to some extent back then? Which makes me wonder if it's actually something else causing this.
I have finally had time looking into this and got into the same solution as proposed by @ghybs .
Installing https://github.com/ionic-team/cordova-plugin-ionic-webview with Cordova fixes the issue. This will only be a fix for iOS, although probably for Android exists something similar.
I don't think there is anything to be done within Phaser as this XHR Cross Origin policy seems to be a limitation that can't be easily worked around on mobile. Chrome has a flag --disable-web-security that will allow the requests, not sure if that could be an option for Android.
Anyway, thanks for all the help, issue can be closed from my point of view. Perhaps add some instructions to the manual of needing the mentioned plugin when wrapping an app with Cordova.
Hi guys,
Thanks for investigating this, I guess if it's not a pure Phaser problem, then this can be closed.
However, I would believe that we need an "official" way of dealing with this, since we will not be the only ones having this issue. A Cordova section in tutorials or somewhere exposed should clarify how Phaser can work with Android/iOS. There might be other "tweaks" to do for mobile development as well and having a dedicated section will greatly help everyone.
Just as little extra info. The demo I mentioned above works fine on android. Images/Atlas load and show properly on a galaxy s8. So this definitely appears to be a an iOS issue.
Adding the cordova-plugin-ionic-webview as suggested by @ghybs and @sftsk worked for me.
At least it started loading my json file then. For the spritesheets to show up i had to change:
<meta http-equiv="Content-Security-Policy" content="default-src 'self' data: gap: https://ssl.gstatic.com 'unsafe-eval'; style-src 'self' 'unsafe-inline'; media-src *; img-src 'self' data: content:;">
to:
<meta http-equiv="Content-Security-Policy" content="default-src 'self' data: gap: https://ssl.gstatic.com 'unsafe-eval'; style-src 'self' 'unsafe-inline'; media-src *; img-src 'self' data: content: blob:;">
In the cordova index.html. Adding the blob: in at the end.
Still need to add sound to my current project though. If i need to do anything special for that i'll post it here.
Discovered this a couple of months ago. Does this help?
Phaser v3.x.x (20180322); WARNING ANTI-PATTERN REMOVED
// CORS: Remove anti-pattern!
// - https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS
// - https://enable-cors.org/
// Avoid this anti-pattern of omitting the protocols schemes in script "src";
// Cross origin requests are only supported for protocol schemes:
// http, data, chrome, chrome-extension, https.
// - anti-pattern is:
//
- use this:
Can't see how this makes any difference tbh. All asset loading is done via a protocol.
I tried that plugin but it always through error in XCode when compiling "cordova-plugin-ionic-webview"
so I decided to try "cordova-plugin-wkwebview-file-xhr" instead, it worked but it has weird thing about splashing the background with assets and any graphics library rect fill not working correctly (flickering).
I even tried adding "cordova-plugin-wkwebview-engine" as suggested by some websites but still the same problem
Attached some pics
http://akhalifa.com/elimination/error_1.jpg
http://akhalifa.com/elimination/error_2.jpg
I was very excited to start a project that uses phaser3-typescript-webpack-cordova. Everything works perfectly until I start testing the cordova with the build package. The phaser assets loader isn't designed for loading assets from IOS. Really hope there's an official instruction of how to load assets from Cordova wrapped app. Thanks.
These are some of the solutions I stumbled upon, hope it is helpful:
https://phaser.discourse.group/t/troubleshoot-cordova-phaser-3-the-preloader-scene-is-being-refreshed/625/2
It is not still 100% solved. I will be happy if you found a solution to the sound problem.
I've just merged in a PR which should (?!) resolve this, so would be happy if someone using Cordova on iOS could build from master and test it please.
Doesn't work, But there is a difference of behavior in iOS and Android. In iOS:
Game loads and is playable it's just that img doesn't load.(also maybe audio didn't test for that)
For android:
Nothing loads. It just serves a blank screen.
Is there any update about this problem?
I am using static files in my android project but my Phaser game's images doesnt shown.
Most helpful comment
Adding the cordova-plugin-ionic-webview as suggested by @ghybs and @sftsk worked for me.
At least it started loading my json file then. For the spritesheets to show up i had to change:
to:
In the cordova index.html. Adding the
blob:in at the end.Still need to add sound to my current project though. If i need to do anything special for that i'll post it here.