Phaser game.input.onUp event firing twice!

Yesterday I was making a game for an online course I’m writing. The game has a flying cat and when you click anywhere on the canvas the cat will change position. This is the line of code I was using:

game.input.onUp.add(this.changePos, this);

The game was working fine on desktop mode, but when I changed to the mobile simulator on Google chrome it looked like the event did not fire at all because the cat didn’t move. After about 15 minutes of trying to debug, I found that instead of not firing the event was actually firing twice. What was happening was that the browser was detecting two different events.

A touch event for the device
A mouse event from the browser

If I had simply tested the game on mobile, it would have worked fine, because the mobile device would not have dispatched a mouse event. So all in all, the game would be fine, but I still needed to test it on chrome, so I needed a workaround. Here’s what I did.

When you use the line of code above, it passes a parameter to the function which is called a pointer. The documentation for Phaser defines a pointer this way.

A Pointer object is used by the Mouse, Touch and MSPoint managers and represents a single finger on the touch screen.

The pointer contains a lot of information including if the user is using a mouse or not. I could simply return from the function if the pointer.isMouse==true, but I do not want to have to maintain two sets of code, and want my code to work on both desktop and mobile.

So the solution is twofold

1. Detect if the code is being run on a mobile device.
2. Return from the function if a mouse event is detected and we are using a mobile device.

The first part I am already using in the game.

isMobile=navigator.userAgent.indexOf(“Mobile”);
isMobile=(isMobile==-1)?false:true;

Now Phaser does have built in mobile detection, but I use this code to set things up before the game is declared, so I can set the game size.

The second part I simply include a pointer parameter variable in my function and check if is a mouse, and if we are using a device, return.

Here is what the code looks like:

Main.js
var game;
window.onload = function()
{
isMobile=navigator.userAgent.indexOf("Mobile");
isMobile=(isMobile==-1)?false:true;

if (isMobile==false)
{
game=new Phaser.Game(480,640,Phaser.AUTO,"ph_game");
}
else
{
game=new Phaser.Game(window.innerWidth,window.innerHeight,Phaser.AUTO,"ph_game");
console.log("Mobile");
}

game.state.add("StateMain",StateMain);
game.state.start("StateMain");
}

StateMain.js

var StateMain = {

preload: function () {

},

create: function () {
game.input.onUp.add(this.changePos, this);
},
changePos:function(p)
{
if (p.isMouse==true && isMobile==true)
{
console.log("caught mouse!");
return;
}

console.log("clicked");
},
update: function () {

}

}

This allows us to keep testing on chrome while avoiding this pesky annoyance.

I hope this helps someone.

Thanks!

UPDATE!::

I found that sometimes this method isn’t working.

An alternative would be to check the id of the pointer and if it isn’t equal to one, ignore it.

if (pointer.id!=1)
{
return;
}

Leave a Reply