Consider this code:

```
# Set initial values
x = 0
y = 0
speed = 1
if right_key_pressed:
x += speed
if up_key_pressed:
y -= speed
if down_key_pressed:
y += speed
if left_key_pressed:
x -= speed
```

At first glance, this code seems to be a simple and efficient way to handle player movement in a 2D game. However, there is a problem with this code that causes the player’s movement to be faster when traveling diagonally.

The issue lies in the fact that when the player presses two keys at the same time (e.g. right and up), the player’s position will be updated by the sum of the two movement speeds. This means that the player will move faster diagonally than when moving in a single direction since 1+1 = 2.

To understand why this happens, first let’s understand what we’re trying to do. Think about a 2d grid. When we’re moving, we always want our distance from initial position (assume it’s 0,0) and new position to equal to our speed (in the above diagram one is the speed).

Instead of representing movement as X and Y position increments, take a look at them as angles, as follows:

The definition of a circle is as follows:

a round plane figure whose boundary (the circumference) consists of points equidistant from a fixed point (the center).

This means we can visualize our movement as moving across the boundary (circumference of a circle)! Let’s convert our arrow keys to angles, and use trignometric functions to define our movement vectors.

Arrow Key Pressed | Angle (degrees) | Sin Value | Cos Value |
---|---|---|---|

Up | 90 | 1 | 0 |

Down | 270 | -1 | 0 |

Left | 180 | 0 | -1 |

Right | 0 | 0 | 1 |

Top + Right | 45 | 1/√2 | 1/√2 |

This tells us:

**Horizontal component = speed * cos(angle)**

**Vertical component = speed * sin(angle)**

Here’s an updated version of the code that takes this into account:

```
# Set initial values
x = 0
y = 0
speed = 1
# Calculate horizontal and vertical components of movement speed
cos_angle = speed * cos(angle)
sin_angle = speed * sin(angle)
# Update player position
if right_key_pressed:
x += cos_angle
y += sin_angle
if up_key_pressed:
x -= sin_angle
y -= cos_angle
if down_key_pressed:
x += sin_angle
y += cos_angle
if left_key_pressed:
x -= cos_angle
y -= sin_angle
```

With this updated code, the player’s movement will be correctly updated based on the direction of movement, and the issue of faster diagonal movement will be resolved.

Here’s a table comparing the movement of the current code and the expected movement:

Direction | Incorrect Code | Expected Movement |
---|---|---|

Right | x += speed | x += cos(angle) |

Up | y -= speed | y -= sin(angle) |

Down | y += speed | y += sin(angle) |

Left | x -= speed | x -= cos(angle) |

Diagonal | x += speed, y += speed | x += cos(angle), y += sin(angle) |

We can also calculate using the formula for a diagonal that our initial buggy code would’ve been off by a factor of sqrt(2) or approximately 41% faster. Using angles fixes it!

I hope this was easy to understand, let me know if you have any questions in the comments!