Videlais

Common Phaser + Apache Cordova issues

Recommended Posts

Last update of this information was 22 August 2014.

 

In the hope of collecting together the great wisdom of the Phaser community, I am creating this thread dedicated collecting the issues -- not unlike the CocoonJS thread of similar naming -- between Phaser and Apache Cordova.

 

[For the most part, these solutions work with PhoneGap too. However, at the moment anyway, I'm more interested in addressing the underlying system of both: Cordova.]

 

How does Cordova work?

 

When run on a device, Cordova creates a WebView, adds in API hooks, and loads the project via the FILE protocol. Put basically, it is like running your HTML5 project in a separate instance of the device's browser. However, unlike the device's browser, Cordova has the ability to be extended and granted access to additional functionality like the device's camera, geolocation data, or even barcode scanning through its plugins.

 

Do I need cordova.js?

 

Yes.

 

While it is true that you can run projects without this file, it sets up useful Cordova functionality and populates the window.cordova object with system details. Without it, Phaser will not be able to detect it is running under Apache Cordova.

 

Using --

<head>...<script src="cordova.js"></script>...</head>

-- will often be enough to load the script during run-time. (The file itself is added to the project during compilation or as part of established IDE functionality.)

 

What's this 'deviceready' event? [This is now part of Phaser 2.1]

 

Cordova was created to run on different devices with different requirements. One way to generalize all the required runtime tasks was to send a signal when everything Cordova-related was ready. That's what the 'deviceready' event is. Once it is sent, everything that was supposed to be loaded or created by Cordova (such as plugins) should now be ready.

 

For Phaser projects that will use any Cordova plugins, it is highly recommended to wait for this event to trigger before enabling any code.

 

For example, creating a function to load your game would look something like the following --

document.addEventListener('deviceready', loadGameFunction);

-- where loadGameFunction is a function to load your game or enable certain functionality for Phaser to use.

 

 

Common Issues

 

 

Scaled Viewport Size

 

For devices not running iOS, the following line can be added to the <HEAD> of the HTML file to create a viewport and scale up to the size of the device's screen.

<meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width, height=device-height, target-densitydpi=device-dpi" />

For iOS devices, drop the "width=device-width, height=device-height".

 

Audio

 

To enable media playback, you will need to add the Cordova.Media plugin.

 

Once loaded, audio objects will need to be created manually using the Media object.

var media = new Media(src, mediaSuccess, [mediaError], [mediaStatus]);

[Hopefully, a patch or plugin to detect and use this functionality automatically will make its way into Phaser in the near future.]

 

Debugging

 

Using console.log will send messages to CordovaLog.

  • Android
    If using an IDE, it will often filter ADB logcat for the specifically named project activity. However, if using the command-line interface or if not filtered directly, using programs like grep or find can help narrowing down Cordova messages. Examples of this would be something like "adb logcat | grep CordovaLog" to filter for log messages from Cordova, including those sent using console.log.

 

The 'Back' button

 

On those devices that have a 'back' button or similar functionality, it is currently possible to exit a Phaser project run in Cordova by pressing or triggering it twice quickly.

 

To prevent this action, you need to catch the event with code like the following:

document.addEventListener("backbutton", yourCallbackFunction, false);

See the Cordova documentation for greater details.

 

'Pause' and 'Resume' events

 

Whenever a Cordova instance is pushed to the background on a device, the 'pause' event is triggered. When it again is at the fore, the 'resume' event is triggered.

 

Unless these events are caught by an event listener, the default action for Cordova is to completely reload the page upon the 'resume' event, potentially erasing the states and values of all active variables.

 

To prevent this action, you need to catch both events and handle them somehow.

document.addEventListener("pause", yourCallbackFunction, false);
document.addEventListener("resume", yourCallbackFunction, false);

See the Cordova documentation on 'pause' and 'resume'

Share this post


Link to post
Share on other sites

 

Do I need cordova.js?

 

Yes.

 

While it is true that you can run projects without this file, it sets up useful Cordova functionality and populates the window.cordova object with system details. Without it, Phaser will not be able to detect it is running under Apache Cordova.

 

 

 

but if i don't need anything of the cordova api stuff..  no camera, vibration and so on..  what can cordova.js do for me.. is phaser in someway optimized for cordova - will it run faster?

Share this post


Link to post
Share on other sites

but if i don't need anything of the cordova api stuff..  no camera, vibration and so on..  what can cordova.js do for me.. is phaser in someway optimized for cordova - will it run faster?

Searching Phaser's code in Github would suggest that Phaser does exactly one thing differently if it finds window.cordova is anything other than undefined, if the document.readyState isn't already set to "complete" or "interactive then the game constructor waits for 'deviceready' to fire before calling the boot callback rather than waiting for 'DOMContentLoaded'.

 

And I suspect, if you don't include cordova.js before phaser/your code window.cordova may be undefined... So it looks like Phaser just does the minimum to play nice with Cordova.

 

As for whether you need cordova.js... what does the documentation say? Does it say it's required, or that's it's optional?

Share this post


Link to post
Share on other sites

What's this 'deviceready' event? [This is now part of Phaser 2.1]

 

Cordova was created to run on different devices with different requirements. One way to generalize all the required runtime tasks was to send a signal when everythingCordova-related was ready. That's what the 'deviceready' event is. Once it is sent, everything that was supposed to be loaded or created by Cordova (such as plugins) should now be ready.

 

For Phaser projects that will use any Cordova plugins, it is highly recommended to wait for this event to trigger before enabling any code.

 

For example, creating a function to load your game would look something like the following --

document.addEventListener('deviceready', loadGameFunction);

-- where loadGameFunction is a function to load your game or enable certain functionality for Phaser to use.

 

 

Is there an example of this?

 

I am have this in my index.html:

window.onload = function() {        var game = new Phaser.Game(gameWidth, gameHeight, Phaser.AUTO, 'gameContainer');					game.state.add('Boot', BasicGame.Boot);...

but I guess is not right. On older versions of phaser (2.0.2) it works, but I tried 2.1 and the screen is blank.

What changes do I have to do in order to wait for the deviceReady?

Share this post


Link to post
Share on other sites

Judging by your code you are basing this on the templates, my suspicion is that this is nothing to do with Phonegap but that you still have the hasResized event listener in boot.js. . This is gone in phaser 2.1 and results in a blank screen if you don't remove it or update to the new api. Just comment it out to check it is this causing the problem.

Share this post


Link to post
Share on other sites

but if i don't need anything of the cordova api stuff..  no camera, vibration and so on..  what can cordova.js do for me.. is phaser in someway optimized for cordova - will it run faster?

 

No, it won't be any faster. However, the file is needed to setup the window.cordova object and its associated events. As @chg wrote, Phaser looks for the window.cordova object to be defined (which comes from including "cordova.js" before Phaser) and, if so, then waits for the 'deviceready' event.

 

You also might not be using any of the Camera or Vibration stuff, but any audio playing -- for which the Media plugin is needed -- comes after the 'deviceready' event is called too. You cannot access plugins until after the 'deviceready' event, and Phaser doesn't know to wait for it unless window.cordova is defined first.

 

It's better to be safe and just include it.

 

What changes do I have to do in order to wait for the deviceReady?

 

(@spencerTL already answered this, but I thought I would group this with the previous response.)

 

Other than making sure "cordova.js" is loaded before Phaser, you shouldn't have to do anything. As I wrote above, Phaser will try to detect window.cordova and then act from there.

 

However, as I note in the top post as well, Phaser doesn't automatically detect and act on the 'pause' and 'resume' events (yet). So, you will need to handle those somehow.

Share this post


Link to post
Share on other sites

did anybody get ADS to work with cordova?   i've tried a whole bunch of different plugins, none of them will compile except  https://github.com/floatinghotpot/cordova-plugin-admob  (it is the same one that is used in the intel xdk admob demo app..)   they all throw an error and say i should use a newer version of the complier or another error where java.zip complains that the zip file was not found  

 

(i use the newest intel xdk)  

Share this post


Link to post
Share on other sites

Hi there,

I have an issue when using the RendertTexture on Phonegap. Whe nrunnning on Android as a native app, the image doesn't appear. But it works when runiing as HTML5 on browser.
 

Problem is in the function: createUnlockedGraphics

var Levelicon = function(game, x, y) {	Phaser.Image.call(this, game, x, y, "buttons", "button.png");Levelicon.prototype.constructor = Levelicon;Levelicon.prototype.createGraphics = function() {	this.locked ? this.createLockedGraphics() : this.createUnlockedGraphics()};Levelicon.prototype.createLockedGraphics = function() {	this.loadTexture("buttons", "buttonlock.png")};Levelicon.prototype.createUnlockedGraphics = function() {	var a = {		font : "48px font",		fill : "#218DB7",		align : "center"	};	var b = this.game.add.text(0, 0, this._levelNumber.toString(), a);	b.anchor.set(.5, .5);	var c = this.game.add.renderTexture(this.width, this.height);	c.renderXY(this, .5 * this.width, .5 * this.height);	c.renderXY(b, Math.floor(.5 * this.width), Math.floor(.5 * this.height) - 1);	this.setTexture(c);	b.destroy();};module.exports = Levelicon;

Share this post


Link to post
Share on other sites

Scaled Viewport Size

 

For devices not running iOS, the following line can be added to the <HEAD> of the HTML file to create a viewport and scale up to the size of the device's screen.

<meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width, height=device-height, target-densitydpi=device-dpi" />

For iOS devices, drop the "width=device-width, height=device-height".

 

 

so what if I want it to work on both IOS and Android what is the correct viewport?

 

and does cordova have the same issue as cocoonjs scaling? 

Share this post


Link to post
Share on other sites

What's this 'deviceready' event? [This is now part of Phaser 2.1]

 

Cordova was created to run on different devices with different requirements. One way to generalize all the required runtime tasks was to send a signal when everything Cordova-related was ready. That's what the 'deviceready' event is. Once it is sent, everything that was supposed to be loaded or created by Cordova (such as plugins) should now be ready.

 

For Phaser projects that will use any Cordova plugins, it is highly recommended to wait for this event to trigger before enabling any code.

 

For example, creating a function to load your game would look something like the following --

document.addEventListener('deviceready', loadGameFunction);

-- where loadGameFunction is a function to load your game or enable certain functionality for Phaser to use.

 

 

when should this be loaded and how many times? is it best to do it in preload state? like this?

function initApp() {

this.state.start('MainMenu');
}
 
document.addEventListener('deviceready', initApp, false);

 

and lets say I am using admob plugin in a different game state will I need to call this 'deviceready' again? 

Share this post


Link to post
Share on other sites

Hi

I've done simple game with size 240x160 and compiled it with Cordova.

It is scaled to fit screen (SHOW_ALL) and is a little bit blurred. But when I touch the screen the blurr goes off... (it gets sharp).

Does anyone has the same problem as I? Any suggestions?

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...

  • Recently Browsing   0 members

    No registered users viewing this page.