Jump to content

Scaling for HiDPI displays


Recommended Posts

This seems to be a frequent topic in here and after reading :







I'm not really any wiser. As Phaser has developed code snippets become obsolete and links die. :(


My current thinking is that I want my game to run at 1x resolution - let's say at 640 x 360. Let's also say I have game assets at 1x, 2x and 3x generated and will load the correct set in based on devicePixelRatio during Preload. I'd like to scale my entire game up based on the dpr and then with CSS scale it to fit. But logically my game code still thinks its running on a 1x device.


Could someone show me how you would scale the game like this? And where to do this, (in Game's constructor?)

Link to comment
Share on other sites

Your game shouldn't care if it's running at 1x, 2x or 10x. Your game logic should be independent from the number of pixels (eg: a ship should move at the same speed if game runs or 640x360 or if game runs at 1280x720).


What I usually do to fix all this issues is to express everything in percents rather the pixel constants. Eg: if you used to set your sprite with to 320px, you should instead set it to game.width / 2 (still 320px, but if game is larger the sprite is larger). This way all you have to do for retina displays is set game.width = window.innerWidth * window.devicePixelRatio and all your sprites and game logic will act the same, regardless the resolution.


You don't even have to use game.width or game.height as the norm, but one thing that you should keep in mind: if resolution is higher than game size is bigger. If game size is bigger your sprites have to be bigger to keep everything the same.


I don't know if is the best way, but this is how I do it and I find it very easy to just write sprite sizes related to game size.


As for the code, this is how I do it, set the game width and height to the one of the device.


Then, in the Boot state create function I use the Phaser ScaleManager:

this.game.scale.scaleMode = Phaser.ScaleManager.SHOW_ALL;this.game.scale.pageAlignHorizontally = true;this.game.scale.pageAlignVertically = true;
Link to comment
Share on other sites

  • 3 weeks later...

Sure - that's kinda what I was getting at. Though I'd still prefer to use a base, logical game size instead of percents.... After re-reading http://www.html5gamedevs.com/topic/5949-solution-scaling-for-multiple-devicesresolution-and-screens/ I noticed the solution to the issue I'm seeing.


As an example, this is what I am doing:

var dpr = window.devicePixelRatio;var canvasWidth = window.innerWidth * dpr,    canvasHeight= window.innerHeight * dpr;var game = new Phaser.Game(canvasWidth, canvasHeight, Phaser.AUTO, 'phaser-example', { preload: preload, create: create });function preload() {    var assetFolder = dpr + 'x/';    game.load.image('box', assetFolder + 'box.png');    game.scale.scaleMode = Phaser.ScaleManager.SHOW_ALL;    game.scale.setMinMax(window.innerWidth, window.innerHeight, window.innerWidth, window.innerHeight);}function create() {    game.add.sprite(getScaledPosition(100), getScaledPosition(100), 'box');}function getScaledPosition(a) {  return a * dpr;}

Here's that in a browser - left shows a devicePixelRatio of 1 - right devicePixelRatio is 2




The crucial bit is getScaledPosition()without it, the box is positioned at 50, 50 on a device with pixel ratio 2. I tried creating a Phaser.Group and scaling that, but that scaled the image, not just the position.


I've yet to implement this in my full game yet, I've only been toying with a tech demo. It does mean that anytime I move a game entity I have to wrap the coordinates with this function, which is a bit inelegant...


Perhaps there's something that can take care of this that I've not seen, anyone know? Something that scales, but only scales position, not widths or heights?

Link to comment
Share on other sites


  • Recently Browsing   0 members

    • No registered users viewing this page.
  • Create New...