ฉันกำลังสร้างเกมสำรวจอวกาศและตอนนี้ฉันเริ่มทำงานกับแรงโน้มถ่วง (ใน C # กับ XNA)
แรงโน้มถ่วงยังคงต้องการการปรับแต่ง แต่ก่อนที่ฉันจะทำได้ฉันต้องจัดการกับปัญหาด้านประสิทธิภาพด้วยการคำนวณทางฟิสิกส์ของฉัน
นี่คือการใช้วัตถุ 100 รายการโดยปกติแล้วการแสดงผล 1,000 รายการโดยไม่มีการคำนวณทางฟิสิกส์ได้ดีกว่า 300 FPS (ซึ่งเป็นฝา FPS ของฉัน) แต่วัตถุใด ๆ ที่มากกว่า 10 หรือมากกว่านั้นจะนำเกมมาด้วย เข่าเมื่อทำการคำนวณทางฟิสิกส์
ฉันตรวจสอบการใช้เธรดของฉันและเธรดแรกกำลังฆ่าตัวเองจากงานทั้งหมดดังนั้นฉันจึงคิดว่าฉันต้องทำการคำนวณทางฟิสิกส์ในเธรดอื่น อย่างไรก็ตามเมื่อฉันพยายามเรียกใช้เมธอดการอัปเดตของคลาส Gravity.cs ในเธรดอื่นแม้ว่าเมธอดการอัปเดตของ Gravity จะไม่มีอะไรอยู่เกมยังคงลดเหลือ 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;
}
}
ใช่ฉันรู้. มันเป็นลูป foreach วนซ้อนกัน แต่ฉันไม่รู้วิธีอื่นในการคำนวณแรงโน้มถ่วงและดูเหมือนว่ามันจะทำงานได้มันเข้มข้นมากจนมันต้องมีเธรดของตัวเอง (แม้ว่าใครจะรู้วิธีที่มีประสิทธิภาพสูงสุดในการคำนวณเหล่านี้ฉันก็ยังอยากรู้ว่าฉันสามารถทำมันในหลาย ๆ กระทู้แทน)
EntityEngine.cs (จัดการอินสแตนซ์ของ 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 ถูกสร้างขึ้นใน Game1.cs และวิธีการ Update () นั้นเรียกว่าภายใน Game1.cs
ฉันต้องการการคำนวณทางฟิสิกส์ใน Gravity.cs เพื่อให้ทำงานทุกครั้งที่มีการอัปเดตเกมในเธรดแยกต่างหากเพื่อให้การคำนวณไม่ทำให้เกมช้าลงจนเหลือน้อยมาก (0-2) FPS
ฉันจะดำเนินการเกี่ยวกับการทำเกลียวนี้อย่างไร (คำแนะนำใด ๆ สำหรับระบบแรงโน้มถ่วงของดาวเคราะห์ที่ได้รับการปรับปรุงจะยินดีต้อนรับถ้ามีใคร)
ฉันยังไม่ได้มองหาบทเรียนเพราะเหตุใดฉันจึงไม่ควรใช้การทำเกลียวหรืออันตรายจากการใช้อย่างไม่ถูกต้องฉันกำลังมองหาคำตอบที่ตรงไปตรงมาเกี่ยวกับวิธีการทำ ฉันใช้เวลาไปหนึ่งชั่วโมงกับคำถามนี้มากกับผลลัพธ์เล็ก ๆ น้อย ๆ ที่ฉันเข้าใจหรือมีประโยชน์ ฉันไม่ได้ตั้งใจออกมาหยาบคาย แต่มันก็ยากที่จะเขียนโปรแกรม noob เพื่อให้ได้คำตอบที่มีความหมายฉันมักจะได้คำตอบที่ซับซ้อนดังนั้นฉันจึงสามารถแก้ไขปัญหาของฉันได้ง่ายถ้าฉันเข้าใจหรือ บางคนบอกว่าทำไมฉันไม่ควรทำในสิ่งที่ฉันต้องการจะทำและไม่เสนอทางเลือกอื่น (มีประโยชน์)
ขอขอบคุณสำหรับความช่วยเหลือ!
แก้ไข : หลังจากอ่านคำตอบที่ฉันได้รับฉันเห็นว่าพวกคุณสนใจจริง ๆ และไม่เพียง แต่พยายามที่จะคายคำตอบที่อาจใช้งานได้ ฉันต้องการฆ่านกสองตัวด้วยหินก้อนเดียว (ปรับปรุงประสิทธิภาพและเรียนรู้พื้นฐานบางอย่างของการมัลติเธรด) แต่ดูเหมือนว่าปัญหาส่วนใหญ่อยู่ในการคำนวณของฉันและเกลียวนั้นยุ่งยากกว่าการเพิ่มประสิทธิภาพการทำงาน ขอบคุณทุกคนฉันจะอ่านคำตอบของคุณอีกครั้งและลองวิธีแก้ปัญหาของคุณเมื่อฉันทำกับโรงเรียนขอบคุณอีกครั้ง!
k
นี้ได้O(n^2)
มาก
sin² + cos² ≡ 1
มันถูกทำให้เป็นมาตรฐานอยู่แล้ว! คุณสามารถใช้เวกเตอร์ดั้งเดิมที่เชื่อมวัตถุสองตัวที่คุณสนใจและทำให้วัตถุนี้เป็นปกติ ไม่มีการเรียกตรีโกณมิติใด ๆ ที่จำเป็น