Tôi đang xây dựng một trò chơi khám phá không gian và hiện tại tôi đã bắt đầu làm việc về trọng lực (Trong C # với XNA).
Trọng lực vẫn cần điều chỉnh, nhưng trước khi tôi có thể làm điều đó, tôi cần giải quyết một số vấn đề về hiệu suất với các tính toán vật lý của mình.
Điều này đang sử dụng 100 đối tượng, thông thường kết xuất 1000 trong số chúng không có tính toán vật lý nào đạt được hơn 300 FPS (đó là giới hạn FPS của tôi), nhưng bất kỳ hơn 10 đối tượng nào cũng mang trò chơi (và một luồng duy nhất mà nó chạy) đến đầu gối khi làm tính toán vật lý.
Tôi đã kiểm tra việc sử dụng luồng của mình và luồng đầu tiên tự giết mình khỏi tất cả các công việc, vì vậy tôi đoán rằng tôi chỉ cần thực hiện phép tính vật lý trên một luồng khác. Tuy nhiên, khi tôi cố chạy phương thức Cập nhật của lớp Gravity.cs trên một luồng khác, ngay cả khi phương thức Cập nhật của Gravity không có gì trong đó, trò chơi vẫn giảm xuống còn 2 FPS.
Trọng lực.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;
}
}
Vâng, tôi biết. Đó là một vòng lặp foreach lồng nhau, nhưng tôi không biết làm thế nào khác để tính toán trọng lực, và điều này dường như hoạt động, nó chỉ chuyên sâu đến mức nó cần chủ đề riêng của nó. (Ngay cả khi ai đó biết một cách siêu hiệu quả để thực hiện các phép tính này, tôi vẫn muốn biết làm thế nào tôi CÓ THỂ làm điều đó trên nhiều luồng thay thế)
EntityEngine.cs (quản lý một thể hiện của 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 được tạo trong Game1.cs và phương thức Update () của nó được gọi trong Game1.cs.
Tôi cần tính toán vật lý của mình trong Gravity.cs để chạy mỗi khi trò chơi cập nhật, trong một luồng riêng biệt để phép tính không làm chậm trò chơi xuống mức FPS khủng khiếp (0-2).
Làm thế nào tôi sẽ đi về làm cho luồng này hoạt động? (mọi đề xuất cho hệ thống Trọng lực hành tinh được cải thiện đều được hoan nghênh nếu có ai có chúng)
Tôi cũng không tìm kiếm một bài học về lý do tại sao tôi không nên sử dụng luồng hoặc sự nguy hiểm của việc sử dụng nó không chính xác, tôi đang tìm kiếm một câu trả lời thẳng về cách thực hiện. Tôi đã dành một giờ để googling câu hỏi này với rất ít kết quả mà tôi hiểu hoặc hữu ích. Tôi không có ý tỏ ra thô lỗ, nhưng dường như rất khó để một người lập trình nhận được câu trả lời có ý nghĩa thẳng, tôi thường nhận được một câu trả lời phức tạp đến mức tôi có thể dễ dàng giải quyết vấn đề của mình nếu tôi hiểu nó, hoặc ai đó nói lý do tại sao tôi không nên làm những gì tôi muốn làm và không đưa ra giải pháp thay thế nào (điều đó hữu ích).
Cảm ơn bạn vì sự giúp đỡ!
EDIT : Sau khi đọc câu trả lời tôi đã nhận được, tôi thấy rằng các bạn thực sự quan tâm và không chỉ cố gắng đưa ra một câu trả lời có thể có hiệu quả. Tôi muốn giết hai con chim bằng một viên đá (cải thiện hiệu suất và học một số điều cơ bản về đa luồng), nhưng có vẻ như hầu hết vấn đề nằm ở tính toán của tôi và việc xâu chuỗi rắc rối hơn so với việc tăng hiệu suất. Cảm ơn tất cả các bạn, tôi sẽ đọc lại câu trả lời của bạn và thử các giải pháp của bạn khi tôi hoàn thành việc học, Cảm ơn một lần nữa!
k
này O(n^2)
rất nhiều.
sin² + cos² ≡ 1
dù sao nó cũng đã được chuẩn hóa! Bạn chỉ có thể sử dụng vectơ gốc kết nối hai đối tượng bạn quan tâm và chuẩn hóa đối tượng này. Không có cuộc gọi trig nào cần thiết.