# physics – Applying friction separately to forward and side directions

I’m making a movement-based, first-person 3D game where the player should be able to gain a lot of horizontal speed over time with WASD, but also will stop due to friction very quickly the moment they release their movement key. The player’s current horizontal movement is a velocity stored in a 2-dimensional vector.

Due to the requirement of needing to stop fast, I have a high amount of friction applied (the velocity is multiplied by `0.7`.) However, in order to allow gaining high amounts of horizontal speed, the friction is much, much lower when the player is moving, `0.99`.

I intend to separate the friction for forward/back from the friction for left/right, as this allows the player finer control over the current directions they’re moving in.

Unfortunately, my code is broken, resulting in it working exactly as I intend only when you’re facing in a cardinal direction — every other time, you have far too much friction. At this point, I realise that I’m not really sure what I’m doing, and my guesses aren’t panning out. How do I correctly apply friction separately to the forwards/backwards and side directions?

I don’t really want to include it in the question, but in case it’s necessary, here’s my current code — JavaScript, with a custom Vec2 class.
`powXY` is `v1.x **= v2.x; v1.y **= v2.y`. Everything else should be self-explanatory.

``````const direction = this.CAMERA.rotation.y;
const forwardBackVector = Vec2.fromDirection(direction).abs();
const leftRightVector = Vec2.fromDirection(direction + Math.PI / 2).abs();

let forwardBackInput = 0;
let leftRightInput = 0;

if (this.KEYBOARD.isDown("KeyE"))
forwardBackInput++;
if (this.KEYBOARD.isDown("KeyD"))
forwardBackInput--;

if (this.KEYBOARD.isDown("KeyS"))
leftRightInput++;
if (this.KEYBOARD.isDown("KeyF"))
leftRightInput--;

let forwardBackFriction = new Vec2(this.FRICTION).powXY(...forwardBackVector.xy);
let leftRightFriction = new Vec2(this.FRICTION).powXY(...leftRightVector.xy);

const acceleration = Vec2.ZERO;
if (forwardBackInput) {
const normalisedVector = Vec2.fromDirection(direction + (forwardBackInput === 1 ? 0 : Math.PI));
const dot = this.horizontalVelocity.dot(normalisedVector) * this.horizontalVelocity.length();
.multiply(dot < this.SPEED_HORIZONTAL_CAP ? this.SPEED_HORIZONTAL_FAST : this.SPEED_HORIZONTAL)
.multiply(delta)
.multiply(leftRightInput ? 0.5 : 1));

forwardBackFriction = new Vec2(this.FRICTION_MOVE).powXY(...forwardBackVector.xy);
}

if (leftRightInput) {
const normalisedVector = Vec2.fromDirection(direction + Math.PI / 2 * leftRightInput);
const dot = this.horizontalVelocity.dot(normalisedVector) * this.horizontalVelocity.length();
.multiply(dot < this.SPEED_HORIZONTAL_CAP ? this.SPEED_HORIZONTAL_FAST : this.SPEED_HORIZONTAL)
.multiply(delta)
.multiply(forwardBackInput ? 0.5 : 1));

leftRightFriction = new Vec2(this.FRICTION_MOVE).powXY(...leftRightVector.xy);
}

$$```$$