2D kule savunması - Bir düşmana kurşun


14

Bir merminin düşmanı vurması için iyi bir çözüm bulmaya çalışıyorum. Oyun 2D kule savunma, kule bir kurşun ateş ve garantili düşman vurmak gerekiyordu.

Bu çözümü denedim - http://blog.wolfire.com/2009/07/linear-algebra-for-game-developers-part-1/

Merminin kökenini ve düşmanı da çıkarmak için adı geçen bağlantı (vektör çıkarma). Bunu denedim ama sadece düşmanın etrafında bir kurşun izliyor.

float diffX = enemy.position.x - position.x;
float diffY = enemy.position.y - position.y;

velocity.x = diffX;
velocity.y = diffY;

position.add(velocity.x * deltaTime, velocity.y * deltaTime);

Vektörleri tanıyorum ama bu çözümü çalıştırmak için hangi adımların (vektör matematik işlemleri) yapılması gerektiğinden emin değilim.


Yanıtlar:


11

Akıl yürütmeniz mükemmeldi: konumumdan hedefime geçmek için bir vektör kullanın. Bu bir vektörün amacıdır ; sadece hızı unuttun !

Hız bir vektördür: hız ve yön. Ancak, fark vektörünü normalleştirmeyi ve mermi hızını (bir skaler) çarpmayı unutursanız, temelde hedefe yakınsanız (fark vektörü küçükse) merminin yavaşladığını söylüyorsunuz ; eğer uzaktaysanız mermi hızı daha büyük olur.

Bu altta yatan problemdir: vektörün hem yönünü hem de büyüklüğünü hesaplamanız gerekir .


Yardım için teşekkürler. Fark vektörünü hesapladıktan sonra skaler kullanmaya çalıştım, işe yaradı ama iyi görünmüyor. Fark vektörünü hesaplayıp hesaplamayacağımı, normalleştirip hızını skalarsam görmeye çalıştım. Şimdi daha iyi görünüyor. Evet, sanırım bir süre sonra bu oyunda güdümlü füzelere ihtiyacım var. Tekrar teşekkürler.
Tashu

1
Bu cevap kimseye bir anlam ifade etmiyor mu?
BlueRaja - Danny Pflughoeft

@Fxlll: Tamam, sanırım ne söylemeye çalıştığını görüyorum. Başlangıç ​​/ bitiş cevabı ile ilgili olmayan çok fazla tüy var ve ben de İngilizcenizle karıştırıldım (ki muhtemelen sizin hatanız olmadığını anlıyorum) . Bu yanıtı temizlemek için bir düzenleme önerisi gönderdim.
BlueRaja - Dany Pflughoeft

@BlueRaja - Danny Pflughoeft çabalarınız için teşekkürler!
FxIII

7

Hedef sabit bir hızda sabit bir yönde hareket ediyorsa ve mermi yolunuz sabit bir hızda düz bir çizgideyse, kesişecekleri kesin noktayı tahmin etmek ve kulenizin silahını o noktaya hedeflemek için ikinci dereceden bir denklem kullanabilirsiniz. .

Merminin işaretine vuracağı kesin olduğundan ve ateş etmeden darbeye kadar geçen tam zamanı hesaplayabildiğiniz için, çarpışma tespitine gerek yoktur, sadece silahı ateşleyin, hesaplanan zaman aralığını bekleyin, bir isabet kaydedin.

İkinci dereceden denklem için sözde kod:

Vector totarget =  target.position - tower.position;

float a = Vector.Dot(target.velocity, target.velocity) - (bullet.velocity * bullet.velocity);
float b = 2 * Vector.Dot(target.velocity, totarget);
float c = Vector.Dot(totarget, totarget);

float p = -b / (2 * a);
float q = (float)Math.Sqrt((b * b) - 4 * a * c) / (2 * a);

float t1 = p - q;
float t2 = p + q;
float t;

if (t1 > t2 && t2 > 0)
{
    t = t2;
}
else
{
    t = t1;
}

Vector aimSpot = target.position + target.velocity * t;
Vector bulletPath = aimSpot - tower.position;
float timeToImpact = bulletPath.Length() / bullet.speed;//speed must be in units per second

Sahte kod için teşekkürler, ikinci dereceden denklemin bu durumla nasıl çalıştığını görmek için kontrol edeceğim. Tekrar teşekkürler.
Tashu

Sorun, kullanıcının mermiye doğru hareket edebilmesi ve vurmadan hemen önce merminin izinden uzaklaşabilmesidir. Bu durumda, bu çözüm yeterince iyi olur mu?
Martin.

Hayır, ilk cümlede olduğu gibi. Bu, tüm oyunlar için değil, hedeflerin yalnızca sabit bir hızda hareket ettiği bir oyun içindir. Sabit hız hem yön hem de hız anlamına gelir. Örneğin, Savunma Izgara tarzı oyun oyunu bu yaklaşımı kullanabilirsiniz.
Steve H

3

Merminin ulaşacağı zamana kadar nesnelerin konumunu 'tahmin etmeniz' gerekir. Bunu, hız / hız (umarım bu sabit;)) nesnelerini ve yön vektörünü kullanarak yapabilirsiniz.

Tam formülün kafamın üstünde ne olduğundan emin değilim ama bunun böyle bir şey olduğunu düşünüyorum:

NewPosition = OldPosition + (Hız * DirectionVector);

Ayarlanmış bir yolunuz varsa, nesnenin yönü değiştiğinde yeniden hesaplamanız gerekir. Bu NewPosition'ı düşmanınız olarak kullanın. Konum vektörü ve madde işareti 'hedef arama efekti' olmadan nesneye çarpmalıdır. Hedef arama, düşman vektörünün orijinal vektör hesaplandığından beri hareket etmesi nedeniyle oluşur, ancak bir nesne yeterince uzun bir yönde seyahat ettiğinde yakalanabilir.

Bu yardımcı olur umarım :)


3
Ya da hile yapabilir ve otomatik olarak vurabilir, ardından hareketli hareketli grafiği görsel geri bildirim olarak kullanabilirsiniz. Veya sadece mermilerinizi 50000²mph'de ateşleyin.
Jonathan Connell

1

Karekök ve 2 gücünü kullanmaktan kaçınabilirsiniz.

var distX:Float = target.x - x;
var distY:Float = target.y - y;
_velX = distX / timeTravel;
_velY = distY / timeTravel;

// Take out if you want a nice slow down as approaches effect.  
timeTravel -= 1.0; // make sure u have a positive timeTravel.
x += _velX;
y += _velY;

if (distX < 0)
    distX = -distX;

if (distY < 0)
    distY = -distY;

if (_velX < 0)
    _velX = -_velX;

if (_velY < 0)
    _velY = -_velY;

// Should both snap @ the same time.
if (distX < _velX)
x = target.x; // snap & see what happens.

if (distY < _velY)
y = target.y; // snap & see what happens.

// TODO: call your onHitTarget here ...
// Hopefully this shall provide 10x the performance 
// of using Math.sqrt and all the extra multiplications.

Her şey bellekten yazılmıştır. Bu arada, çalışan öğeleri kullanın - bu konuda yeniyseniz satır satır test edin. Şamandıra AS3'te Sayıdır.

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.