Pindah dari A (x, y) ke B (x1, y1) dengan kecepatan konstan?

21

Saat ini saya memiliki sesuatu seperti:

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

Dan setiap 0,01 detik saya menyegarkan posisi objek saya seperti ini:

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

Jadi ini memindahkan objek saya dari point0 ke point1 dalam 1 detik. Yang saya butuhkan adalah memiliki 2 poin, untuk dapat memindahkan objek dari point0, menghadap (ke arah) point1 dengan kecepatan konstan. Jadi, ketika saya memiliki titik yang lebih dekat ke titik awal saya, objek akan bergerak ke arahnya dengan kecepatan yang sama jika saya memiliki titik yang lebih jauh. Ada saran yang dihargai. Terima kasih.

Fofole
sumber
Kemungkinan rangkap: gamedev.stackexchange.com/questions/23430/... Saya akan memposting jawaban yang sama dengan yang saya berikan pada pertanyaan lain. Tapi ini tidak akan memalukan bagiku.
Gustavo Maciel

Jawaban:

26

Saya akan menggunakan beberapa struktur aljabar linier karena lebih mudah menggambarkan operasi seperti itu. Jika Anda tidak tahu bagaimana menerapkan operasi vektor ini, saya akan memberikan penjelasan singkat di bagian akhir.

Jadi katakanlah Anda mulai dengan nilai-nilai ini: startdan endtandai titik akhir gerakan, speedadalah berapa banyak piksel yang harusnya bergerak dengan detik, dan elapsedadalah tingkat di mana Anda akan memperbarui posisi objek Anda (beberapa mesin sudah memberikan nilai itu untuk Anda ):

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

Hal pertama yang ingin Anda hitung adalah jarak antara kedua titik, dan vektor yang dinormalisasi yang berisi arah dari awal hingga akhir. Juga, Anda harus "mematahkan" posisi objek ke starttitik. Langkah ini dilakukan hanya sekali, pada awalnya:

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

Kemudian pada metode pembaruan Anda, Anda memindahkan objek dengan menambahkan perkalian direction, speeddan elapsedke posisinya. Setelah itu, untuk memeriksa apakah gerakan sudah berakhir, Anda melihat apakah jarak antara titik awal dan posisi objek saat ini lebih besar dari jarak awal yang Anda hitung. Jika itu benar, kami pasang posisi objek ke titik akhir, dan berhenti memindahkan objek:

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

Referensi Operasi Vektor Cepat

Perwakilan

Vector2 A = float aX, aY;

Jumlah / Kurangi

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

Kalikan dengan Scalar (float)

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

Panjang / Jarak

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

Normalisasi

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

Itu seharusnya cukup untuk mengubah kode di atas menjadi operasi reguler jika Anda tidak memiliki Vectorkelas yang tersedia untuk Anda.


Contoh Konversi

// 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;
    }
}
David Gouveia
sumber
1
@Fofole Itu sebabnya saya memberi penjelasan tentang vektor di akhir. Jawabannya seharusnya generik. Jika Anda tidak memiliki kelas vektor, maka gunakan dua float terpisah. Misalnya Vector2 start;menjadi float startX, startY;. Dan Anda dapat dengan mudah menghitung jarak secara manual, seperti yang saya jelaskan di bagian akhir. Yaitu float dX = bX - aX; float dY = bY - aY; float distance = Math.sqrt(dx*dx+dy*dy);.
David Gouveia
@Fafole Periksa hasil edit, saya menambahkan contoh. Tidak yakin apakah saya melewatkan sesuatu.
David Gouveia
3 tahun kemudian dan Anda baru saja membuat saya mengerti cara memindahkan objek dengan vektor. Tepuk tangan!
Oliver Schöning
3

Buat Vektor dan normalkan kembali. Peringatan, beberapa kode semu dengan nomor yang salah di depan:

Vector = new Vector(point0.getX() - point1.getX(), point0.getY() - point1.getY());

Ini akan memberi Anda Vector seperti:

25.96; 85.41

Sekarang normalkan vektornya, dan Anda akan menerima ini :

0.12; 0.75

Dari sini gerakannya sama dengan delta Anda.

Polisi
sumber
2

Disalin dan ditempel dari jawaban saya ke: Dapatkan poin pada garis antara dua poin

Dalam Pseudocode:

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
}
Tristan
sumber
Jawaban ini paling cocok untuk kasus penggunaan saya.
shell