简体   繁体   中英

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: http://i.imgur.com/2NdRXGn.gifv

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.radius = radius;
  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
{
     // cancel the launch because you are already at your destination
}

Adjust your ball speed to whatever constant speed you require

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM