1
\$\begingroup\$

Hello game dev community. I have recently got into making games in a browser window, and me and a friend ran into a common problem. Let's say I have a game like diep.io, where users can control their tank and move across a large grid. Each player can only see a certain distance, even if they moved the window to a larger monitor, like from 1080p to a 4K monitor.

I've created a game in HTML5 canvas, but the problem is that it depends on the browser's window.innerWidth and innerHeight properties. I can tell that this is an issue, because if I drew a grid, one player on a 1080p monitor could only see x distance but a player on a 4K monitor with a larger width and height could see x * 2 distance (or how much larger it actually is), meaning that the player on a 4K monitor has an advantage, by seeing players in a larger distance.

How exactly could I tackle this problem? My friend has the same issue, and I hope this answers it.

\$\endgroup\$
  • 1
    \$\begingroup\$ You want to render to "logical", not real or physical pixels. Which tends to mean that when your screen has twice the real pixels, you render twice the real pixels. I don't know how HTML/JavaScript handles this, but some frameworks/APIs work in such logical pixels, after setting the real size of the window (this is, essentially, how 3D tends to work). \$\endgroup\$ – Clockwork-Muse Mar 3 '19 at 7:17
  • \$\begingroup\$ @Clockwork-Muse So what you're saying is that I need to use sizes on the screen relative to the screen size, like doing 0.35 * screenWidth if I wanted something to fill up 35% of the screen on all sizes? I guess that would be the only method. \$\endgroup\$ – Jacob Gunther Mar 3 '19 at 13:53
1
\$\begingroup\$

To get the obvious limiting factors out of the way: since there are currently 3 very common aspect ratios out there (4:3/5:4, 16:9, 21:9) and you can also just scale the window any way you want, it's impossible to show the exact same area to everyone. You could either go for the limiting approach, where you choose one of the aspect ratios and make sure that every other is just a cropped version or you can make sure the area they see is equal by using the

$$width = \sqrt {\frac{area} {aspect}} $$

formula. It depends on your preferences.

To display the same area across different resolutions, first pic a resolution that's comfortable to you (e.g. the width of the game on your monitor, just query innerWidth), then simply do

let factor = innerWidth / myComfortableResolution;
context.scale(factor, factor);

at the start of your program and after every resetTransform and setTransform if you use them. This will scale the viewing area to be the exact same width in units on every resolution.

If you use the formula from the first paragraph, replace myComfortableResolution with the width you get from it.

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ So you're saying that I would need to use a render scale like this: renderScale = window.innerWidth / Math.sqrt(window.innerWidth / ((window.innerWidth * window.innerHeight) / (16 * 9))); if I wanted to use a 16:9 aspect ratio? \$\endgroup\$ – Jacob Gunther Mar 30 '19 at 21:42
  • \$\begingroup\$ @JacobGunther the aspect ratio is width/height so 16/9, not 16*9 \$\endgroup\$ – Bálint Mar 31 '19 at 7:46

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.