Программирование игр и обработчики событий

StackOverflow https://stackoverflow.com/questions/63960

  •  09-06-2019
  •  | 
  •  

Вопрос

Я не программировал игры около 10 лет (моим последним опытом был DJGPP + Allegro), но я решил проверить XNA на выходных, чтобы посмотреть, как она развивается.

Я довольно впечатлен, однако, продолжая собирать игровой движок по кусочкам, у меня возник (вероятно) основной вопрос.

Насколько вы должны полагаться на делегатов и события C # для управления игрой?Как прикладной программист, я активно использую делегаты и события, но я не знаю, связаны ли это со значительными накладными расходами.

В моем игровом движке я разработал своего рода "камеру преследования", которую можно прикрепить к объекту, а затем пересчитывать ее положение относительно объекта.Когда объект перемещается, есть два способа обновить камеру слежения.

  • Используйте метод "UpdateCameras()" в основном игровом цикле.
  • Используйте обработчик событий и попросите chase cam подписаться на object.OnMoved.

Я использую последнее, потому что оно позволяет мне объединять события в цепочку и хорошо автоматизировать большие части движка.Внезапно то, что могло бы быть огромным и сложным, сводится к горстке 3-5 линейных обработчиков событий...Это прекрасно.

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

Идеи?

Это было полезно?

Решение

Если бы вы представляли событие как список подписчиков, то в вашем коде все, что вы делаете, - это регистрируете подписчика.Количество инструкций, необходимых для достижения этой цели, вероятно, будет минимальным на уровне CLR.

Если вы хотите, чтобы ваш код был универсальным или динамическим, то вам нужно проверить, подписано ли что-либо перед вызовом события.Механизм событий / делегирования C # и .NET предоставляет вам это с очень небольшими затратами (с точки зрения процессора).

Если вы действительно беспокоитесь о каждом такте, вы бы никогда не написали универсальную / динамическую игровую логику.Это компромисс между поддерживаемым / настраиваемым кодом и абсолютной скоростью.

Написано хорошо, я бы предпочел мероприятия / делегатов, пока не смогу доказать, что это проблема.

Единственный способ по-настоящему узнать, является ли это проблемой для вас, - это профилировать свой код, что вы в любом случае должны делать при разработке любой игры!

Другие советы

Важно понимать, что события в C # не являются асинхронными событиями в очереди (как, например, очередь сообщений Windows).По сути, они представляют собой список указателей на функции.Таким образом, создание события не имеет худших последствий для производительности, чем перебор списка указателей на функции и вызов каждого из них.

В то же время осознайте, что из-за этого события происходят синхронно.Если ваше мероприятие слушатель это медленно, ты замедлишь ход занятия повышение события.

Главный вопрос здесь, по-видимому, заключается в следующем:"Каковы накладные расходы, связанные с использованием делегатов и событий C #?"

События имеют незначительные накладные расходы по сравнению с обычным вызовом функции.

Использование делегатов может создать неявный и, следовательно, скрытый мусор.Мусор может быть основной причиной проблем с производительностью, особенно на XBox360.

Следующий код генерирует около 2000 байт мусора в секунду (при 60 кадрах в секунду) в виде объектов EntityVisitor:

    private delegate void SpacialItemVisitor(ISpacialItem item);

    protected override void Update(GameTime gameTime)
    {
        m_quadTree.Visit(ref explosionCircle, ApplyExplosionEffects);
    }

    private void ApplyExplosionEffects(ISpacialItem item)
    {
    }

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

В свободное от реальной работы время я тоже изучал XNA.

ИМХО (или не такое скромное, если вы спросите моих коллег) заключается в том, что накладные расходы на дескрипторы событий будут перегружены другими элементами игры, такими как рендеринг.Учитывая интенсивное использование событий в обычном режиме.Сетевое программирование, я бы сказал, что базовый код хорошо оптимизирован.

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

XNA поощряет использование интерфейсов, событий и делегатов для управления чем-либо, написанным с ее помощью.Взгляните на классы, связанные с GameComponent, которые настраивают это для вас.

Ответ таков: "Столько, сколько вам будет удобно".

Чтобы немного уточнить, если, например, вы берете и наследуете класс gamecomponent в класс cameracontroller и добавляете его в игру.Коллекция компонентов.Затем вы можете создать свои классы камер и добавить их в свой cameracontroller.

Выполнение этого приведет к регулярному вызову cameracontroller и позволит выбрать и активировать нужную камеру или несколько камер, если это то, к чему вы стремитесь.

Вот пример этого (все его учебные пособия превосходны):Перекодировать

Кроме того, вам, возможно, будет интересно узнать, что Шон Харгривз, первоначальный разработчик Аллегро, является одним из главных разработчиков в команде XNA :-)

Прежде чем переходить к вопросу о влиянии события на производительность, вы должны сначала оценить, нужно ли это.

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

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top