Sto costruendo un gioco di esplorazione dello spazio e attualmente ho iniziato a lavorare sulla gravità (in C # con XNA).
La gravità deve ancora essere modificata, ma prima di poterlo fare, devo affrontare alcuni problemi di prestazioni con i miei calcoli di fisica.
Questo utilizza 100 oggetti, di solito il rendering di 1000 di essi senza calcoli fisici supera i 300 FPS (che è il mio limite FPS), ma non più di 10 oggetti portano il gioco (e il singolo thread su cui gira) al suo ginocchia quando si eseguono calcoli di fisica.
Ho controllato il mio utilizzo del thread e il primo thread si stava uccidendo da tutto il lavoro, quindi ho pensato che dovevo solo fare il calcolo della fisica su un altro thread. Tuttavia, quando provo a eseguire il metodo di aggiornamento della classe Gravity.cs su un altro thread, anche se il metodo di aggiornamento di Gravity non contiene nulla, il gioco è ancora ridotto 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 so. È un ciclo foreach nidificato, ma non so come altro fare il calcolo della gravità, e questo sembra funzionare, è così intenso che ha bisogno del suo thread. (Anche se qualcuno conosce un modo super efficiente di fare questi calcoli, mi piacerebbe comunque sapere come avrei potuto farlo su più thread)
EntityEngine.cs (gestisce un'istanza di 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 viene creato in Game1.cs e il suo metodo Update () viene chiamato in Game1.cs.
Ho bisogno che il mio calcolo della fisica in Gravity.cs venga eseguito ogni volta che il gioco si aggiorna, in un thread separato in modo che il calcolo non rallenti il gioco fino a un FPS orribilmente basso (0-2).
Come potrei fare per far funzionare questo threading? (eventuali suggerimenti per un sistema planetario a gravità migliorato sono ben accetti se qualcuno li possiede)
Inoltre non sto cercando una lezione sul perché non dovrei usare il threading o i pericoli di usarlo in modo errato, sto cercando una risposta diretta su come farlo. Ho già trascorso un'ora a cercare su Google questa domanda con pochi risultati che ho capito o che sono stati utili. Non intendo venire fuori maleducato, ma sembra sempre difficile come un noob programmatore ottenere una risposta chiara e significativa, di solito preferisco una risposta così complessa che potrei facilmente risolvere il mio problema se lo capissi, o qualcuno che dice perché non dovrei fare quello che voglio fare e non offre alternative (che sono utili).
Grazie per l'aiuto!
EDIT : Dopo aver letto le risposte che ho ricevuto, vedo che a voi ragazzi importa davvero e non state solo cercando di trovare una risposta che potrebbe funzionare. Volevo uccidere due uccelli con una fava (migliorare le prestazioni e apprendere alcune nozioni di base sul multlthreading), ma sembra che la maggior parte del problema risieda nei miei calcoli e che il threading sia più fastidioso di quanto valga per gli aumenti delle prestazioni. Grazie a tutti, rileggerò di nuovo le vostre risposte e proverò le vostre soluzioni quando avrò finito la scuola, grazie ancora!
k
questo O(n^2)
problema.
sin² + cos² ≡ 1
che è già normalizzato comunque! Avresti potuto semplicemente usare il vettore originale che collega i due oggetti che ti interessano e normalizzare questo. Non sono necessarie chiamate di emergenza.