Saya sedang membangun game eksplorasi ruang angkasa dan saya saat ini mulai mengerjakan gravitasi (In C # with XNA).
Gravitasi masih perlu diubah, tetapi sebelum saya bisa melakukan itu, saya perlu mengatasi beberapa masalah kinerja dengan perhitungan fisika saya.
Ini menggunakan 100 objek, biasanya menghasilkan 1000 dari mereka tanpa perhitungan fisika mendapatkan lebih dari 300 FPS (yang merupakan batas FPS saya), tetapi lebih dari 10 atau lebih objek membawa game (dan satu utas berjalan) untuk itu berlutut saat melakukan perhitungan fisika.
Saya memeriksa penggunaan utas saya dan utas pertama mematikan sendiri dari semua pekerjaan, jadi saya pikir saya hanya perlu melakukan perhitungan fisika pada utas lain. Namun ketika saya mencoba menjalankan metode Pembaruan kelas Gravity.cs di utas lain, bahkan jika metode Pembaruan Gravity tidak memiliki apa pun di dalamnya, permainan masih turun menjadi 2 FPS.
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;
}
}
Ya aku tahu. Itu adalah loop foreach bersarang, tapi saya tidak tahu bagaimana lagi melakukan perhitungan gravitasi, dan ini tampaknya berhasil, itu hanya begitu intensif sehingga perlu utas sendiri. (Bahkan jika seseorang tahu cara super efisien untuk melakukan perhitungan ini, saya masih ingin tahu bagaimana saya BISA melakukannya pada banyak utas sebagai gantinya)
EntityEngine.cs (mengelola instance dari Gravity.cs)
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 dibuat di Game1.cs, dan metode Pembaruan () disebut di dalam Game1.cs.
Saya membutuhkan perhitungan fisika saya di Gravity.cs untuk menjalankan setiap kali pembaruan game, di utas terpisah sehingga perhitungan tidak memperlambat permainan ke FPS yang sangat rendah (0-2).
Bagaimana cara saya membuat karya threading ini? (setiap saran untuk sistem Gravitasi Planet yang ditingkatkan dipersilahkan jika ada yang memilikinya)
Saya juga tidak mencari pelajaran mengapa saya tidak boleh menggunakan threading atau bahaya menggunakannya secara tidak benar, saya mencari jawaban langsung tentang bagaimana melakukannya. Saya sudah menghabiskan satu jam mencari pertanyaan ini dengan sedikit hasil yang saya mengerti atau sangat membantu. Saya tidak bermaksud kasar, tetapi selalu tampak sulit sebagai pemrograman noob untuk mendapatkan jawaban yang bermakna langsung, saya biasanya lebih suka mendapatkan jawaban yang begitu rumit sehingga saya bisa dengan mudah menyelesaikan masalah saya jika saya memahaminya, atau seseorang mengatakan mengapa saya tidak harus melakukan apa yang ingin saya lakukan dan tidak menawarkan alternatif (yang membantu).
Terima kasih atas bantuannya!
EDIT : Setelah membaca jawaban yang saya dapatkan, saya melihat bahwa kalian benar-benar peduli dan tidak hanya mencoba memuntahkan jawaban yang mungkin berhasil. Saya ingin membunuh dua burung dengan satu batu (meningkatkan kinerja dan mempelajari beberapa dasar-dasar multlebar), tetapi tampaknya sebagian besar masalahnya terletak pada perhitungan saya dan bahwa threading lebih merepotkan daripada layak untuk peningkatan kinerja. Terima kasih semua, saya akan membaca jawaban Anda lagi dan mencoba solusi Anda ketika saya selesai dengan sekolah, Terima kasih lagi!
k
ini O(n^2)
.
sin² + cos² ≡ 1
itu sudah dinormalisasi pula! Anda bisa saja menggunakan vektor asli yang menghubungkan dua objek yang Anda minati, dan menormalkan yang ini. Tidak ada panggilan panggilan apa pun yang diperlukan.