2012-03-25 2 views
4

Я пишу игру, которая в настоящее время работает как в Windows, и Mac OS X. Мой основной игровой цикл выглядит следующим образом:Правильный способ привода главного цикла в какао

while(running) 
{ 
    ProcessOSMessages(); // Using Peek/Translate message in Win32 
         // and nextEventMatchingMask in Cocoa 
    GameUpdate(); 
    GameRender(); 
} 

То, очевидно, немного упрощен, но это суть его. В Windows, где я полностью контролирую приложение, он отлично работает. К сожалению, у Apple есть собственный способ сделать что-то в приложениях Cocoa.

Когда я впервые попытался реализовать свой основной цикл в Cocoa, я не мог понять, куда его поместить, поэтому я создал свой собственный NSApplication на this post. Я бросил свой GameFrame() прямо в мою функцию run, и все работало правильно.

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

This article из apple описывает старый способ сделать это, с NSTimer и «новым» способом сделать это, используя CVDisplayLink. Я подключил версию CVDisplayLink, но он просто чувствует .... странно. Мне не нравится, что моя игра управляется дисплеем, а не наоборот.

Могу ли я использовать только два варианта использования CVDisplayLink или перезаписать свои собственные NSApplication? Ни одно из этих решений не кажется совершенно правильным.

ответ

2

Мне любопытно увидеть, если кто-то, кто на самом деле сделал это заботится взвеситься, но вот мое понимание:

Apple, толкает CVDisplayLink раствора над делает петлю на основной поток, который использует -nextEventMatchingMask:untilDate:inMode:dequeue:, потому что я Думайте, он обеспечивает лучшую отзывчивость для элементов управления пользовательского интерфейса. Это может быть не актуально для полноэкранных игр. (Примечание: вам не нужно заменять NSApplication, чтобы использовать эту форму игрового цикла.) I думаю, Основная потенциальная проблема с использованием CVDisplayLink заключается в том, что она будет работать только с одним фреймом заранее, и она делает это определение на ранней стадии, что даже сильнее, чем вертикальная синхронизация. С положительной стороны это может улучшить латентность.

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

+0

Метод CVDisplayLink в настоящее время работает для меня без проблем, он просто чувствует ... странно. Я знаю, что это не лучшая причина не использовать его, мне просто интересно, есть ли лучшее/более интуитивное решение. Это действительно то, что используют коммерческие игровые студии? – Kyle

+0

Я бы предположил, что большинство коммерческих игр игнорируют рекомендацию Apple и делают петлю в основном потоке, иначе вообще не используют фреймворки Cocoa. С другой стороны, я думаю, что в большинстве игр для iPhone используется «CADisplayLink», что эквивалентно. Я также хотел бы отметить, что если вы используете vsync, ваша игра уже (косвенно) управляется дисплеем. –

+0

По иронии судьбы, портирование на iPhone - это то, что обеспечило это вдохновение, чтобы найти «правильный» способ сделать это. Версия iPhone действительно управляется дисплеем, который не чувствует себя так же странно, потому что там больше смысла, IMO. Vsync - это вариант в моей игре, но во время разработки я держу его, чтобы выполнять реальные измерения производительности. – Kyle

1

Вам необязательно создавать собственный класс, основанный на NSApplication, или использовать CVDisplayLink, чтобы обойти тот факт, что runloop приложения скрыт от вас в Cocoa.

Вы могли бы просто создать поток и вместо этого запустить свой цикл цикла.

Для чего это стоит, я просто использую CVDisplayLink.

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