I think that indeed resolution independance would be a nice feature.
We need to distinguish world coordinates from screen coordinates, since it allows not only for resolution independance, but it allows also to have 'understandable' figures within your code.
In fact we have 3 coordinates : world coordinates, screen coordinates, and also world view coordinates === world coordinates - current view coordinates (in case you move the screen).
For instance a game where you fight in the streets will have world x coordinates ranging from 0 to 2000 ( you make your way through the 2kms of the city), a world view width of 20 ( you see 20 meters away), and screen coordinates ranging from 0 to 959 pixels on an iphone 4.
Two more examples :
- In a fighting game happening in a room, you would choose meter as unit, so you can easily understand that 2 is 'far', and 0.2 is 'near'.
The world width would be of like 5, and height of 3.
- In a strategy game like starcraft, choose also meter as unit, <10 is near and >1000 is far. The range of each weapon (expl : 200m) is easy to understand.
The world width would be 500 for instance.
As Joncon stated, the fact that the scale is no more an integer scale will cause the images to have lower quality. However 1) i didn't found this loss important and 2) the fact that you will always take all available room is more important than 1).
Because -that's when things gets complicated- you have anyway to handle 2 resolutions of image to handle hi-dpi devices.
OR... have all your graphics as vector graphics and have them drawn on the fly when you know the final resolution. For this you can use svg, or the solution i used : load .js files that describes a draw(ctx,x,y) function, that i called a drawCode.
// draw this object. uses world view coordinates as input
function draw(ctx,x,y) {
ctx.beginPath();
ctx.moveTo(... );
ctx.lineTo(... );
ctx.strokeStyle='#F00';
ctx.stroke();
}
I did it in a game i made (yet to be finished...) and it worked fine.
To implement it, i had to change ig.main, the scaling of the images, and i added a new kind of object that is considered as a resource, the drawCode == a text file that contains a draw(ctx,x,y) function.
So basically what i do :
- choose a fixed aspect ratio in the constants of the game.
- choose a view width (expl : 5 (meters) for a fighting game).
view height is computed out of width + aspect ratio.
- get width/height of current screen, and try to best fit the aspect ratio (portait / landscape mode) with this screen.
- compute the scale (most probably non-integer)
- all images will be scaled with this scale, so the drawImage will be unscaled.
- For non-Safari browsers, all vector graphics will be 'printed' in this scale into some canvases, so the drawImage will be unscaled.
- For Safari/iOS you will have much much better (>5X) performances with canvas draws (ctx.lineTo(), ... ) rather than with putImage, so i just keep on calling my drawing code using ctx.scale.
By doing this, almost full screens size is used whatever the resolution, and yet the game seems pretty much the same on the several devices i tested it on.
The signature of my ig.main becomes :
ig.main( gameClass, worldWidth, aspectRatio, [loaderClass] );
(i create the canvas in code, so no need to put it in html file + recall its id in ig.main)
( 1.5 aspect ratio is a good value if you target recent mobile devices. )