# 2D top down 360 degrees rotational movement - stop instant rotation

I currently have a working, decently complicated, way of moving my player around.

Using A & D you rotate the player and using W and D you increase forward or backward moving speed.

This works great!

I now want to update my code so that while rotating, the player will not instantly start moving in that direction, but it will start turning in that direction and after an adjustable "speed/time" start moving in that direction entirely.

So the player can rotate freely around without anything happening. But when facing a new direction, the player's speed should easy towards that direction until it is moving in the direction the player is facing. Currently this happens instantly.

An example of how I want my movement: https://www.youtube.com/watch?v=CwkVrxYZvEE

Here's my current code, I barelly understand how this works tbh. I do feel I'd just need a few minor tweaks to get this working?

Feel free to ask if you need any more info! Also feel free to use any of this code for your own purposes!

var canvas = document.getElementById('canvas');
var c = canvas.getContext('2d');

// Movement
var playerWidth = 64;
var playerHeight = 64;
var playerX = 500;
var playerY = 500;
var playerAngle = 1 * Math.PI / 180;
var rotationRate = 4 * Math.PI / 180;
var playerSpeed = 0;
var maxSpeed = 4;
var moveResistance = 0.04;
var speedRate = 0.05;
var speedUp = false;
var turnRight = false;
var speedDown = false;
var turnLeft = false;

// Images
var playerSprite1 = new Image();
playerSprite1.src = '/assets/sprites/spider-red.png';

// Game loop
setInterval(function() {
c.clearRect(0, 0, canvas.width, canvas.height);
calculatePosition();
drawReDrawCanvas();
}, 1000 / 60);

function calculatePosition() {
if (speedUp) {
playerSpeed += speedRate;
if (playerSpeed > maxSpeed) {
playerSpeed = maxSpeed;
}
}
else if (speedDown) {
playerSpeed -= speedRate;
if (playerSpeed < -maxSpeed) {
playerSpeed = -maxSpeed;
}
}
else {
// Somehow the player keeps moving if speed is < 0.05
if (Math.abs(playerSpeed) < 0.05) {
playerSpeed = 0;
}
if (playerSpeed > 0) {
playerSpeed -= moveResistance;
}
if (playerSpeed < 0) {
playerSpeed += moveResistance;
}
}
if (turnRight) {
playerAngle += rotationRate;
}
if (turnLeft) {
playerAngle -= rotationRate;
}
}

function drawReDrawCanvas() {
playerX += Math.sin(playerAngle) * playerSpeed;
playerY -= Math.cos(playerAngle) * playerSpeed;
c.save();
c.translate(playerX, playerY);
c.rotate(playerAngle);
c.drawImage(playerSprite1, playerWidth / -2, playerHeight / -2);
c.restore();
}

var k = e.code;
switch (k) {
case 'KeyW':
speedUp = true;
speedDown = false;
break;
case 'KeyD':
turnRight = true;
turnLeft = false;
break;
case 'KeyS':
speedDown = true;
speedUp = false;
break;
case 'KeyA':
turnLeft = true;
turnRight = false;
break;
}
});

var k = e.code;
switch (k) {
case 'KeyW':
speedUp = false;
break;
case 'KeyD':
turnRight = false;
break;
case 'KeyS':
speedDown = false;
break;
case 'KeyA':
turnLeft = false;
break;
}
});
<!doctype html>
<html>
<title>Rotation</title>
<body>
<canvas id="canvas"></canvas>

<script type="text/javascript" src="player.js"></script>
</body>
</html>

Had a friend who's pretty good at math solve this with (for) me!

Here's the result:

var canvas = document.getElementById('canvas');
var c = canvas.getContext('2d');

// Movement
var playerWidth = 64;
var playerHeight = 64;
var playerX = 500;
var playerY = 500;
var playerAngle = -1 * Math.PI / 2;
var rotationRate = 4 * Math.PI / 180;
var playerSpeedX = 0;
var playerSpeedY = 0;
var maxSpeed = 4;
var moveResistance = 0.99;
var thrust = 0.1;
var speedUp = false;
var turnRight = false;
var speedDown = false;
var turnLeft = false;

// Images
var playerSprite1 = new Image();
playerSprite1.src = '/assets/sprites/spider-red.png';

// Game loop
setInterval(function() {
c.clearRect(0, 0, canvas.width, canvas.height);
drawMap();
calculatePosition();
drawReDrawCanvas();
}, 1000 / 60);

function calculatePosition() {
var thrustX = thrust * Math.cos(playerAngle);
var thrustY = thrust * Math.sin(playerAngle);
if (speedUp) {
playerSpeedX = playerSpeedX + thrustX;
playerSpeedY = playerSpeedY + thrustY;
}
else if (speedDown) {
playerSpeedX = playerSpeedX - thrustX;
playerSpeedY = playerSpeedY - thrustY;
}
playerSpeedX = playerSpeedX * moveResistance;
playerSpeedY = playerSpeedY * moveResistance;
var speed = Math.sqrt(playerSpeedX * playerSpeedX + playerSpeedY * playerSpeedY);
if (speed > maxSpeed) {
playerSpeedX = playerSpeedX / (speed / maxSpeed);
playerSpeedY = playerSpeedY / (speed / maxSpeed);
}
if (turnRight) {
playerAngle += rotationRate;
}
if (turnLeft) {
playerAngle -= rotationRate;
}
}

function drawReDrawCanvas() {
playerX += playerSpeedX;
playerY += playerSpeedY;
c.save();
c.translate(playerX, playerY);
c.rotate(playerAngle);
c.drawImage(playerSprite1, playerWidth / -2, playerHeight / -2);
c.restore();
}

var k = e.code;
switch (k) {
case 'KeyW':
speedUp = true;
speedDown = false;
break;
case 'KeyD':
turnRight = true;
turnLeft = false;
break;
case 'KeyS':
speedDown = true;
speedUp = false;
break;
case 'KeyA':
turnLeft = true;
turnRight = false;
break;
}
});

var k = e.code;
switch (k) {
case 'KeyW':
speedUp = false;
break;
case 'KeyD':
turnRight = false;
break;
case 'KeyS':
speedDown = false;
break;
case 'KeyA':
turnLeft = false;
break;
}
});