Постоянная частота кадров в WPF для игры

Я создаю простую игру-симулятор транспортных средств и снарядов в WPF с использованием С#. Мне нужно иметь постоянную частоту кадров (т.е. мне нужно знать, на сколько перемещать объект с определенной скоростью в каждом кадре). Таким образом, я мог бы подписаться на событие, которое вычисляет и обновляет позиции в соответствии с физикой игры, на CompositionTarget.Rendering.

CompositionTarget.Rendering += UpdatePositions;

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

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

Спасибо!


person Nicolas    schedule 12.10.2011    source источник
comment
Не используйте WPF ни для чего, кроме самой базовой разработки игр. Он действительно не был предназначен для этого использования. Вам следует изучить среду XNA, если вы хотите создать игру с использованием .NET.   -  person dlev    schedule 12.10.2011
comment
Я думаю, что это самая основная часть разработки игр, и я уже много работал, поэтому мне действительно нужно разобраться с моими проблемами с частотой кадров...   -  person Nicolas    schedule 12.10.2011
comment
использование секундомера, чтобы узнать, сколько времени прошло между кадром и предыдущим, вообще не будет чистым - как так?   -  person EboMike    schedule 12.10.2011
comment
Игры, основанные на частоте кадров, ужасны. Никогда не управляйте своим движением с частотой кадров. Что произойдет, если клиент не сможет поддерживать установленную вами частоту кадров?   -  person Chris Eberle    schedule 12.10.2011
comment
Помимо того, следует использовать для этого WPF, вы можете использовать nowTime = DateTime.Now; Дельта TimeSpan = nowTime - lastDateTime (дает прошедший интервал). Тогда lastDateTime = nowTime;   -  person Mranz    schedule 12.10.2011
comment
Я могу ошибаться, но я думаю, что использование событий для этого добавит значительные накладные расходы.   -  person Tipx    schedule 12.10.2011
comment
Как уже говорили другие, не привязывайте свой временной шаг к частоте кадров: gafferongames.com/game -физика/исправьте-свой-временной шаг   -  person jeffora    schedule 12.10.2011


Ответы (3)


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

Некоторая связанная информация:

Почему частота кадров в WPF Нерегулярно и не ограничивается обновлением монитора?

http://rhnatiuk.wordpress.com/2008/12/21/wpf-video-playback-problems/

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

Я много работал с анимацией WPF, и мне очень сложно заставить что-либо плавно анимироваться в WPF (если вы действительно хотите это сделать, я записал несколько рекомендации здесь).

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

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

person Patrick Klug    schedule 12.10.2011
comment
в этих передовых методах вы говорите: событие CompositionTarget.Rendering заставляет WPF непрерывно анимировать. Если вы используете это событие, отсоединяйте его при каждой возможности. Что вы подразумеваете под отсоединением события? Спасибо - person Nicolas; 12.10.2011
comment
это просто означает, что подключение к CompositionTarget.Rendering не является оптимальным, поскольку это может повлиять на производительность, даже если вы ничего не делаете в обработчике событий. MS рекомендует отключать/отписываться (CompositionTarget.Rendering-= Foo) всякий раз, когда нет абсолютной необходимости прослушивать событие. - person Patrick Klug; 12.10.2011
comment
этот совет взят прямо из MS: msdn.microsoft.com/en-us/library /bb613584.aspx - person Patrick Klug; 12.10.2011

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

Следующие 2 ссылки обсуждают «время игры», «реальное время» и связанные с ними понятия: http://blogs.msdn.com/shawnhar/archive/2007/07/25/understanding-gametime.aspx, http://blogs.msdn.com/shawnhar/archive/2007/11/23/game-timing-in-xna-game-studio-2-0.aspx

person Alexei Levenkov    schedule 12.10.2011

Вы можете использовать WPF для рисования окружающего пользовательского интерфейса вашей игры, а затем использовать API DirectComposition, чтобы Composition Engine (DWM) составлял вашу цепочку обмена непосредственно поверх окна WPF.

Я загрузил пример, демонстрирующий этот на github.

Пользовательский интерфейс не будет иметь постоянной частоты кадров, но ваша цепочка обмена будет. Тестирование просто провалилось бы в окно WPF.

person Tom Huntington    schedule 28.07.2020