• Advertisement

Pitfalls of pixels as unit in game

Recommended Posts

So I've been trying to develop my own little c++, 2d fighting game from scratch and I'm hung up on what exactly I'm suppose to use as 'units' for my game. Currently, as suggested here on another game dev site, my game screen is thought of as a 160x90 grid. So if my game is being run at 1080p screen resolution, that would equal exactly 12 pixels per 1 grid unit (which I call a world unit). For example, I will have code in my game where I will tell my sprite to move 10.0 units/sec in the positive x direction. This means at 1080p my sprite will move 120 pixels/sec when run (12 pixels/unit * 10 units). 

Recently though, I've started trying to add some collision detection to my game and I've run into a bit of an issue with when to convert my world units into pixels and getting my collisions to work properly. While I'm sure I can fix this after some time, this got me thinking what exactly are the problems with just assuming a certain screen resolution and working strictly with pixels in my game? So instead of saying 'move my sprite 10 game units/sec' just say 'move my sprite 100pixels/sec', avoiding and unit conversion techniques. Then, if I want to, I can come up with some way just to upscale to higher res images or whatever for denser screen resolutions. The reason I ask is on a lot of forums people seem to be against using pixels as units when it comes to collision and physics, even for 2d games.

Share this post


Link to post
Share on other sites
Advertisement

Do never ever convert your pixels to units or vice versa for any math computations! Thats a rule of thumb.

Just use your world units directly, which should be float or double. Integer is not great when you want to smooth movement.

The conversion for world to screen units is only done in rendering or for screen to world conversions (mouse picking for example). You can precalculate a factor which you can multiply your world coordinates to convert to screen coordinates and vice versa.

Building up your world from tiles/grid is totally fine and i do this too like this:

static constexpr f32 TILE_SIZE = 0.5f;
static constexpr u32 TILE_COUNT_FOR_WIDTH = 40;
static constexpr u32 TILE_COUNT_FOR_HEIGHT = 22;
static constexpr f32 GAME_ASPECT = TILE_COUNT_FOR_WIDTH / (f32)TILE_COUNT_FOR_HEIGHT;
static constexpr f32 GAME_WIDTH = TILE_COUNT_FOR_WIDTH * TILE_SIZE;
static constexpr f32 GAME_HEIGHT = GAME_WIDTH / GAME_ASPECT;
static constexpr f32 HALF_GAME_WIDTH = GAME_WIDTH * 0.5f;
static constexpr f32 HALF_GAME_HEIGHT = GAME_HEIGHT * 0.5f;

Also my worlds are always built in a right handed coordinate system - which is the same as opengl. So negative Y is going down and positive Y is going up and half the screen dimension is added to X and Y so the world coordinate 0, 0 is always the center of the screen - without taking any translation into account of course.

Keep in mind, that you need to take the aspect ratio into account as well - so you should letterbox your game view, so it will fit on any display. I do this for every frame once and store the result:

// Calculate a letterboxed viewport offset and size
// @NOTE: Scale is used later for doing unprojection
viewSize = Vec2f(halfGameWidth, halfGameHeight) * 2.0f;
viewScale = (f32)windowSize.w / (halfGameWidth * 2.0f);
Vec2i viewportSize = Vec2i(windowSize.w, (u32)(windowSize.w / aspectRatio));
if (viewportSize.h > windowSize.h) {
  viewportSize.h = windowSize.h;
  viewportSize.w = (u32)(viewportSize.h * aspectRatio);
  viewScale = (f32)viewportSize.w / (halfGameWidth * 2.0f);
}
Vec2i viewportOffset = Vec2i((windowSize.w - viewportSize.w) / 2, (windowSize.h - viewportSize.h) / 2);
viewport.size = viewportSize;
viewport.offset = viewportOffset;

// Update view projection
Mat4f proj = Mat4f::CreateOrthoRH(-halfGameWidth, halfGameWidth, -halfGameHeight, halfGameHeight, 0.0f, 1.0f);
Mat4f model = Mat4f::Identity;
viewProjection = proj * model;

 

