Обновление физического движка в отдельной ветке, это мудро? - PullRequest
0 голосов
/ 24 мая 2011

Я на 100% новичок в потоках, для начала я решил, что хочу использовать его для обновления своей физики в отдельном потоке.Я использую сторонний физический движок под названием Farseer, вот что я делаю:

// class level declarations
System.Threading.Thread thread;
Stopwatch threadUpdate = new Stopwatch();

//In the constructor:
PhysicsEngine()
{
(...)

            thread = new System.Threading.Thread(
                        new System.Threading.ThreadStart(PhysicsThread));
            threadUpdate.Start();

            thread.Start();
}


        public void PhysicsThread()
        {
            int milliseconds = TimeSpan.FromTicks(111111).Milliseconds;
            while(true)
            {
                if (threadUpdate.Elapsed.Milliseconds > milliseconds)
                {
                    world.Step(threadUpdate.Elapsed.Milliseconds / 1000.0f);
                    threadUpdate.Stop();
                    threadUpdate.Reset();
                    threadUpdate.Start();
                }
            }
        }

Это нормальный способ обновления физики, или я должен кое-что найти? 1004*

Ответы [ 2 ]

3 голосов
/ 24 мая 2011

В игре вам нужно синхронизировать обновление физики с частотой кадров игры.Это потому, что ваш рендеринг и игровой процесс будут зависеть от производительности вашего физического движка в каждом кадре.И ваш физический движок будет зависеть от пользовательского ввода и событий игрового процесса в каждом кадре.

Это означает, что единственное преимущество расчета вашей физики в отдельном потоке состоит в том, что он может работать на отдельном ядре процессора для остальной части вашегоигровая логика и рендеринг.(Довольно безопасно для ПК в наши дни, и мобильное пространство только начинает приобретать двухъядерный процессор.)

Это позволяет им одновременно выполнять и физику, и игровой процесс / рендеринг, но недостатком является то, что вам нужно иметьнекоторый механизм, предотвращающий изменение данных одним потоком, в то время как другой поток использует эти данные.Это обычно довольно сложно реализовать.

Конечно, если ваша физика не зависит от пользовательского ввода - как Angry Birds или The Incredible Machine (то есть: пользователь нажимает «play»)и симуляция запускается) - в этом случае вы можете заранее рассчитать физическое моделирование, записав его вывод для воспроизведения.Но вместо того, чтобы блокировать основной поток, вы можете переместить эту трудоемкую операцию в фоновый поток - что является хорошо понятной проблемой.Вы даже можете зайти так далеко, чтобы начать воспроизведение своей записи в главном потоке, даже до того, как она закончит запись!

1 голос
/ 24 мая 2011

нет ничего плохого в вашем подходе в целом.Перенос трудоемких операций, таких как вычисления физического движка, в отдельный поток часто является хорошей идеей.Тем не менее, я предполагаю, что ваше приложение включает в себя какое-то визуальное представление ваших физических объектов в пользовательском интерфейсе?В этом случае у вас возникнут проблемы.

Элементы управления пользовательского интерфейса в Silverlight имеют сходство с потоками, то есть вы не можете обновить их состояние из потока, созданного в приведенном выше примере.Чтобы обновить их состояние, вам нужно будет вызвать его с помощью диспетчера, например TextBox.Dispatcher.Invoke (...).

Другой альтернативой является использование Silverlight BackgroundWorker .Это полезный маленький класс, который позволяет вам выполнять трудоемкую работу.Это переместит вашу работу в фоновый поток, избегая необходимости создавать свои собственные System.Threading.Thread.Он также будет предоставлять события, которые результаты маршала возвращают в поток пользовательского интерфейса.

Намного проще!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...