Touch events for Flappy Sonic
Some time ago during the Flappy Bird madness I made a tutorial on how to make the game using EaselJS so you can play it on your browser.
There were some details left that I will be fixing as long as I have free time. The first and most important for me is: Mobile compatibility.
If you load the page in your mobile device the game controls will feel weird, thats because it's based on click events. The first step to do is add tap events for the actions.
For doing so we have just to change this:
canvas.onclick = handleClick;
For this:
canvas.addEventListener('mousedown',handleClick,false); canvas.addEventListener('touchstart',handleClick,false);
So now we will be listening for mouse and touch aswell. Also for removing the event listeners we will have to change this:
canvas.onclick = null;
For this:
canvas.removeEventListener('mousedown',handleClick); canvas.removeEventListener('touchstart',handleClick);
This was very easy to do, however if we load the game on a touch device, it's still feeling weird because our character will jump twice per touch. This is because of the ghost clicks. This is very well documented in this blog post and also documented in this Google article.
Basically, it is because of the way that browser deal with those events, and how do they link touch and click events.
Before the rise of touch devices there were already thousands of webpages with clickable stuff, if the touch events were not linked to the click events, all those clickable things will not work using a touch device, so the solution was to link touch and click events. Once the user touches the screen (touchstart and touchend events), there is a short period of time (around 300ms) and then a click event is rised.
In our case, as we added event listeners for both the tapping and the clicking, they are going to be raised one after another, this is not desirable at all so we want to remove this default behaviour.
For cancelling this behaviour we need to use preventDefault and stopPropagation so the handleClick function will now start like this:
function handleClick(event) {
event.preventDefault();
event.stopPropagation();
...
This is going to be ok for some mobile browsers, I've tested this on an iPad and the game is now fully playable. However, the ghost click is still present on my Android device. This is going to require a more advanced solution.
Now we will use Google's Fast Button implementation from the article mentioned before, there is one already implemented and well documented version in this github repository.
Once you've included the js file (in my case I included it the tpl jade template like I did with the other game classes) you can define an event listener like this:
new FastButton(canvas, function() {
handleClick();
});
As we need to create and destroy these listeners depending on the game state, we will have to store them as variables for calling to destroy when they are not needed anymore.
var handleClickFastButton = new FastButton(canvas, function() {
handleClick();
});
And then:
handleClickFastButton.destroy();
This way touching events would be working as desired, and the mobile players can make the same scores that the desktop ones using the mouse. One last detail is disable text-selecting on the canvas, because sometimes it darkens as the browser understands that you are trying to select it. This is solved with this css line.
canvas{user-select: none;-webkit-user-select: none;-moz-user-select: none;}
Finally, you can click here to play the game.