When it comes to mobile HTML5 games there are a few new problems to solve when compared to desktop. For example managing the resize of the game area is very important, whether you’re rendering the game using DOM or Canvas. Noboby wants to play the game that takes only half of the screen, because everything would be just too small. On the other hand having the game area twice as the screen size and forcing user to scroll it is also a very bad idea. Resizing the game area to fit the device screen is the best solution in this situation. Let’s see what options we have right now.
var canvas = document.getElementById('canvas');
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
We just grab the Canvas element and change its width and height to the actual values.
2. CSS scaling
We can also set the Canvas to take the whole available space using only CSS.
var scaleX = canvas.width / window.innerWidth;
var scaleY = canvas.height / window.innerHeight;
var scaleToFit = Math.min(scaleX, scaleY);
stage.style.transformOrigin = "0 0";
stage.style.transform = "scale("+scaleToFit+")";
The example above takes the width and height of the Canvas element, calculates the scale and then the CSS Transforms are applied. This technique is used in Enclave Games‘ Captain Rogers – it works great for simple games on small devices.
It’s not perfect though. The scaling used above can make the game look blurred on devices with bigger screens. It won’t take the content of the game into consideration too – it just scales the Canvas with everything inside. We used
scaleToFit, but there are also other options – beside fitting we can make it stretch or cover.
It just stretches the whole game (see the scaling techniques 1. and 2.) so if your device have different aspect ratio than your game it will look strange and unnatural.
This way you will fill the whole screen, but the extra content will be cut off – some of the elements of your game that will be placed on the borders of the screen won’t be visible. Instead of
var scaleToFit = Math.min(scaleX, scaleY); you can use
var scaleToCover = Math.max(scaleX, scaleY); to see the expected result.
This technique looks like it’s the best one, though still not perfect. The game ratio will be the same and nothing will be cut off – the only problem would be with inactive stripes on both sides of the Canvas element.
Check out this handy article at Mozilla Hacks to see this and other optimization techniques useful for your HTML5 mobile game.
There is another way to manage screen size and be content-aware at the same time. It’s a higher level of scaling which include showing different game areas for different aspect ratios and having the Canvas fill the whole screen constantly. This looks like the most universal approach, but it’s the hardest one to achieve and it’s not perfect for every type of game as seeing more than others can give the player unfair advantage. You can see this in action in Jesse Freeman‘s Super Paper Monster Smasher.
The last thing to remember is that the scaling have to be executed both at the beginning (when you launch your game) and on the resize event on the browser to scale the scene dynamically. You just have to add an event listener to your code:
window.addEventListener('resize', resizeCanvas, false);
Then on every resize event the
resizeCanvas() function will be executed. You just have to place your scaling code there and it will work as expected.
What are your techniques to manage screen size? Do you have different ways to do it? Do you even do it by yourself or leave it to the framework? Share your experience!