I’m creating a 2D top-down pixel-perfect game, and I decided to implement the player’s movement without using the TopDown Movement behavior, as the movement generated by that behavior produces X and Y positions with many decimal places, and I need integer numbers. So far, I have managed to resolve this, but when trying to normalize the diagonals so that the player has the same speed in all directions, two situations arise:
Without using the int() function to convert the X and Y positions to integers, normalization works perfectly, but there is a jitter when moving diagonally, as I am using a low resolution and the movement doesn’t stay with just integers (I need it to be this way because a second character should follow the player, and he behaves strangely if the player’s position is not exact).
On the other hand, using int() to convert the X and Y positions to integers makes the movement perfect, but the normalization of the diagonals doesn’t work due to the correction.
What you describe is like you would want to have 300x200 resolution
And wish to not see pixel and have everything in 4k
You reduced per pixel movement to your resolution so it will be “pixelly”
You can try upscale all your images (not in game but in image editor)
And have much higher resolution than it looks
Like you would make your 10x10 player image just scale up 10 times for example
And now it is 100x100 and each visible pixel is built from 10 pixels
EXAMPLE
You see 2 images here on the left is one in original size 10x10 pixels
And big one on the right is up scaled 10x so it is built from 100x100 pixels
HOWEVER
In that big one on the right
One visible pixels so one square you see is built from 100 pixels
And now you can make higher resolution in your game
Zoom out to make this look smaller
And you would have smooth movement same as pixels would not be so visible
And as for diagonal speed i do not remember exactly but diagonal movement speed should be either 1.6 or 1.7 of up down left right movement speed
This is what I do for my pixel perfect games, it’s kinda sad that you have to do this, but it makes sense.
Just don’t go TOO big.
Anything around half the size of the default screen resolution is a bit overkill, unless it’s supposed to be a really big thing, like a background or something.
You suggest increasing the size of the images to make the movement smoother, right? But I would like to work with pixel perfect, to avoid having images with different-sized pixels or even pixels overlapping each other. I really don’t mind it being pixelated, that was my idea from the start, I just want to normalize the diagonals. Without causing X and Y positions with broken numbers, the idea is that they are always in perfect pixels, there is no reason to display decimal numbers when we capture the X and Y positions of the player, store them in variables, and put them in a text to display.
There are a lot of things to consider here. Generally there are no “normalized” diagonals with small resolutions being pixel perfect. At least not in the major definition of normalized.
Short answer with a dirty solution: remove all of your “int” expressions from your logic, and ensure you turn on “round pixels” in your game projec
Long answer:
Pixel perfect means just that, only move where pixels are (meaning no subpixels/partial pixels). This means that if you’re going diagonal you’re always going to see stair-stepping. Rather than using int() you could get somewhat smoother stair stepping (rather than back and forth) by using either ceil() or floor() to always round up or down (rather than int() which cuts off the decimals which means the movement will have sudden movement that doesn’t feel as smooth as just rounding. But even just using round() will be smoother than int)
What I would instead recommend is a larger implementation of the idea ZeroX mentioned above. Is increase your game resolution (game resolution, not ASSET resolution) by an integer value, 4x, 5x, 6x, etc. As an example, if your game assets are designed around 320x180, you would set your game resolution 3x larger, to get 960 x 540 (or 6x larger, for 1920x1080).
Then at the start of each scene, you’d set your layer zooms to the same (3x or 6x). This will make them appear to the player as if they were still the same size as if they were running at 320x180, but the actual computer/engine/renderer knows there are more pixels there.
This allows you to have movement on more pixels, appearing smoother for movement.
When i read your messages
All i understand
I want to have no decimals because i don’t want decimals
I really do not care why you don’t want them
All i care is what you want to achieve
And my 1st rule of game making is DO NOT care how it is done
All you should care is what player will see
If movement you get will be accurate
You should not care does it have decimals or not
So you wanna fight decimals for not having them
Or do you want your game to be pixel perfect movement?
Think before you answer because right now i am more willing to believe you don’t want something just because you do not want it
And you do not really care for actual after effect
For me it could be 54.41230352165440201254
As long as it would LOOK like it is pixel perfect
Now what i suggest is do not make everything as small as possible just for it to be PIXELS all the way
I would make it big where everything is up scaled proportionally
So if something is higher 1 pixel it also need to be wider 1 pixel
Imagine game boy game on your monitor
Your monitor is WAY greater in amount of pixels
LOOK
If you look closely you can count that X in coins count is built from 9 pixels
Do you believe it is 9 pixels on your monitor?
Or is it upscalled and one visible pixel is built from many pixels?
Actually, the issue with integer numbers is because of how the game looks on another system. The idea is to have an NPC following the player with the pathfinding behavior, but due to the low screen resolution, when this NPC tries to move to a broken number, it seems to not know which pixel to go to, making them not 100% aligned. Increasing the game’s resolution should help, I will try replacing int() with these other options (I need to test this, I’m making the game gradually as I have little time available). Thank you very much for the help, everyone.