js canvas 使用勾股定理的物体运动动画

js canvas object movement animation using pythagorean theorem

我试图让一个对象移动到点击位置,就像在像暗黑破坏神或现代 moba 游戏这样的角色扮演游戏中,我需要找到一种方法来动画点击坐标,我找到了一种使用毕达哥拉斯定理的方法,我在一定程度上理解和定制了代码,但是有一个错误,球在动画的最后一直在弹跳。我知道发生这种情况是因为“移动”变量和循环,但不明白为什么。

这是绘制对象的函数

function drawPlayer() {
    //
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    ctx.beginPath();
    ctx.arc(player.x, player.y, 12, 0, Math.PI*2);
    ctx.fillStyle = 'white';
    ctx.fill();
    ctx.closePath();
    
    //Calculate variables
    let dx = player.newx - player.x;
    let dy = player.newy - player.y;
    let distance = Math.sqrt(dx*dx + dy*dy);
    let moves = distance/player.speed;
    let xunits = (player.newx - player.x)/moves;
    let yunits = (player.newy - player.y)/moves;

    if (moves > 0 ) {
        moves--;
        player.x += xunits;
        player.y += yunits;
        console.log(moves);
    }
}

const canvas = document.getElementById('canvas1');
const ctx = canvas.getContext('2d');
canvas.addEventListener('click', e => {
  setClickCoords(e);
  drawPlayer();

})
canvas.width = 300;
canvas.height = 300;

const player = {
  x: 0,
  y: 0,
  newx: 0,
  newy: 0,
  speed: 1,
  radius: 15,
}

function drawPlayer() {
  //Draw 
  ctx.clearRect(0, 0, canvas.width, canvas.height);
  ctx.beginPath();
  ctx.arc(player.x, player.y, 12, 0, Math.PI * 2);
  ctx.fillStyle = 'white';
  ctx.fill();
  ctx.closePath();

  //Calculate variables
  let dx = player.newx - player.x;
  let dy = player.newy - player.y;
  let distance = Math.sqrt(dx * dx + dy * dy);
  let moves = distance / player.speed;
  let xunits = (player.newx - player.x) / moves;
  let yunits = (player.newy - player.y) / moves;

  console.log(moves);

  if (moves > 0) {
    moves--;
    player.x += xunits;
    player.y += yunits;
    console.log(moves);
  }
}

function setClickCoords(e) {

  player.newx = e.offsetX;
  player.newy = e.offsetY;
  document.getElementById('oldcoords').innerHTML = "old Coords " + player.x + " " + player.y;
  document.getElementById('newcoords').innerHTML = "new Coords " + player.newx + " " + player.newy;
}


function gameLoop() {
  window.setTimeout(gameLoop, 24);
  drawPlayer()
}

gameLoop();
body {
  background: black;
  display: flex;
  flex-direction: column;
}

#canvas1 {
  border: 3px solid white;
  top: 50%;
  left: 50%;
  position: absolute;
  width: 300px;
  height: 300px;
  transform: translate(-50%, -50%);
}

#oldcoords,
#newcoords {
  color: white;
  font-size: 18px;
}
<span id="oldcoords"></span>
<span id="newcoords"></span>

<canvas id="canvas1"> </canvas>

检查 moves 是否在 0 和 1 之间。如果介于两者之间,则将球移动到所需位置。目前,球在该方向上走得太远,必须在下一个动画中 return。

const canvas = document.getElementById('canvas1');
const ctx = canvas.getContext('2d');
canvas.addEventListener('click', e => {
  setClickCoords(e);
  drawPlayer();

})
canvas.width = 300;
canvas.height = 300;

const player = {
  x: 0,
  y: 0,
  newx: 0,
  newy: 0,
  speed: 1,
  radius: 15,
}

function drawPlayer() {
  //Draw 
  ctx.clearRect(0, 0, canvas.width, canvas.height);
  ctx.beginPath();
  ctx.arc(player.x, player.y, 12, 0, Math.PI * 2);
  ctx.fillStyle = 'white';
  ctx.fill();
  ctx.closePath();

  //Calculate variables
  let dx = player.newx - player.x;
  let dy = player.newy - player.y;
  let distance = Math.sqrt(dx * dx + dy * dy);
  let moves = distance / player.speed;

  console.log(moves);

  if (moves > 1) {
    let xunits = (player.newx - player.x) / moves;
    let yunits = (player.newy - player.y) / moves;
    moves--;
    player.x += xunits;
    player.y += yunits;
    console.log(moves);
  } else if (moves > 0) {
    moves = 0;
    player.x = player.newx;
    player.y = player.newy;
    console.log(moves);
  }
}

function setClickCoords(e) {

  player.newx = e.offsetX;
  player.newy = e.offsetY;
  document.getElementById('oldcoords').innerHTML = "old Coords " + player.x + " " + player.y;
  document.getElementById('newcoords').innerHTML = "new Coords " + player.newx + " " + player.newy;
}


function gameLoop() {
  window.setTimeout(gameLoop, 24);
  drawPlayer()
}

gameLoop();
body {
  background: black;
  display: flex;
  flex-direction: column;
}

#canvas1 {
  border: 3px solid white;
  top: 50%;
  left: 50%;
  position: absolute;
  width: 300px;
  height: 300px;
  transform: translate(-50%, -50%);
}

#oldcoords,
#newcoords {
  color: white;
  font-size: 18px;
}
<span id="oldcoords"></span>
<span id="newcoords"></span>

<canvas id="canvas1"> </canvas>