2011-01-26 4 views
1

Я пишу свою собственную игру, которая обрабатывает большое количество игровых сущностей (счет ≈1000). Каждый объект должен быть нарисован на экране. В начале я не был уверен, что C# даст мне хорошую частоту кадров. Но затем, когда я применил некоторые основные отбраковки, я был потрясен еще более высокой частотой кадров.Управление огромным количеством объектов

Итак, когда я добавляю логику ИИ к сущностям, время обновления для каждого объекта занимает некоторое время. У меня есть списки с объектами, и я петлю через них и вызываю obj.Update (dt). Похоже, этот способ не самый лучший. Обновление «огромных» объектов может занять много мс, поэтому другим придется ждать, когда этот парень закончит собственное обновление.

Так что мой вопрос: Какой способ лучше управлять огромным количеством динамических объектов?

+4

- это многопотоковая/параллельная обработка для вас? – TDaver

+7

Кажется идеальным контентом для http://gamedev.stackexchange.com/, посвященного веб-сайта для разработки игр. –

+1

Рассмотрите возможность делать обновления параллельно, если сможете. – jason

ответ

3

Проблема заключается в том, что вы перебираете объекты, вызывающие ваш метод Update. Что, если что-то не обновляется? Что делать, если что-то не необходимо обновляется каждый кадр?

Лучше, чтобы добавить событие в основной цикл и ваши объекты подписаться на него:

public void FrameListener(float _ticks); 


public class Game 
{ 
    public Event FrameListener OnFrame; 
} 

Теперь, когда что-то нужно обновить, он просто присоединяется к этому событию (получение дельта-тик COUNT прошло к нему). Когда объект становится бездействующим, он может отказаться от подписки. Используя этот метод, обновляются только те объекты, которые нуждаются в обновлении .

Кроме того, вы можете добавить счетчик к процессу подписки (это означает, что вы можете портировать объект события в пользу методов типа AddListener()), сообщая системе только для вызова делегата на каждый «n» фрейм. В игре, где вы, возможно, строите производство, например (поселенцы, цивилизация и т. Д.), Нет смысла для этих вещей обновлять свое производство в каждом кадре. Даже каждые 5 секунд достаточно. Это сокращает много накладных расходов, когда вы можете точно определить, как часто объекты должны обновляться.

Статические объекты просто не придают делегату, поэтому никогда не накладывайте на них лишних накладных расходов.

3

Во-первых, 1000 объектов на самом деле не огромный. При 60 кадр/с, это 60 кГц, что составляет 16 мкс - по меньшей мере 32 000 тактов на большинстве аппаратных средств на один объект. Некоторые объекты должны обладать высокой стоимостью.

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

+0

Спасибо, когда я выбрал C#, я пытался найти некоторую информацию о его производительности. И многие люди говорят, что это не правильный случай для развития игры. Так что я думал, что 1000 действительно ОГРОМНО.% -O – joe

+0

@joe: C# обычно имеет довольно приличную производительность в эти дни. Это все еще не на одном уровне с хорошо продуманным C++, но разница не должна иметь значения для вашего сценария. В частности, тяжелая GC очень сильно ухудшает производительность, поэтому я бы очень небрежно смотрел на каждое «новое» в коде обновления объекта. В том же духе, если вы еще этого не сделали, превратите все свои маленькие классы в структуры. –

1

Я думаю, что ваши проблемы не связаны с разработкой игры, а с принципами общих характеристик.

Возможно, вам придется изучить несколько способов оптимизации производительности. Вот список, но не исчерпывающий:

  • многопоточность/параллельность: может достичь очень хороших улучшений, но может добавить много сложности в ваше приложение.Если вы используете C# 4, вы можете взглянуть на новую библиотеку Parallel
  • в зависимости от версии и версии вашего VS, вы можете активировать анализ кода (или использовать FXcop, если он недоступен в VS). Инструмент может обеспечить хорошие советы
  • использовать инструменты профилирования, чтобы обнаружить узкие вас код
  • использовать инструменты для анализа сложности коды, особенно цикломатической сложности
  • Google немного советов общей производительности (строка строителя VS конкатенации, и т.д.)
  • Google немного больше за кончик производительности жестко (изменить порядок следования параметров в методах, уменьшить использование переменной величины, уменьшить граф вызовов и т.д.)

tip для более конкретной игры dev (от новичка в игре dev Я признаю): * попытайтесь разбить свои объекты на подмножества вместо одного набора ... иногда более эффективно иметь граф объектов, а не список объектов. Вы можете обновить один узел графика вместо целых объектов. * исключить, если возможно, обновления не отображаемых объектов.

. .
+0

Спасибо за полезные советы! к сожалению, я не могу отметить более одного правильного ответа ( – joe

+0

no pb :) Я рад, если это поможет –

Смежные вопросы