İki nokta arasındaki bir çizgide puan alma


9

JavaScript'te basit bir uzay oyunu yapıyorum, ama şimdi vektörlerle ilgili bir duvara çarptım.

Oyun görünümü 2d ızgarada yukarıdan aşağıya. Kullanıcı ızgarayı tıkladığında, uzay gemisi o noktaya uçacaktır.

Yani, iki nokta setim varsa:

{ x : 100.2, y : 100.6 }; // the ship
{ x : 20.5,  y : 55.95 }; // the clicked coordinates

Eğer oyun döngüsü saniyede 60 iterasyonda keneler ve istenen gemi hızı kene başına 0.05 puan (saniyede 3 puan) ise, oyun döngüsünün her bir kene için gemi için yeni koordinat setini nasıl hesaplayabilirim?

ps Ataleti veya gemiyi etkileyen birden fazla vektörü hesaba katmak istemiyorum, sadece geminin yaptığı her şeyi durdurmasını (yani tek yönlü uçmasını) ve statik bir hızda tıklanan koordinatlara gitmesini istiyorum.

Yanıtlar:


8

Sözde kodda:

speed_per_tick = 0.05
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: Şunu Do goal_distsizin de ifdurum?
Nate W.Mar

21

LERP - Doğrusal İnterpolasyon

Birkaç gün önce benzer bir soruna bu cevabı verdim, ama başlıyoruz:

Doğrusal Enterpolasyon, ilerlemeye bağlı olarak size iki sayı arasında bir sayı veren bir işlevdir. Aslında, iki nokta arasında bir nokta elde edebilirsiniz.


Büyük Formül - Nasıl hesaplanır

Genel LERP Formülü tarafından verilir pu = p0 + (p1 - p0) * u. Nerede:

  • pu: Sonuç numarası
  • p0: İlk sayı
  • p1: Son sayı
  • u: İlerleme. Yüzde 0 ile 1 arasında verilir.

Yüzde nasıl alınır?

"Bu yüzdeyi nasıl alabilirim !?" diye merak ediyor olabilirsiniz. Endişelenme. Bu şöyledir: Başlangıç ​​vektörünün bitmesi için ne kadar zaman geçmesi gerekir? Tamam, daha önce geçen zamana bölün. Bu size yüzdeyi verecektir.

Bak, şöyle bir şey: percentage = currentTime / finalTime;


Vektörleri Hesaplama

Sonuçta elde edilen bir vektör elde etmek için tek yapmanız gereken, biri X bileşeni diğeri Y bileşeni için formülü iki kez uygulamaktır. Bunun gibi bir şey:

point.x = start.x + (final.x - start.x) * progress;
point.y = start.y + (final.y - start.y) * progress;

Değişken zamanı hesaplama

Puanlarınızın 0,5 puan hızında seyahat etmesini isteyebilirsiniz, evet? Diyelim ki, daha uzun bir süre daha uzun bir mesafe kat edilecek.

Aşağıdaki gibi yapabilirsiniz:

  • Mesafe uzunluğunu al Bunun için iki şeye ihtiyacınız olacak. Mesafe vektörü alın, sonra uzunluk değerine dönüştürün.

    distancevec = final - start;
    distance = distancevec.length();

Umarım vektörleri matematik bilirsiniz. Bunu yapmazsanız, bu formülle bir vektör uzunluğunu hesaplayabilirsiniz d = sqrt(pow(v.x, 2) + pow(v.y, 2));.

  • Süreyi alın ve son zamanı güncelleyin. Bu kolay. Her bir kene için 0.5 uzunluk elde edersiniz, sadece bölmeliyiz ve kaç tane kenemiz var.

    finalTime = distance / 0.5f;

Bitti.

DİKKAT: Belki bu sizin için tasarlanan hız olmayabilir, ancak bu doğru. böylece köşegen hareketlerde bile doğrusal bir hareketiniz olur. X + = 0.5f, y + = 0.5f yapmak istiyorsanız, bir vektör matematik kitabı okuyun ve planlarınızı tekrar kontrol edin.


Yüzde konumunuzdan hedefe bırakılmak isterseniz ne olur? Eğer delta zamanı kullanamazsanız, x: y koordinatlarını kullanırsanız.
Dave

progressBu cevapta belirtildiği gibi hesapladıysanız , bu 0..1aralıkta olmalıdır . Yapmanız gerekenler:progressLeft = 1.0 - progress;
Gustavo Maciel

3

Bu, yönün normalini hesaplayarak ve ardından geçerli konumu parametrik denklemle hesaplayarak yapılabilir

newPoint = startPoint + directionVector * velocity * t

T, geminin istenilen yönde seyahat etmeye başlamasından bu yana geçen süredir. Bunu, güncelleme başına şu şekilde de yapabilirsiniz:

newPoint = currentPoint + directionVector * velocity * timeDelta

Ve bunu her karede / fizikte vb. Hesaplarsınız. gemi varış noktasına ulaşıncaya kadar güncelleyin.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.