Bir uzay keşif oyunu inşa ediyorum ve şu anda yerçekimi üzerinde çalışmaya başladım (XNA ile C # da).
Yerçekimi hala ince ayarlamaya ihtiyaç duyuyor, ancak bunu yapmadan önce fizik hesaplamalarımla bazı performans konularına değinmem gerekiyor.
Bu, 100 nesneyi kullanıyor, normalde 1000'i fizik hesaplaması olmadan yapıyor, 300 FPS'den (FPS kapağımın) çok iyi alıyor, ancak 10'dan fazla nesne, oyunu (ve çalıştığı tek iş parçacığını) kendine getiriyor. Fizik hesaplamaları yaparken diz çöküyor.
İplik kullanımımı kontrol ettim ve ilk iş parçacığı tüm işten kendini öldürüyordu, bu yüzden başka bir iş parçacığı üzerinde fizik hesaplaması yapmam gerektiğini düşündüm. Ancak Gravity.cs sınıfının Update yöntemini başka bir iş parçacığında çalıştırmaya çalıştığımda, Gravity'nin Güncelleme yöntemi içinde hiçbir şey olmasa da, oyun hala 2 FPS'ye düştü.
Gravity.cs
public void Update()
{
foreach (KeyValuePair<string, Entity> e in entityEngine.Entities)
{
Vector2 Force = new Vector2();
foreach (KeyValuePair<string, Entity> e2 in entityEngine.Entities)
{
if (e2.Key != e.Key)
{
float distance = Vector2.Distance(entityEngine.Entities[e.Key].Position, entityEngine.Entities[e2.Key].Position);
if (distance > (entityEngine.Entities[e.Key].Texture.Width / 2 + entityEngine.Entities[e2.Key].Texture.Width / 2))
{
double angle = Math.Atan2(entityEngine.Entities[e2.Key].Position.Y - entityEngine.Entities[e.Key].Position.Y, entityEngine.Entities[e2.Key].Position.X - entityEngine.Entities[e.Key].Position.X);
float mult = 0.1f *
(entityEngine.Entities[e.Key].Mass * entityEngine.Entities[e2.Key].Mass) / distance * distance;
Vector2 VecForce = new Vector2((float)Math.Cos(angle), (float)Math.Sin(angle));
VecForce.Normalize();
Force = Vector2.Add(Force, VecForce * mult);
}
}
}
entityEngine.Entities[e.Key].Position += Force;
}
}
Evet biliyorum. İç içe geçmiş bir foreach döngüsü, ancak yerçekimi hesaplamasını başka nasıl yapacağımı bilmiyorum ve bu işe yarıyor, kendi dişine ihtiyacı olacak kadar yoğun. (Birisi bu hesaplamaları yapmanın süper etkili bir yolunu bilse bile, hala bunun yerine nasıl birden fazla iş parçacığında yapabileceğimi bilmek istiyorum.)
EntityEngine.cs (Gravity.cs örneğini yönetir)
public class EntityEngine
{
public Dictionary<string, Entity> Entities = new Dictionary<string, Entity>();
public Gravity gravity;
private Thread T;
public EntityEngine()
{
gravity = new Gravity(this);
}
public void Update()
{
foreach (KeyValuePair<string, Entity> e in Entities)
{
Entities[e.Key].Update();
}
T = new Thread(new ThreadStart(gravity.Update));
T.IsBackground = true;
T.Start();
}
}
EntityEngine, Game1.cs içinde oluşturulur ve Update () yöntemi Game1.cs içinde çağrılır.
Oyunun her güncellemesinde ayrı bir iş parçacığında çalıştırmak için Gravity.cs'deki fizik hesaplamama ihtiyacım var, böylece hesaplama oyunu yavaş yavaş düşürecek kadar düşük (0-2) FPS.
Bu iş parçacığı iş yapmak hakkında nasıl giderim? (Geliştirilmiş bir Planet Gravity sistemi için herhangi bir öneriniz varsa, bunlara sahipse memnuniyetle karşılanır)
Ayrıca iş parçacığını neden kullanmamam gerektiği ya da yanlış kullanmanın tehlikeleri hakkında bir ders aramıyorum, nasıl yapılacağına dair kesin bir cevap arıyorum. Zaten anladığım veya yardımcı olduğum ufak sonuçlarla bu soruyu googling yaparak bir saat geçirdim. Kaba çıkmayı kastetmiyorum, ama her zaman düz anlamlı bir cevap almak için bir programlama noob olarak zor gözüküyor, genellikle çok karmaşık bir cevap almayı tercih ederim; Birisi neden yapmak istediğimi yapmamam gerektiğini söyleyen ve alternatif sunamayan biri (yardımcı olur).
Yardım için teşekkürler!
EDIT : Aldığım cevapları okuduktan sonra, sizin gerçekten umursadığınızı ve işe yarayabilecek bir cevabı dağıtmaya çalışmadığınızı görüyorum. İki taşı bir taşla öldürmek istedim (performansı arttırmak ve çok yönlülüğün temellerini öğrenmek), ancak sorunumun çoğunun hesaplamalarımda yattığı ve diş açmanın performans artışları için değerinden daha zor olduğu anlaşılıyor. Hepinize teşekkür ederim, cevaplarınızı tekrar okuyacağım ve okulum bittiğinde çözümlerinizi deneyeceğim, Tekrar teşekkürler!
k
, bu O(n^2)
problemi çok azaltacaktır .
sin² + cos² ≡ 1
zaten zaten normalize olduğundan! İlgilendiğiniz iki nesneyi birbirine bağlayan orijinal vektörü kullanabilir ve bunu normalleştirebilirsiniz. Hiçbir trig, ihtiyaç duyulanı çağırmaz.