Я будую гру з дослідження космосу, і в даний час я почав працювати над гравітацією (в C # з XNA).
Сила тяжіння все ще потребує налаштування, але перш ніж я можу це зробити, мені потрібно вирішити деякі проблеми з моїми фізичними розрахунками.
Для цього використовується 100 об'єктів, звичайно рендерінг 1000 з них без фізичних обчислень отримує понад 300 FPS (що є моєю кришкою FPS), але будь-які об'єкти більше 10 або більше приносять гру (та одну нитку, на якій вона працює) до своєї коліна при виконанні фізичних розрахунків.
Я перевірив моє використання потоку, і перший потік вбивав себе від усієї роботи, тому я зрозумів, що мені просто потрібно зробити розрахунок фізики на іншій нитці. Однак, коли я намагаюся запустити метод оновлення класу Gravity.cs на інший потік, навіть якщо в методі оновлення Gravity немає нічого, гра все ще знижується до 2 FPS.
Гравітація.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.
Як би я пішов про те, щоб зробити цю роботу з ниткою? (будь-які пропозиції щодо вдосконаленої системи планетарної тяжкості вітаються, якщо хтось має)
Я також не шукаю уроку, чому я не повинен використовувати різьблення чи небезпеку неправильного використання, шукаю пряму відповідь, як це зробити. Я вже витратив годину на гуглінг цього самого питання з невеликими результатами, які я зрозумів або були корисними. Я не маю на увазі грубість, але це завжди здається важким, як програмування noob отримати прямий змістовний відповідь, я, як правило, швидше отримую відповідь настільки складний, я легко міг би вирішити свою проблему, якби я зрозумів це, або хтось сказав, чому я не повинен робити те, що хочу зробити, і не пропоную альтернатив (які корисні).
Дякую за допомогу!
EDIT : Прочитавши відповіді, які я отримав, я бачу, що ви, хлопці, насправді хвилюєтесь і не просто намагаєтесь вияснити відповідь, яка може спрацювати. Мені хотілося вбити двох птахів одним каменем (покращуючи продуктивність та вивчаючи деякі основи багатопотокового прочитання), але, здається, більша частина проблеми лежить у моїх розрахунках, і те, що нарізання рішень - це більше клопоту, ніж варто для підвищення продуктивності. Дякую всім, я ще раз прочитаю ваші відповіді та спробую ваші рішення, коли закінчу зі школою, ще раз дякую!
k
цієї O(n^2)
проблеми багато.
sin² + cos² ≡ 1
він все одно нормалізується! Ви могли просто використати оригінальний вектор, який з'єднує два об'єкти, які вас цікавлять, і нормалізував цей. Жодного триггера не вимагає.