5

これは以前に何度か尋ねられたことがあることは知っていますが、実際に機能する答えは見つかりませんでした。似たようなものもありますが、移動距離によって速度が異なります。

ですから、私の問題は、オブジェクト(この場合はプレーヤー)を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; //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;
    };
}

これが理にかなっていることを願っています。関連するコードの部分だけを含める必要がありました。私の問題はおそらくxRatioとyRatioの部分にあると思いますが、それを理解することはできません。私は完全に困惑しています。

編集:playerAngleがプレイヤーをドラッグの方向に向けさせ、その部分が正常に機能することを追加したいと思います。

4

2 に答える 2

9

ライブデモ

以下は、必要なものを機能させるために必要な基本事項です。

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

これは私がしばらく前に行ったデモで、あなたが探しているもののように聞こえます。問題に基づいてターゲットを変更するためにクリックする機能を追加しました。

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();
于 2012-12-12T21:45:35.273 に答える
3

あなたの問題はそれであるように思われ、ベクトル座標ではなく角度ですxRatioyRatioこれは機能するはずです:

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
        }
    };
}
于 2012-12-12T22:02:21.027 に答える