4
\$\begingroup\$

I'm trying to create my first C++ 2D fighting game from scratch, using SDL, and so far I got things to where I am able to move a couple sprites around using some keyboard keys. Right now, I have it so 1 unit of measurement equals 1 pixel; setting my player position to 900.0f 100.0f (my pixel units are of type float) will place him 900 pixels in the x direction and 100 pixels in the y direction.

At first, I thought that using pixels units for a sprite based 2D fighting game would make sense, but after thinking about it, I realized that I might have issues with differing screen resolutions. Someone with a higher screen resolution of 2560 x 1600 would move slower than someone with a lower screen resolution of 1920 x 1080.

Now I'm sure there would be ways to correct this specific issue, but it got me wondering if there would be better basic units of measurement I should be using for a 2D game. What should I use as units for my 2D game?

\$\endgroup\$
2
  • 1
    \$\begingroup\$ If your game scale depends on the resolution, then measure everything in pixels before upscaling. \$\endgroup\$ Aug 12, 2017 at 21:03
  • \$\begingroup\$ Possible duplicate of What sprite size should I use for 2D game?. While that question is about Unity, the argument presented applies to all engines/platforms: your choice of internal unit is arbitrary since the player never sees it, and it mainly serves your own convenience as a developer in helping you achieve other goals, like pixel perfect alignment, laying out tiled maps, etc. \$\endgroup\$
    – DMGregory
    Aug 13, 2017 at 14:10

2 Answers 2

4
\$\begingroup\$

You could define your movement in terms of "design units". In other words, you figure out how much "logical" distance a sprite would cover in a certain amount of time, which is then scaled dynamically based on the window resolution.

To do this, first, visualize your game screen as a grid, perhaps 100 by 100, or 160 by 90 (to fit 16:9 resolutions), or some other value. Each asset is placed along this grid on the X/Y axis, as appropriate. First, you calculate where the thing would be in terms of its logical location, which is then upscaled to the device's resolution.

In this system, 160 by 90 would be exactly 12 pixels per unit at 1080p, exactly 8 pixels at 720p, etc. So in one resolution, the sprite would move 12 pixels, and on another only 8 pixels, but would move the same physical distance on the screen (assuming screens of the same size), or the same relative distance (e.g. expressed as a percentage).

Some languages, like Flash/ActionScript have a default resolution expressed in logical units, others allow you to design your own, and others still will require that you do all the scaling yourself. If possible, consider using some variant of SVG (Scalable Vector Graphics) instead of bitmaps (PNG, JPG, GIF, TIFF, etc) in order to minimize the visual artifacts.

You haven't specified your platform, so the precise answer about how to do this will vary, but the general idea is that you should separate the logical units (where things are placed in relation to each other) from physical units (pixels).

Note that you could still choose to use bitmap-based graphics, but the quality will suffer somewhat. Typically, games like this tend to look "blocky", but that's often done intentionally for nostalgic purposes, as if it were an 8-bit game created in the 1980's instead of a modern game. There seems to be a lot of that going on in the market today, so you might decide that's your look. Try searching on your favorite search engine for "retro game design" if you're not sure what I'm talking about.

\$\endgroup\$
1
  • 1
    \$\begingroup\$ Note that the fact that the example 160x90 unit subdivision here is a common factor of both 720p and 1080p target resolutions, so you get a whole number of pixels per unit in both cases. This can be very important if you're making a pixel-perfect 2D or retro-style game, where your unit grid gives you a precise integer size to make all your 2D art (or upscale it to from another common factor) without creating fractional scales that can distort the artwork. \$\endgroup\$
    – DMGregory
    Aug 13, 2017 at 14:08
1
\$\begingroup\$

It is worth noting that SDL runs on top of OpenGL, which uses 'normalized device coordinates', which is a coordinate system ranging from [-1, 1] in both axes and the center of origin (0,0) being at the center of the screen. Y grows upwards, and X to the right. Using this has the added benefit that a logical point will always be at the center of the screen, no matter the chosen screen resolution.

It could be worth a look ;)

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .