3

How do I go in the horizontal direction the camera is facing in radians, according to which of the four WASD keys are pressed? W goes forwards, A goes left, S goes back, and D goes right

It would be annoying if in say Minecraft, pressing W made you walk North instead of whichever way you're facing

  • depends on your camera representation if it is matrix then you just use its basis vectors... see [Understanding 4x4 homogenous transform matrices](https://stackoverflow.com/a/28084380/2521214) – Spektre Nov 26 '20 at 09:14

2 Answers2

2

The idea is this.

const signed char Z = WKeyIsPressed-SKeyIsPressed, X = DKeyIsPressed-AKeyIsPressed;
if (Z || X) {
    const float Direction = ((HorizontalViewAngleRadians-(Z-1)*M_PI/2)*(Z != 0)+(HorizontalViewAngleRadians-X*M_PI/2)*(X != 0))/((Z&&X)+1)+(X == 1 && Z == -1)*(float)M_PI, Speed = 0.0625F;
    XLocation -= sinf(Direction)*Speed;
    ZLocation += cosf(Direction)*Speed;
}
1

Okay, from your answer it seems like you already have a grasp on what you need to do. But for the sake of anyone else coming here who has never done this before, I will start with the basics.

The Math

Lets say you have a player that wants to move forward. They instinctively know pressing "forward" allows them to move in the direction of the camera.

However when designing a game, it is not just as simple as incrementing a value on one axis. What if they turn around? Are at a 90 degree angle? What if they are facing north east?

To do this you must understand how sine and cosine, interact with circle and angles.

Sine takes an angle and plots out a point on a circle. It then measures the distance from that point to the X-Axis.

Cosine does the same, but instead of measuring the distance to the X-Axis it measures to the Y-Axis.

sine and cosine plotted on circle

(sin = red, cos = green)

You can see here that as the Direction approaches North, the red line will grow while the green shrinks. This is what we want. If we are facing directly north, we do not want to move east or west at all. And the farther right we turn, the more the green line extends. Causing us to move East more.

If we can determine the angle we are facing, we can determine how much on each axis we want to move the Player.

Note that sin and cos return a value between -1 and 1, so to move the player faster than that, multiply the resulting values by the player's speed.

The Code

To move forward:

moveForward(direction) {
    z += cos(direction) * playerSpeed;
    x += sin(direction) * playerSpeed;
}

(If we were working on a 2D game, we would move X instead of Z and Y instead of X)

Now that we know how to move forward, moving backward is straightforward (no pun intended).

moveBackward(direction) {
    z -= cos(direction) * playerSpeed;
    x -= sin(direction) * playerSpeed;
}

(Notice how we subtract on both axes, this is because if we are facing North-East - and we are walking backward - we would want to move South-West.)

For moving right:

moveRight(direction) {
    z -= cos(direction) * playerSpeed;
    x += sin(direction) * playerSpeed;
}

For moving left:

moveLeft(direction) {
    z += cos(direction) * playerSpeed;
    x -= sin(direction) * playerSpeed;
}

There you have it! We now can determine any movement vector based on an input angle!

Things to pay attention to:

Make sure you know what angle measurement you are using. In most cases it is going to be in radians, so don't try to use degrees unless that is what your sin/cos functions are expecting.

Make sure you know the "handedness" of your coordinate system as well. For example in some environments the Y-Axis is forward/back. And the Z-Axis is up and down. Or East is negative X and West is positive X.

Octal
  • 187
  • 10