一定の速度でA(x、y)からB(x1、y1)に移動しますか?


21

私は現在、次のようなものを持っています:

float deltaX = point0.getX() - point1.getX();
float deltaY = point0.getY() - point1.getY();

そして、0.01秒ごとにオブジェクトの位置を次のように更新します。

object.setPosition(object.getX()-deltaX/100,object.getY()-deltaY/100);

これにより、1秒でオブジェクトがpoint0からpoint1に移動します。私が必要なのは、オブジェクトをpoint0から、(point1の方向に)一定の速度で移動できるようにするための2つのポイントを持つことです。したがって、最初のポイントに近いポイントがある場合、オブジェクトは、より遠くにポイントがある場合と同じ速度でそれに向かって移動します。どんな提案も大歓迎です。ありがとう。


可能性のある重複:gamedev.stackexchange.com/questions/23430/… 他の質問に答えたのと同じ答えを投稿します。しかし、これは私の部分の恥知らずでしょう。
グスタボマシエル

回答:


26

そのように操作を説明する方が簡単なので、線形代数構造を使用します。これらのベクトル演算の実装方法がわからない場合は、最後に簡単に説明します。

これらの値から始めてみましょう:動きの終点startendマークし、speed秒単位で移動するピクセルelapsed数であり、オブジェクトの位置を更新するレートです(一部のエンジンは既にその値を提供しています) ):

Vector2 start = new Vector2(x1, y2);
Vector2 end = new Vector2(x2, y2);
float speed = 100;
float elapsed = 0.01f;

最初に計算するのは、両方のポイント間の距離と、開始から終了までの方向を含む正規化されたベクトルです。また、オブジェクトの位置をstartポイントに「スナップ」する必要があります。このステップは最初に一度だけ行われます:

float distance = Vector2.Distance(start, end);
Vector2 direction = Vector2.Normalize(end - start);
object.Position = start;
moving = true;

次に、更新メソッドでdirectionspeedとの乗算elapsedをその位置に追加してオブジェクトを移動します。その後、動きが終わったかどうかを確認するために、開始点とオブジェクトの現在位置の間の距離が、計算した初期距離より大きいかどうかを確認します。それが当てはまる場合、オブジェクトの位置を終点にスナップし、オブジェクトの移動を停止します。

if(moving == true)
{
    object.Position += direction * speed * elapsed;
    if(Vector2.Distance(start, object.Position) >= distance)
    {
        object.Position = end;
        moving = false;
    }
}

クイックベクトル操作リファレンス

表現

Vector2 A = float aX, aY;

合計/減算

A+B = a.x + b.x; a.y + b.y;
A-B = a.x - b.x; a.y - b.y;

スカラーで乗算(フロート)

A*float = a.x*float; a.y*float;

長さ/距離

length(A) = sqrt(a.x*a.x + a.y*a.y)
distance(A,B) = length(B-A)

ノーマライズ

normalize(A) = a.X/length(A); a.Y/length(A);

Vectorクラスを使用できない場合は、上記のコードを通常の操作に変換するのに十分なはずです。


変換の例

// Your Variables
float startX, startY, endX, endY;
float speed = 100;
float elapsed = 0.01f;

// On starting movement
float distance = Math.sqrt(Math.pow(endX-startX,2)+Math.pow(endY-startY,2));
float directionX = (endX-startX) / distance;
float directionY = (endY-startY) / distance;
object.X = startX;
object.Y = startY;
moving = true;

// On update
if(moving == true)
{
    object.X += directionX * speed * elapsed;
    object.Y += directionY * speed * elapsed;
    if(Math.sqrt(Math.pow(object.X-startX,2)+Math.pow(object.Y-startY,2)) >= distance)
    {
        object.X = endX;
        object.Y = endY;
        moving = false;
    }
}

1
@Fofoleですから、最後にベクトルについて説明しました。答えは一般的であると想定されていました。Vectorクラスがない場合は、2つの個別のフロートを使用します。たとえば、にVector2 start;なりfloat startX, startY;ます。最後に説明するように、距離は手動で簡単に計算できます。すなわちfloat dX = bX - aX; float dY = bY - aY; float distance = Math.sqrt(dx*dx+dy*dy);
デヴィッドゴーベイア

@Fafole編集を確認し、例を追加しました。私が何かを逃したかどうかはわかりませんが。
デヴィッドゴーベイア

3年後、ベクトルを使用してオブジェクトを移動する方法を理解してもらいました。乾杯!
オリバーシェーニング


2

私の答えからコピーして貼り付けました:2つのポイント間の線でポイントを取得します

擬似コード内:

speed_per_tick = 0.05 //constant speed you want the object to move at
delta_x = x_goal - x_current
delta_y = y_goal - y_current
goal_dist = sqrt( (delta_x * delta_x) + (delta_y * delta_y) )
if (dist > speed_per_tick)
{
    ratio = speed_per_tick / goal_dist
    x_move = ratio * delta_x  
    y_move = ratio * delta_y
    new_x_pos = x_move + x_current  
    new_y_pos = y_move + y_current
}
else
{
    new_x_pos = x_goal 
    new_y_pos = y_goal
}

この回答は、私のユースケースに最適です。
シェル
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.