Birbirine yönelen çeşitli boyut ve hızda nesnelerim var. Her güncellemede, her nesnenin üzerinden geçip, diğer tüm nesnelerin ağırlıklarından dolayı kuvvetler eklemeliyim. Çok iyi ölçeklenemiyor, oyunumda bulduğum iki büyük darboğazdan biri ve performansı geliştirmek için ne yapacağımdan emin değilim.
O hissediyor Ben performansını artırmak gerekir gibi. Herhangi bir zamanda, sistemdeki nesnelerin muhtemelen% 99'u yalnızca bir nesne üzerinde ihmal edilebilir bir etkiye sahip olacaktır. Tabii ki, nesneleri kütleye göre sıralayamıyorum ve sadece en büyük 10 nesneyi düşünmüyorum, çünkü kuvvet mesafe ile kütleye göre değişir (denklem çizgileri boyuncadır force = mass1 * mass2 / distance^2
). Bence , dünyanın diğer tarafında yüzlerce küçük kaya parçasını göz ardı ederek, muhtemelen hiçbir şeyi etkileyemeyen en büyük nesneleri ve en yakın nesneleri göz önünde bulundurmak iyi bir yaklaşım olacaktır. En yakın ben üzerinde yinelemek zorunda tüm nesneleri ve onların pozisyonları değişiyor sürekli, bu yüzden sadece bir kere yapabilirim gibi değil.
Şu anda böyle bir şey yapıyorum:
private void UpdateBodies(List<GravitatingObject> bodies, GameTime gameTime)
{
for (int i = 0; i < bodies.Count; i++)
{
bodies[i].Update(i);
}
}
//...
public virtual void Update(int systemIndex)
{
for (int i = systemIndex + 1; i < system.MassiveBodies.Count; i++)
{
GravitatingObject body = system.MassiveBodies[i];
Vector2 force = Gravity.ForceUnderGravity(body, this);
ForceOfGravity += force;
body.ForceOfGravity += -force;
}
Vector2 acceleration = Motion.Acceleration(ForceOfGravity, Mass);
ForceOfGravity = Vector2.Zero;
Velocity += Motion.Velocity(acceleration, elapsedTime);
Position += Motion.Position(Velocity, elapsedTime);
}
(Çok fazla kod kaldırdığımı unutmayın - örneğin çarpışma testleri, çarpışmaları algılamak için nesneler üzerinde ikinci kez yineleme yapmam).
Bu yüzden her zaman tüm listeyi yinelemiyorum - bunu yalnızca ilk nesne için yapıyorum ve nesne her zaman başka bir nesneye doğru hissettiği kuvveti bulduğunda, diğer nesnenin de aynı kuvveti hissettiğini, bu yüzden sadece her ikisini de güncelliyor onlar - ve sonra ilk nesnenin güncellemenin geri kalanında tekrar düşünülmesi gerekmez.
Gravity.ForceUnderGravity(...)
Ve Motion.Velocity(...)
vb fonksiyonlar sadece XNA en vektör matematik inşa biraz kullanabilirsiniz.
İki nesne çarpıştığında, kütlesiz enkaz oluştururlar. Ayrı bir listede tutulur ve büyük nesneler, hız hesaplamalarının bir parçası olarak enkaz üzerinde yinelenmez, ancak her enkaz parçası, büyük parçacıkların üzerinde yinelenmelidir.
Bunun inanılmaz sınırlara ölçeklendirilmesi gerekmez. Dünya sınırsız değil, sınırlarını aşan nesneleri yok eden bir sınır içeriyor - belki binlerce nesneyi ele alabilmeyi istiyorum, şu anda oyun 200 civarında boğulmaya başlıyor.
Bunu nasıl geliştirebileceğime dair bir fikrin var mı? Bazı sezgisel döngü uzunluğunu yüzlercedan birkaçına kadar tıraş etmek için kullanabilir miyim? Bazı kodlar her güncellemeden daha az sıklıkta çalıştırabilir mi? İyi bir büyüklükteki dünyaya izin verecek kadar hızlı oluncaya kadar birden fazla okutmalı mıyım? Hız hesaplamalarını GPU'ya yüklemeyi denemeli miyim? Eğer öyleyse, bunu nasıl mimarlık ederdim? GPU'da statik ve paylaşılan verileri saklayabilir miyim? GPU'da HLSL işlevleri oluşturabilir ve bunları keyfi olarak (XNA kullanarak) çağırabilir miyim yoksa çizim işleminin bir parçası mı olmak zorundalar?
G * m1 * m2 / r^2
G'nin davranışı değiştireceği yer. (sadece bir yolu izlememelerine rağmen, kullanıcı sistemi rahatsız edebildiğinden dolayı)