我正在开发一个太空探索游戏,目前我已经开始研究重力(在XNA的C#中)。
重力仍然需要调整,但是在我能够做到这一点之前,我需要在物理计算中解决一些性能问题。
这使用了100个对象,通常不进行物理计算就可以渲染其中的1000个对象,而FPS则超过300 FPS(这是我的FPS上限),但是超过10个左右的对象会将游戏(及其运行的单线程)带入在进行物理计算时会屈膝。
我检查了我的线程使用情况,发现第一个线程正在杀死所有工作,因此我认为只需要对另一个线程进行物理计算即可。但是,当我尝试在另一个线程上运行Gravity.cs类的Update方法时,即使Gravity的Update方法中没有任何内容,游戏仍然会降低到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。
我将如何使该线程工作?(如果有人提出任何关于改进行星重力系统的建议,则欢迎)
我也不是在寻找为什么不应该使用线程或不正确使用线程的危险的教训,我正在寻找一个直接的答案。我已经花了一个小时来研究这个问题,但我了解或帮助的结果很少。我并不是要粗鲁无礼,但是作为编程新手总是很难获得一个有意义的直接答案,我通常宁愿得到一个如此复杂的答案,如果我理解了它,很容易就能解决我的问题,或者有人说为什么我不应该做我想做的事情,并且没有提供其他选择(很有帮助)。
感谢您的帮助!
编辑:阅读完我得到的答案后,我看到你们真的在乎,而不仅仅是试图给出可能有用的答案。我想用一块石头杀死两只鸟(提高性能并学习多线程的一些基础知识),但是似乎大多数问题出在我的计算上,而且线程多麻烦,而不是提高性能值得。谢谢大家,在我完成学业后,我将再次阅读您的答案,并尝试您的解决方案,再次感谢!
k
此O(n^2)
问题的产生。
sin² + cos² ≡ 1
它已经被归一化了!您可能只是使用了将两个感兴趣的对象连接起来的原始向量,并对其进行了标准化。无需任何触发电话。