In a tile-based 2D RPG, a character is supposed to walk into all eight directions.
However, if we blindly tell the player to move in the direction (1, 1), he will be around 41% (√2-fold) faster. Thus, my next idea was to normalize the direction vector before moving.
Unfortunately, since the vector (1, 1) normalizes to (√2 / 2, √2 / 2) ≈ (0.71, 0.71), but the game functions on a whole-pixel basis, this will make the player reach invalid 2D locations. My next idea was that I should just make diagonal movement slower by √2 somehow.
So next, I tried another approach: When I receive an input and the player isn't already walking, I set the player's destination point. Then, I compute how much of his way to the destination the player can actually walk in one frame, given the player's velocity in "pixels per frame". I will repeat the player position update every frame, until the destination is reached.
So for example, if the player needs to move from the origin (0, 0) in the direction (1, 1) at speed 1, his sprite will be displayed at (0.71, 0.71) after one frame, and in the next frame it snaps to his destination (1, 1). This is okay, because the player ends up at a valid coordinate.
While this last approach sounds okay, it has only created more problems, because now diagonal movement takes two frames, and orthogonal movement takes only one frame. In other words, the walking speeds are still not equal.
How do you usually solve this?