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:
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.
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.
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.
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";
}
{
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);
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);
}
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: