Déplacement d'un objet le long d'une ligne droite à une vitesse constante du point A à B

Je sais que cela a été demandé quelques fois auparavant, mais il n'y a pas eu de réponse qui fonctionne réellement que je peux trouver. Il y en a un semblable, mais la vitesse varie en fonction de la distance parcourue.

Donc, mon problème est que j'essaie d'obtenir un objet (un joueur dans ce cas) pour déplacer une longue ligne droite du point A vers B à une vitesse constante. Cela se fait en cliquant sur le lecteur et en faisant glisser vers l'endroit où je le souhaite marcher, donc il peut être dans n'importe quelle direction et sur n'importe quelle distance.

J'ai un code qui fonctionne presque, mais le joueur finit toujours légèrement par hasard, d'autant plus la distance qu'il parcourt est plus longue. Voici ce code:

window.addEventListener('mouseup', function(e) { selectedPlayer.moveX = e.pageX; selectedPlayer.moveY = e.pageY; movePlayer(selectedPlayer); }); function movePlayer(player) { var xDistance = player.moveX - player.x; var yDistance = player.moveY - player.y; var travelDistance = Math.sqrt((xDistance * xDistance) + (yDistance * yDistance)); var timeToTravel = travelDistance; //This may seem pointless, but I will add a speed variable later var playerAngle = Math.atan2(yDistance, xDistance) * (180 / Math.PI); var xRatio = Math.atan2(xDistance, travelDistance); var yRatio = Math.atan2(yDistance, travelDistance); //This function is called in another part of code that repeats it 60 times a second walkPlayer = function() { setTimeout(function(){ player.x = player.moveX; player.y = player.moveY; selectedPlayer = undefined; walkPlayer = undefined; }, timeToTravel * 20) player.angle = playerAngle; player.x += xRatio; player.y += yRatio; }; } 

J'espère que cela a du sens, j'ai dû inclure seulement la partie du code qui est pertinente. Je pense que mon problème réside probablement dans les parties xRatio et yRatio, mais je ne peux pas le comprendre; Je suis complètement perplexe.

EDIT: J'aimerais ajouter que playerAngle rend le joueur face à la direction de la traînée, et cette partie fonctionne bien.

Demo en direct

Voici les bases nécessaires pour obtenir ce dont vous avez besoin de travailler,

 var tx = targetX - x, ty = targetY - y, dist = Math.sqrt(tx*tx+ty*ty), rad = Math.atan2(ty,tx), angle = rad/Math.PI * 180;; velX = (tx/dist)*thrust; velY = (ty/dist)*thrust; player.x += velX player.y += velY 

C'est une démo que j'ai fait un peu en arrière, ce qui ressemble à ce que vous recherchez, j'ai ajouté la possibilité de cliquer afin de modifier la cible en fonction de votre problème.

 window.addEventListener('mouseup', function(e) { targetX = e.pageX; targetY = e.pageY; }); var ctx = document.getElementById("canvas").getContext("2d"), x = 300, y = 0, targetX = Math.random()*300, targetY = Math.random()*300, velX = 0, velY = 0, thrust = 5; function draw(){ var tx = targetX - x, ty = targetY - y, dist = Math.sqrt(tx*tx+ty*ty), rad = Math.atan2(ty,tx), angle = rad/Math.PI * 180;; velX = (tx/dist)*thrust; velY = (ty/dist)*thrust; // stop the box if its too close so it doesn't just rotate and bounce if(dist > 1){ x += velX; y += velY; } ctx.fillStyle = "#fff"; ctx.clearRect(0,0,400,400); ctx.beginPath(); ctx.rect(x, y, 10, 10); ctx.closePath(); ctx.fill(); ctx.fillStyle = "#ff0"; ctx.beginPath(); ctx.rect(targetX, targetY, 10, 10); ctx.closePath(); ctx.fill(); setTimeout(function(){draw()}, 30); } draw(); 

Votre problème semble être que xRatio et yRatio sont des angles, pas des coordonnées vectorielles. Cela devrait fonctionner:

 document.addEventListener('mouseup', function(e) { movePlayer(selectedPlayer, {x:e.pageX, y:e.pageY}); }); function movePlayer(player, target) { var start = { x: player.x, y: player.y, t: Date.now() }, distance = Math.sqrt(distance.x*distance.x + distance.y*distance.y), time = distance; //This may seem pointless, but I will add a speed variable later difference = { x: target.x - player.x, y: target.y - player.y, t: time }; player.angle = Math.atan2(distance.y, distance.x) * (180 / Math.PI); //This function is called in another part of code that repeats it 60 times a second walkPlayer = function(curTime) { // we need timing information here: Date.now() var elapsed = curTime - start.t, ratio = elapsed / difference.t; player.x = start.x + difference.x * ratio; player.y = start.y + difference.y * ratio; if (ratio >= 1) { player.x = target.x; player.y = target.y; // end calling of walkPlayer } }; }