Edited by Finalspace

Share this post


Link to post
Share on other sites

It depends on the engine.

The first pitfall to using pixels directly is that, of course, you can't easily change the resolution. However, this might not necessarily be true if you can just set the old pixels as "world units" with little hassle. So that's going to depend on the engine.

The second possible pitfall is that pixels are by definition integers; you can't have a real half-pixel, so you can't be at pixel position 4.2. This is of course imprecise. But it's trivial to just keep pixel positions as floating-point and round or truncate them at display time. It's just a more simplistic "world units" conversion at that point, really. The engine itself can even transparently handle it.

Personally, I prefer to define the game at a particular resolution and just use pixels for distances and movement and such, for two reasons:

  1. It's more simple to do it that way. It means there's no need to worry about whether I'm talking about the display or the game world; it's all the same.
  2. Changing the resolution would involve changing each individual image anyway, so making it easier to code that change would be of little consequence as I see it.

Of course, this is for 2-D games that use raster graphics. If you use vector graphics or 3-D graphics, I definitely see merit in not using pixels as a measurement; after all, you're not working with pixels in that case.

Share this post


Link to post
Share on other sites

Also consider fixed point (you can for example divide a pixel into 256 units).

If you are using pixel perfect sprites there is more of a reason to use some kind of pixel unit, whereas with pure 3d there isn't such a concept as a pixel, so the pixel may not make sense, but you still may choose to use integers.

There are benefits to both floats and ints. Although floats are often seen as the 'default choice' these days, integers are good for consistent behaviour, compression, packing, some people use them for units on large scale maps.

Share this post


Link to post
Share on other sites

@JulieMaru-chan 

3 hours ago, JulieMaru-chan said:

Personally, I prefer to define the game at a particular resolution and just use pixels for distances and movement and such

What about for things like collision detection and physics? Do pixels still work out okay for these kinds of calculations?

@lawnjelly

1 hour ago, lawnjelly said:

If you are using pixel perfect sprites there is more of a reason to use some kind of pixel unit

What about for a 2d game using vector graphics?

Share this post


Link to post
Share on other sites

Physics and collision response can work okay.  You'll likely end up using your own internal representations, but it won't hurt anything.

Also note that many games people think of as pixel based have higher precision internally.  For example, the original Super Mario Bros had 8 bits of sub-pixel data for position and speed, which enabled variations in running versus walking. Visually players saw the player moving a pixel or not, but internally there was more data.

That is, I think, what was being referred to earlier in the discussion as fixed-point data. 

What you see on the screen does not need to precisely match what the simulator is doing internally.  Games tend to keep far more information than is shown to the player, and tend to keep information at a higher precision than the player thinks about.

Share this post


Link to post
Share on other sites
8 hours ago, frob said:

That is, I think, what was being referred to earlier in the discussion as fixed-point data. 

Yes, on our 8/16/32/64 bit computers it makes far more sense to divide a pixel into 256 then say, 100, because you can use bitshifts, bitmasks etc. The fixed point can refer to the number of bits given to the fraction and the number to the whole number, instead of referring to the position of a decimal point.

http://x86asm.net/articles/fixed-point-arithmetic-and-tricks/

Share this post


Link to post
Share on other sites
8 hours ago, frob said:

What you see on the screen does not need to precisely match what the simulator is doing internally.  Games tend to keep far more information than is shown to the player, and tend to keep information at a higher precision than the player thinks about.

While rounding high precision positions to whole pixels for rendering purposes only should be the default strategy to deal with pixels (both for fixed point and for floating point) in some cases deliberately and selectively quantizing positions, times, velocities etc. in the game engine might make sense.

For example, suppose you need to execute a long jump to a ledge in a platformer or to run into a narrow opening in a racing or flying game: the player cannot tell whether his sprite is actually aligned with the pixel grid or slightly off, and therefore basing success or failure (through high precision collision detection) on unavailable information would be unfair.

Share this post


Link to post
Share on other sites
5 hours ago, LorenzoGatti said:

