• Hey Guest! Ever feel like entering a Game Jam, but the time limit is always too much pressure? We get it... You lead a hectic life and dedicating 3 whole days to make a game just doesn't work for you! So, why not enter the GMC SLOW JAM? Take your time! Kick back and make your game over 4 months! Interested? Then just click here!

HTML5 Trouble with rendering scale on Android phones (HTML5)

R

radnom

Guest
Hi, I'm making an HTML5 game, specifically a 'Facebook Instant Game' and I have been struggling with getting the game to render correctly on device.

On my PC Windows browser the game appears crisp and I am resizing the game correctly when the window is resized.

However, on my Android phone's browser, the game always appears to be rendering at a low resolution. Looking into this online, it appears the culprit is 'devicePixelRatio' which on this device is set to 3.5. As far as I can tell, this means we are basically rendering at 1/3.5 scale, and the solution floating around online is to 'simply' multiply the canvas size by devicePixelRatio. I am stuck trying to figure out where and what I am meant to do to achieve this though.

I've tried combinations of
window_set_size and surface_resize with different numbers (i.e. my target resolution, or my target resolution multiplied by devicePixelRatio) but I can't figure out what I am meant to use.

To be clear, I'd like:
* The game to render at the full resolution and scale to fit whatever window it is in
* Support for Windows and mobile device browsers
* Support for resizing the window at runtime
* Keep the aspect ratio intact and fit the game within the browser window


Any help would be much appreciated.



EDIT:
I've solved my problem!! Here's the solution, for those who get stuck on this.


I added a small Javascript extension, scaleCanvas.js. Inside it I created this function:

function ScaleCanvas_SetWindowSize(image_wid, image_hei, window_wid, window_hei)
{
var canvas = document.getElementById('canvas');
canvas.width = window_wid;
canvas.height = window_hei;
canvas.style.width = image_wid + "px";
canvas.style.height = image_hei + "px";
}​

In GML code, in an update loop, I find out the scale we should use to fit the game into the browser. In this case room_width and room_height are my target width and height, this could be changed if you are using views.

var _x_scale = 1;
var _y_scale = 1;
if (room_width != browser_width)
{
_x_scale = browser_width / room_width;
}
if (room_height != browser_height)
{
_y_scale = browser_height / room_height;
}
var _window_scale = min(_x_scale, _y_scale);​

Now I check if the display width has changed since last frame. This is just to avoid doing processing if the window size hasn't changed.

var _last_display_width = display_width;
display_width = floor(room_width * _window_scale);
display_height = floor(room_height * _window_scale);
if (_last_display_width != display_width)
{
display_set_gui_size(room_width, room_height);
ScaleCanvas_SetWindowSize(display_width, display_height, room_width, room_height);
}​


And that's it!

Some notes:

devicePixelRatio was a huge red herring. It's important, but we don't need to touch it. I was trying to scale things by it, but as you can see I didn't need it in the end.

Initially I was also using surface_resize and window_set_size but they were not helping. In the end I removed them entirely and made much more progress.

It's easier to test the behaviour by using a PC browser's zoom functionality (which changes devicePixelRatio) rather than test on device each time. If you zoom in and the image gets abnormally pixelated then it's not working. If you zoom in and then you have to scroll, it's not working. This solution should keep the whole canvas within the window, at the correct pixel ratio, and rendered at full resolution then downscaled.

Perhaps a better solution than downscaling would be to set the target resolution values to the browser_width * devicePixelRatio (where I'm using 'room_width' ) but I haven't tried this yet.
 
Last edited by a moderator:
Top