Для своих собственных проектов iOS я использую классический подход (создайте окно .nib, создайте класс, наследующий EAGLView
, добавьте EAGLView
к представлению в контроллере представления, который помещен в его собственный .nib).
На работе я использовал немного другой подход, основанный на SDL, который вы можете просмотреть в нашей библиотеке с открытым исходным кодом, АПРЕЛЬ .Главная цель APRIL - поддержка как можно большего количества платформ, сохраняя при этом простоту (только управление окнами и вводом), а также ясность в вопросах лицензирования и бесплатное использование.Наши разработчики хотят писать приложения на одной платформе (Windows, Mac или Linux, в зависимости от вкусов и желаний), а затем код передается мне для адаптации к другим платформам.
В подходе, который мы используем в APRIL, вы не создаете никаких .nibs, а при вызове UIApplicationMain
вы указываете класс делегата в качестве его четвертого аргумента.Основной код игры остается абсолютно одинаковым для каждой платформы, и только специфичные для платформы вещи находятся в коде #ifdef
или абстрагированы в вспомогательной библиотеке.
В делегате приложения вы создаете контроллер представленияи окно:
- (void)applicationDidFinishLaunching:(UIApplication *)application {
// create a window.
// early creation so Default.png can be displayed while we're waiting for
// game initialization
window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// viewcontroller will automatically add imageview
viewController = [[AprilViewController alloc] initWithWindow:window];
[viewController loadView];
// set window color
[window setBackgroundColor:[UIColor blackColor]];
// display the window
[window makeKeyAndVisible];
// thanks to Kyle Poole for this trick
// also used in latest SDL
// quote:
// KP: using a selector gets around the "failed to launch application in time" if the startup code takes too long
// This is easy to see if running with Valgrind
[self performSelector:@selector(runMain:) withObject:nil afterDelay:0.2f];
}
Обратите внимание, как мы задерживаем запуск на 0,2?Вот почему я упоминаю вид изображения выше.В течение этих 0,2 секунд у нас сразу после Default.png будет отображаться пустой экран, и перед переносом элемента управления в runMain: вводится дополнительная задержка, которая освобождает элемент управления от основного приложения:
- (void)runMain:(id)sender
{
// thanks to Kyle Poole for this trick
char *argv[] = {"april_ios"};
int status = april_RealMain (1, argv); //gArgc, gArgv);
#pragma unused(status)
}
Итак,Теперь элемент управления никогда не возвращается обратно в реальный основной цикл UIApplication.Затем вы создаете свой собственный главный цикл.
void iOSWindow::enterMainLoop()
{
while (mRunning)
{
// parse UIKit events
doEvents();
handleDisplayAndUpdate();
}
}
void iOSWindow::doEvents()
{
SInt32 result;
do {
result = CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0, TRUE);
} while(result == kCFRunLoopRunHandledSource);
}
(На заметке сторон, конечно, контроллер вида используется, чтобы упростить поворот пользовательского интерфейса в соответствии с ориентацией устройства.)
Оба изэти подходы используют CADisplayLink
, если они поддерживаются ОС.Я не заметил никаких проблем ни с одним из методов, хотя мои частные проекты в основном основаны на акселерометре.Я подозреваю, что подход АПРЕЛЯ может также устранить некоторые проблемы.