Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
264 views
in Technique[技术] by (71.8m points)

javascript - Moving an object along a straight line at a constant speed from point A to B

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.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

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

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

2.1m questions

2.1m answers

60 comments

56.9k users

...