Home > Blockchain >  js canvas object movement animation using pythagorean theorem
js canvas object movement animation using pythagorean theorem

Time:04-28

I am trying to make an object move to click position, like in rpgs like diablo or modern moba games, i needed to find a way to animate to click coordinates and i have found a method that uses pythagorean theorem, i understood and custimized the code to a certain degree, but there is a bug where the ball keeps bouncing in the very end of animation. I know this happens because of the "moves" variable and the loop, but can't understand exactly why.

here's the function that draws the object

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>

CodePudding user response:

Check if moves is between 0 and 1. If it's between, move the ball to the desired position. Currently, the ball goes too far in the direction and has to return in the next animation.

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>

  • Related