For example, suppose you need to execute a long jump to a ledge in a platformer or to run into a narrow opening in a racing or flying game: the player cannot tell whether his sprite is actually aligned with the pixel grid or slightly off, and therefore basing success or failure (through high precision collision detection) on unavailable information would be unfair.

That's not going to factor in to this realistically. No human can possibly be precise enough to be pixel-perfect on a consistent basis anyway. It might even literally be impossible if the speed is too high. So I wouldn't worry about an edge case such as this.

Share this post


Link to post
Share on other sites

The edge case of caring for pixel-perfect positioning is fairly common in old, low resolution games where 1 pixel is actually a large distance and 1 frame is a long time. When I refer to racing or flying games I mean things like aiming for ramps in Micro Machines or bullet gaps in Space Invaders, not forgiving 3D games.

Share this post


Link to post
Share on other sites

Don't use pixels, you get tied down to resolution and hack physics.

I would recommend using real world units, feet, meters, etc.

That way you can relate to real world equations, (10 m/s means much more than 100 pixels/s), describing the screen size in units would also detach you from the actual pixel resolution, and allow you to use subpixel accurate rendering without complicating the code with fixed point math which has absolutely no advantage over floats in any modern CPU.

And, with float data, you could take advantage of SIMD intrensics, which you can't with fixed point math. 

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now


  • Advertisement
  • Advertisement
  • Popular Tags

  • Advertisement
  • Popular Now

  • Similar Content

    • By Terry Jin
      Hi everyone! 

      I am from an indie studio that has received funding for our concept and is ready to create the next generation 2D Pokemon-inspired MMORPG called Phantasy World. This ad is for a volunteer position but hopefully will transition into something more. Our vision is to create a game that draws inspiration from the series but is dramatically different in both aesthetics and gameplay as the work would be our own.
       
      We are hoping that you can help us make this a reality and are looking for game developers familiar with the unreal engine and would be happy to work on a 2D top down game. Sprite artists are also welcome as we are in desperate need of talented artists! Join our discord and let's have a chat! https://discord.gg/hfDxwDX

      Here's some of our in game sprites for playable characters while moving around the game world! Hope to see you soon!
       


    • By Sean Meredith
      Hi all, I am starting to develop a tactics game and ran into a problem I had not thought of. I began by drawing a screen with a hex grid, and this is no big deal. I got that working fine. But, I realized it didn't look quite right. This is because in most strategy games, you're not looking straight down. There is a bit of a tilt. Attached is an example of what I mean. The hexagons on bottom are larger than the hexagons on top, and I'm unsure of how to go about adding this effect. Especially when you consider that some maps may be of different sizes. 
      I'm not sure if this is the right place to post something like this, but it seems as though some sort of linear transformation would be applied? No? I don't even know where to begin in a problem like this.
      Thanks.

    • By nick1
      Hello,

      I have limited programming experience in C++, but have always had a passion for games.  Where do I start?  I have a rough idea of the type of game I want to develop and am ready to commit the time necessary to learn new languages.  Are mobile games too difficult to begin with? Should I begin learning the basics of keyboard controls before attempting touch screens?  I would appreciate any input or advice!
      Thanks!
      Nick1
    • By MochiArtist
       draw stuff like this 
       
      Okay, so I am an artist and have been for 6 years. However, I struggle to write code. I'd like to make a small demo of a game I'd like to make one day. If your willing to help it'd be much appreciated. so here is the concept: it's a survival game that involves cute characters that are mochi. 
      Mochi Universe
      Draft version 0.01 (24 December, 2015)
       
      Concept
      The game concept revolves around city building and exploration. The target audience will be age 9+ (most likely because of the possibility of fighting). The cute graphics should appeal to all audiences male and female. The gameplay includes elements of real-time strategy games (such as warcraft ) with faster paced action (such as clash of clans). In order to build your city, you will need to explore the surrounding environment and collect items (such as in minecraft). The gameplay will less intense than warcraft and clash of clans, so the focus will be more on casual gamers than hardcore gamers.
  • Advertisement