Je suis en train de construire un jeu d'exploration spatiale et j'ai actuellement commencé à travailler sur la gravité (en C # avec XNA).
La gravité doit encore être modifiée, mais avant de pouvoir le faire, je dois résoudre certains problèmes de performances avec mes calculs physiques.
Cela utilise 100 objets, ce qui rend normalement 1000 d'entre eux sans calculs physiques dépasse bien 300 FPS (ce qui est mon plafond FPS), mais plus de 10 objets environ amènent le jeu (et le seul thread sur lequel il s'exécute) à son genoux lors des calculs de physique.
J'ai vérifié l'utilisation de mon fil et le premier fil se tuait de tout le travail, alors j'ai pensé que je devais juste faire le calcul physique sur un autre fil. Cependant, lorsque j'essaie d'exécuter la méthode Update de la classe Gravity.cs sur un autre thread, même si la méthode Update de Gravity n'a rien dedans, le jeu est toujours à 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;
}
}
Ouais je sais. C'est une boucle imbriquée foreach, mais je ne sais pas comment faire le calcul de la gravité, et cela semble fonctionner, c'est tellement intensif qu'il a besoin de son propre thread. (Même si quelqu'un connaît un moyen super efficace de faire ces calculs, j'aimerais quand même savoir comment je pourrais le faire sur plusieurs threads à la place)
EntityEngine.cs (gère une instance 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 est créé dans Game1.cs et sa méthode Update () est appelée dans Game1.cs.
J'ai besoin que mon calcul physique dans Gravity.cs s'exécute à chaque fois que le jeu est mis à jour, dans un thread séparé afin que le calcul ne ralentisse pas le jeu à un niveau horriblement bas (0-2) FPS.
Comment pourrais-je faire fonctionner ce filetage? (toutes les suggestions pour un système de gravité planétaire amélioré sont les bienvenues si quelqu'un les a)
Je ne cherche pas non plus une leçon sur la raison pour laquelle je ne devrais pas utiliser le filetage ou les dangers de l'utiliser de manière incorrecte, je cherche une réponse directe sur la façon de le faire. J'ai déjà passé une heure à googler cette question avec peu de résultats que j'ai compris ou qui m'ont été utiles. Je ne veux pas me montrer grossier, mais il semble toujours difficile en tant que noob de programmation d'obtenir une réponse directe et significative, je préfère généralement obtenir une réponse si complexe que je serais facilement en mesure de résoudre mon problème si je le comprenais, ou quelqu'un disant pourquoi je ne devrais pas faire ce que je veux faire et n'offrant aucune alternative (qui est utile).
Merci pour l'aide!
EDIT : Après avoir lu les réponses que j'ai obtenues, je vois que vous vous souciez vraiment et n'essayez pas simplement de cracher une réponse qui pourrait fonctionner. Je voulais tuer deux oiseaux avec une pierre (améliorer les performances et apprendre certaines bases du multlthreading), mais il semble que la plupart du problème réside dans mes calculs et que le filetage soit plus compliqué que cela ne vaut pour les augmentations de performances. Merci à tous, je vais relire vos réponses et essayer vos solutions quand j'aurai fini l'école, merci encore!
k
de ce O(n^2)
problème beaucoup.
sin² + cos² ≡ 1
est déjà normalisé de toute façon! Vous auriez pu simplement utiliser le vecteur d'origine qui relie les deux objets qui vous intéressent et normaliser celui-ci. Aucun appel trig n'est nécessaire.