Estoy construyendo un juego de exploración espacial y actualmente he comenzado a trabajar en la gravedad (en C # con XNA).
La gravedad aún necesita ajustes, pero antes de que pueda hacer eso, necesito abordar algunos problemas de rendimiento con mis cálculos físicos.
Esto está usando 100 objetos, normalmente representando 1000 de ellos sin cálculos físicos, supera los 300 FPS (que es mi límite de FPS), pero con más de 10 objetos trae el juego (y el hilo único en el que se ejecuta) a su rodillas al hacer cálculos físicos.
Verifiqué el uso de mi hilo y el primer hilo se estaba matando a sí mismo por todo el trabajo, así que pensé que solo necesitaba hacer el cálculo físico en otro hilo. Sin embargo, cuando trato de ejecutar el método de actualización de la clase Gravity.cs en otro hilo, incluso si el método de actualización de Gravity no contiene nada, el juego aún se reduce a 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;
}
}
Si lo se. Es un bucle foreach anidado, pero no sé cómo hacer el cálculo de la gravedad, y esto parece funcionar, es tan intenso que necesita su propio hilo. (Incluso si alguien conoce una forma súper eficiente de hacer estos cálculos, aún me gustaría saber cómo PODRÍA hacerlo en múltiples hilos)
EntityEngine.cs (administra una instancia de 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 se crea en Game1.cs, y su método Update () se llama dentro de Game1.cs.
Necesito que mi cálculo de física en Gravity.cs se ejecute cada vez que se actualiza el juego, en un hilo separado para que el cálculo no ralentice el juego a FPS horriblemente bajo (0-2).
¿Cómo haría para que este hilo funcione? (cualquier sugerencia para un sistema de gravedad planetaria mejorado es bienvenida si alguien los tiene)
Tampoco estoy buscando una lección de por qué no debería usar el enhebrado o los peligros de usarlo incorrectamente, estoy buscando una respuesta directa sobre cómo hacerlo. Ya pasé una hora buscando en Google esta misma pregunta con pocos resultados que entendí o que fueron útiles. No quiero decir que sea grosero, pero siempre parece difícil como un novato en programación obtener una respuesta directa y significativa, por lo general prefiero obtener una respuesta tan compleja que fácilmente podría resolver mi problema si lo entendiera, o alguien diciendo por qué no debería hacer lo que quiero hacer y sin ofrecer alternativas (que son útiles).
¡Gracias por la ayuda!
EDITAR : Después de leer las respuestas que he recibido, veo que a ustedes realmente les importa y no solo están tratando de decir una respuesta que podría funcionar. Quería matar dos pájaros de un tiro (mejorando el rendimiento y aprendiendo algunos conceptos básicos de subprocesos múltiples), pero parece que la mayor parte del problema radica en mis cálculos y que enhebrar es más complicado de lo que vale para aumentar el rendimiento. Gracias a todos, volveré a leer sus respuestas y probaré sus soluciones cuando termine la escuela. ¡Gracias de nuevo!
k
de este O(n^2)
problema mucho.
sin² + cos² ≡ 1
ya está normalizado de todos modos! Podría haber utilizado el vector original que conecta los dos objetos que le interesan y normalizar este. No se necesitan llamadas trigonométricas.