Bir nesnenin güzel bir kavisli hareketle noktalar arasında hareket etmesini sağlamak için iyi bir teknik nedir?
Bir son hedef füzenin yörüngesi gibi son konum da hareket halinde olabilir.
Bir nesnenin güzel bir kavisli hareketle noktalar arasında hareket etmesini sağlamak için iyi bir teknik nedir?
Bir son hedef füzenin yörüngesi gibi son konum da hareket halinde olabilir.
Yanıtlar:
Bunun, önceden hesaplanmış bir yörünge değil, kare kare bir şey olmasını istediğinizi varsayarsak (hedefin hareket edebileceği yerde) ve bu aslında inanılmaz derecede basittir:
Her kare, füzenin hız-vektörünü vektörle karşılaştırın (konum hedefi - konum füzesi ) ; yani füzeden hedefe işaret eden vektör. Her bir çerçeve, eğer iki vektör aynı yöne sahip değilse, velog vektörünü diğer vektöre doğru biraz döndürün, böylece her çerçeve füze hedefine biraz daha yaklaşır.
İki vektör arasındaki çapraz ürünün işaretine bakarak saat yönünde mi yoksa saat yönünün tersine mi döndürüleceğini belirleyebilirsiniz.
[Düzenle] XNA-ish kodu (Bunu test etmek için XNA yok):
//Once a frame:
//Get vector spanning from missile to target
Vector2 vectorToTarget = target.Position - missile.Position;
//Convert to Vector3 to do cross-product
Vector3 vectorToTarget3 = new Vector3(vectorToTarget, 0);
Vector3 missileVelocity3 = new Vector3(missile.Velocity, 0);
//Rotate clockwise/counter-clockwise is determined by sign of cross-product
int crossProductSign = Vector3.Cross(missileVelocity3, vectorToTarget3).Z;
//Positive cross-product means rotate counter-clockwise, negative is clockwise
double rotationAngle = 0;
if(crossProductSign > 0)
rotationAngle = -0.05;
else if(crossProductSign < 0)
rotationAngle = 0.05;
//I'm not sure how to do rotation in XNA, but the internets tell me it's something like this:
missile.velocity = Vector2.Transform(missile.velocity, Matrix.CreateRotationZ(rotationAngle))
rotationAngle
Yalnızca üç olası değeri olduğundan , olası tüm değerlerinin Matrix.CreateRotationZ(rotationAngle)
önbelleğe alınabileceğini, böylece her kareyi çağırmanız gerekmeyeceğini unutmayın.
İki olası teknik vardır:
İlk teknik, çerçeve tabanlı bir simülasyon yapmaktır . Oynanışta hedef füze gibi bir şey yapıyorsanız, hedefinize tam olarak ulaşmak zorunda değilsiniz.
Bu durumda, nesnenin konumunu ve hızını izlemek istersiniz. Her kare hedefe ve geçerli hareket yönüne bakar ve hızı uygun şekilde ayarlar.
Hızı anında yakalarsanız, füzeniz her zaman hedefi vurur. Ancak hızı her bir karede küçük bir miktarda ayarlarsanız, füzeniz hedefe doğru eğilir - ve yeterince yavaş eğilirse, hedef onu atlatabilir.
İkinci teknik bir parametrik bir yöntem . Bu, hedefinize kesin ve tahmin edilebilir bir şekilde ulaşmak istediğiniz şeyleri canlandırmak için kullanışlıdır. Bu durumda parametreniz olarak genellikle "zaman" alır ve bir tür fonksiyona koyarsınız.
Özellikle kullanışlı bir fonksiyonlar dizisi Hareket Denklemleridir lise fiziğinde öğrendiğiniz . Bunları her iki eksene uygulayarak balistik yörüngeler elde edebilirsiniz. Biraz matematikle, bir hedefi vurmak için başlangıç parametrelerini belirleyebilirsiniz - tahmin edilebilir şekilde hareket ederse, hareketli bir parametre bile.
XNA ayrıca bir dizi enterpolasyon ve kavisli hareket fonksiyonu sağlar. İçin Vector2
ve belgelerine göz atınMathHelper
. Bunlar ilginç şeyler yapmak için kullanabileceğiniz ve hatta birleştirebileceğiniz bazı enterpolasyon fonksiyonları sağlar. Örneğin, bir füze ateşlemek: Lerp
(doğrusal interpolate) füzenizin konumunu başlangıç noktasından bir hedef konuma ve ayrıca bu hedef konumu bir başlangıç hedefinden hedef nesnenin gerçek (değişen) konumuna getirin. Bu size hoş bir "kilitleme" efekti verecektir.
(Bazı fonksiyonlar, örneğin eğrileri üretmek için vardır: CatmulRom
,Hermite
bunların hareketli bir hedefle başarılı bir şekilde kullanılması muhtemelen daha zordur.)
"Hareket hızı" na (animasyon bağlamında) bakarsanız, size hızlanma gibi ilginç efektler verebilecek daha ilginç enterpolasyon fonksiyonları elde edebilirsiniz.
Şimdi - hedefiniz hareket ettikçe bu tekniğin bazı garip sonuçlar verdiğini söyleyebilirsiniz. Bununla birlikte, uygulamada, merminiz hedefinizden daha hızlı hareket ettiği sürece, genellikle iyi görünür. Eğer bir sorun varsa, muhtemelen yine de çerçeve tabanlı bir teknik kullanıyor olmalısınız.
Sinüs dalgalarını veya muhtemelen Bezier Eğrilerini aramak isteyebilirsiniz . Sinüs dalgası yaklaşımının normal olup olmadığını bilmiyorum, ama neden bu kadar fakir olacağını göremiyorum.
Craig Reynolds tarafından tanımlandığı gibi Direksiyon Davranışlarına göz atabilirsiniz: http://red3d.com/cwr/steer/
Bu genellikle AI'de NPC'lerin hedeflerine doğru hareket etmesini sağlamak için kullanılır.