沿着直线以恒定速度从点A到B移动对象 [英] Moving an object along a straight line at a constant speed from point A to B

查看:115
本文介绍了沿着直线以恒定速度从点A到B移动对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道这已经被问过几次,但没有答案,实际工作,我可以找到。



所以我的问题是,我试图得到一个对象(玩家)在这种情况下)以恒定速度从点A到B移动长直线。这是通过点击播放器并拖动到我想他走到的地方,所以它可以在任何方向和任何距离。



我有一些代码这是非常接近的作品,但球员总是最终略微偏离航线,更多的是,他的旅行距离越长。这里是代码:

  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; //这可能看起来毫无意义,但我稍后会添加一个速度变量
var playerAngle = Math.atan2(yDistance,xDistance)*(180 / Math.PI);
var xRatio = Math.atan2(xDistance,travelDistance);
var yRatio = Math.atan2(yDistance,travelDistance);

//此函数在代码的另一部分中调用,每秒重复60次
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;
};
}



我希望这有意义,相关的代码。我认为我的问题可能在于xRatio和yRatio部分,但我不能弄清楚;我完全被困了。



编辑:我想补充说,playerAngle使玩家面向拖动的方向,这部分工作正常。 >>



以下是获得所需工作所需的基本知识。

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

velX =(tx / dist)* thrust;
velY =(ty / dist)* thrust;

player.x + = velX
player.y + = velY

这是一个演示,我做了一个回来,听起来像你正在寻找,我添加了能力点击为了改变目标基于你的问题。

  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;

//如果它太近就停止框,所以它不只是旋转和弹跳
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();


I know this has been asked a few times before, but there has been no answer that actually works that I can find. There is a similar one, but the speed varies depending on the distance travelled.

So my problem is that I am trying to get an object (a player in this case) to move a long a straight line from point A to B at a constant speed. This is done by clicking on the player and dragging to where I want him to walk to, so it can be in any direction and over any distance.

I have some code that very nearly works, but the player always ends up slightly off course, more so the longer the distance he travels is. Here is that 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;
    };
}

I hope this makes sense, I've had to include only the part of the code that is relevant. I think my issue probably lies with the xRatio and yRatio parts, but I can't figure it out; I'm completely stumped.

EDIT: I'd like to add that playerAngle makes the player face in the direction of the drag, and that part works fine.

解决方案

Live Demo

Below are the basics required to get what you need working,

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

This is a demo I did a while back which sounds like what you are looking for, I added the ability to click in order to change the target based off of your issue.

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();

这篇关于沿着直线以恒定速度从点A到B移动对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