Racialz - 5 months ago 4
Javascript Question

# How can I always move a ball at the same speed to an (x,y) position regardless of its starting position

This image illustrates my problem very well:

The ball moves very slow when it is close to its endpoint (orange circle) but moves very fast when it's farther away from its endpoint.

The reason this happens is because I'm using this code to calculate my vertical and horizontal velocities for the balls

``````var startingBallSpeed = 100;
xDistance = targetX - this.x;
yDistance = targetY - this.y;

this.horizontalVelocity = (xDistance / startingBallSpeed);
this.verticalVelocity = (yDistance / startingBallSpeed);
``````

QUESTION: How can I make sure that the balls travel the same speed and will still hit the targetX and targetY

Current Behavior: Balls close to endpoint move slow, balls far from endpoint move fast

Desired Behavior: Balls move at the same speed regardless of how close they are to the endpoint

JS: https://jsfiddle.net/7ct1ap53/1

``````ball1 = new Ball(400, 480, "green");
ball2 = new Ball(20, 480, "blue");

targetX = 500;
targetY = 400;
targetBall = new Ball(targetX, targetY, "magenta", radius=10)

var gameArea = {
canvas: document.createElement("canvas"),
start: function() {
this.canvas.width = 500;
this.canvas.height = 500;
this.context = this.canvas.getContext("2d");
document.body.insertBefore(this.canvas, document.body.childNodes[4]);
this.interval = setInterval(updateGame, 20); //20
}
};

function Ball(x, y, color, radius=15) {
this.x = x;
this.y = y;
this.color = color

this.draw = function() {
gameArea.context.beginPath();
gameArea.context.arc(this.x, this.y, this.radius, 0, Math.PI * 2, false);
gameArea.context.fillStyle = color;
gameArea.context.fill();
gameArea.context.closePath();
}

this.launch = function() {
var startingBallSpeed = 100;
xDistance = targetX - this.x;
yDistance = targetY - this.y;

this.horizontalVelocity = (xDistance / startingBallSpeed);
this.verticalVelocity = (yDistance / startingBallSpeed);
}

this.updatePos = function() {
this.x += this.horizontalVelocity;
this.y += this.verticalVelocity;
};
}

\$(function() {
startGame();
});

function updateGame() {
gameArea.context.clearRect(0,0,500,500);
ball1.updatePos();
ball2.updatePos();

ball1.draw();
ball2.draw();
targetBall.draw();
}

function startGame() {

gameArea.start();
ball1.launch();
ball2.launch();
}
``````

You need to normalize the vector defined by xDistance, yDistance to create a unit vector that specifies the direction but has a length of 1. Then you can multiply it by your desired ball speed to get the velocity.

Normalize by dividing by the length:

``````xDistance = targetX - this.x;
yDistance = targetY - this.y;
length = Math.sqrt((xDistance * xDistance) + (yDistance * yDistance));
if(length > 0) // avoid divide by zero
{
xUnitVector = xDistance / length;
yUnitVector = yDistance / length;

this.horizontalVelocity = xUnitVector * startingBallSpeed;
this.verticalVelocity = yUnitVector * startingBallSpeed;
}
else
{