Вопрос по iphone, ios, cocos2d-iphone – cocos2d 2.0-rc2: завершите директорию и перезапустите

7

У меня есть игра на основе cocos2d, которая использует меню UIKit, поэтому я использую фреймворк только для одного viewcontroller, который является самой игрой. Кроме того, у него есть только одна сцена. Поскольку cocos2d 2.0 сам директор являетсяUIViewController подкласс, так что я просто запихнуть его в свойMenuViewController когда пользователь нажимает кнопку запуска:

-(void)startGameButtonPressed {

    CCDirectorIOS* director = (CCDirectorIOS *) [CCDirector sharedDirector];


    // Create an CCGLView with a RGB565 color buffer, and a depth buffer of 0-bits
    self.glView = [CCGLView viewWithFrame:CGRectMake(0, 0, 480, 320)
                              pixelFormat:kEAGLColorFormatRGB565    //kEAGLColorFormatRGBA8
                              depthFormat:0 //GL_DEPTH_COMPONENT24_OES
                       preserveBackbuffer:NO
                               sharegroup:nil
                            multiSampling:NO
                          numberOfSamples:0];

    // attach the openglView to the director
    [director setView:glView];
    [director runWithScene:[GameLayer scene]];
    [director setDelegate:(id <CCDirectorDelegate>) [[UIApplication sharedApplication] delegate]];
    [self.navigationController pushViewController:director animated:YES];
}

Это отлично работает при первом вызове метода, когда пользователь запускает первую игру. Когда игра заканчивается, я звоню[[CCDirector sharedDirector] end].

Большая часть настройки директора выполняется в appDelegate (она не изменена по сравнению со стандартным шаблоном Cocos2d). Я только положилCCGLView в качестве оставшейся собственности в мойMenuViewControllerпотому что в противном случае приложение вылетает, когда[[CCDirector sharedDirector] end] называется иCCGLView не сохраняется. Я думаю, что это может быть ошибка Cocos2D. В[[CCDirector sharedDirector] end] рамки называет[self setView:nil], но он все еще пытается получить доступ к представлению позже (возможно, в другом потоке).

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

Я мог бы действительно использовать ответ на этот вопрос также. Это суть моего заявления прямо сейчас. Echilon

Ваш Ответ

4   ответа
8

Когда вы устанавливаете CCGLView и [Director SetView:], даже если вы выдвигаете контроллер, сцена все еще существует. единственное, что происходит, это то, что сцена останавливается.

Для того, чтобы «перезагрузка» работала, вы должны проверить, есть ли уже запущенная сцена (даже если она остановлена и вместоrunWithScene: ты используешьreplaceScene:.

Вот мой код, чтобы вы могли видеть:

- (void)setupCocos2D {
    CCGLView *glView = [CCGLView viewWithFrame:CGRectMake(0, 0, 320, 480)
                               pixelFormat:kEAGLColorFormatRGB565   //kEAGLColorFormatRGBA8
                               depthFormat:0    //GL_DEPTH_COMPONENT24_OES
                        preserveBackbuffer:NO
                                sharegroup:nil
                             multiSampling:NO
                           numberOfSamples:0];

// HERE YOU CHECK TO SEE IF THERE IS A SCENE RUNNING IN THE DIRECTOR ALREADY    
if(![director_ runningScene]){
    [director_ setView:glView]; // SET THE DIRECTOR VIEW
    if( ! [director_ enableRetinaDisplay:YES] ) // ENABLE RETINA
        CCLOG(@"Retina Display Not supported");

    [director_ runWithScene:[HelloWorldLayer scene]]; // RUN THE SCENE

} else {
    // THERE IS A SCENE, START SINCE IT WAS STOPPED AND REPLACE TO RESTART
    [director_ startAnimation];
    [director_ replaceScene:[HelloWorldLayer scene]];
}      


[director_ setDelegate:(id <CCDirectorDelegate>) [[UIApplication sharedApplication] delegate]];

// I DO NOT PUSH BECAUSE I ALREADY PUSHED TO THIS CONTROLLER, SO I ADD THE COCOS2D VIEW AS A SUBVIEW
[self.view addSubview:[director_ view]];

}

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

РЕДАКТИРОВАТЬ Также, пожалуйста, не говорите, что если вы POP на сцене COCOS2D, вам не нужно[[CCDirector sharedDirector] end] поскольку анимация будет остановлена, когда представление будет удалено / удалено.

Большое спасибо за этот пост @gmogames. Я часами боролся с этим. Echilon
Хорошо сказано .. Спасибо за ваш ценный ответ ... Balan Prabhu
извините, но у меня не работает: The iOSDev
@ ClaricPWI это старый ответ. Вероятно, с тех пор Кокос сильно изменился. gmogames
Я думаю, что причина этого заключается в том, что вы не выдвигаете директора как контроллер вида, а скорее присоединяете GLView к своему собственному представлению. Это может быть лучше, чем мой подход. avf
5

касающейся этого, и поделюсь с вами своим собственным опытом. Я также пытаюсь создать игру, которая загружается в UITableViewController, из которого CCDirector загружается при прикосновении к ячейке. Это пошаговая игра Game Center, отсюда и дизайн (подумайте «Слова с друзьями»). Лучший подход, который я нашел для этого, заключается в следующем (обратите внимание, что я работаю в 2.0 - где CCDirector является подклассом UIViewController):

В AppDelegate.h создайте новый ivar для хранения CCGLView, созданного из кода шаблона. Затем назначьте CCGLView, созданный в didFinishLaunching, вашему новому ivar. Это позволяет директору повторно использовать изначально созданное представление вместо того, чтобы пытаться воссоздавать его каждый раз, когда вы перезагружаете CCDirector, что, по-моему, вызывает всевозможные странные проблемы в моем опыте.

Вы также хотите создать новый метод в AppDelegate с именем -setupDirector или что-то подобное, где вы, ну, в общем, настроите директор. Это должно вызываться каждый раз, когда вы воссоздаете CCDirector. Я разместил свою версию ниже. Обратите внимание, что мой ivar для CCGLView называется «GLView».

- (void)setupDirector {
if (![CCDirector sharedDirector]) {
    CCLOG(@"Calling setupDirector");

    director_ = (CCDirectorIOS*) [CCDirector sharedDirector];

    director_.wantsFullScreenLayout = YES;

    // Display FSP and SPF
    [director_ setDisplayStats:NO];

    // set FPS at 60
    [director_ setAnimationInterval:1.0/60];

    // attach the openglView to the director
    [director_ setView:GLView];

    // for rotation and other messages
    [director_ setDelegate:self];

    // 2D projection
    [director_ setProjection:kCCDirectorProjection2D];
    //  [director setProjection:kCCDirectorProjection3D];

    // Enables High Res mode (Retina Display) on iPhone 4 and maintains low res on all other devices
    if( ! [director_ enableRetinaDisplay:YES] )
        CCLOG(@"Retina Display Not supported");

    // Default texture format for PNG/BMP/TIFF/JPEG/GIF images
    // It can be RGBA8888, RGBA4444, RGB5_A1, RGB565
    // You can change anytime.
    [CCTexture2D setDefaultAlphaPixelFormat:kCCTexture2DPixelFormat_RGBA8888];

    // If the 1st suffix is not found and if fallback is enabled then fallback suffixes are going to searched. If none is found, it will try with the name without suffix.
    // On iPad HD  : "-ipadhd", "-ipad",  "-hd"
    // On iPad     : "-ipad", "-hd"
    // On iPhone HD: "-hd"
    CCFileUtils *sharedFileUtils = [CCFileUtils sharedFileUtils];
    [sharedFileUtils setEnableFallbackSuffixes:NO];             // Default: NO. No fallback suffixes are going to be used
    [sharedFileUtils setiPhoneRetinaDisplaySuffix:@"-hd"];      // Default on iPhone RetinaDisplay is "-hd"
    [sharedFileUtils setiPadSuffix:@"-ipad"];                   // Default on iPad is "ipad"
    [sharedFileUtils setiPadRetinaDisplaySuffix:@"-ipadhd"];    // Default on iPad RetinaDisplay is "-ipadhd"

    // Assume that PVR images have premultiplied alpha
    [CCTexture2D PVRImagesHavePremultipliedAlpha:YES];
}

Кроме того, вы захотите внести пару изменений в способ загрузки шаблона контроллерами представления. Обычно cocos2D устанавливает контроллер навигации с директором_ в качестве корневого контроллера представления. Здесь вы хотите выделить и запустить свой контроллер представления меню и добавить TH вместо вместо _:

// Create a Navigation Controller with the Director
gamesTVC_ = [[GamesTableViewController alloc] initWithStyle:UITableViewStyleGrouped];
navController_ = [[UINavigationController alloc] initWithRootViewController:gamesTVC_];
navController_.navigationBarHidden = NO;

Все остальное в didFinishLaunching может остаться прежним. Теперь в вашем menuViewController в вашем методе startGameButtonPressed вы будете вызывать только что созданный метод setupDirector в экземпляре приложения, на который ссылается вызов:

AppController *app = (AppController *)[[UIApplication sharedApplication] delegate];
if ([CCDirector sharedDirector].runningScene) {
    [[CCDirectorIOS sharedDirector] end];
}
[app setupDirector];
[app.navController pushViewController:app.director animated:YES];

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

AppController *app = (AppController *)[[UIApplication sharedApplication] delegate];
[app.navController popViewControllerAnimated:YES];
[[CCDirector sharedDirector] end];

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

2

что хорошо работает, это просто вызвать startAnimation и stopAnimation в директории, но сохранить представление cocos2d и просто использовать его повторно.

Любая попытка закрыть cocos2d и его представление OpenGL и повторно инициализировать его позже вызовет больше или меньше проблем, потому что он действительно не был достаточно хорошо протестирован. Кроме того, cocos2d прекрасно работает с UIKit, у него есть те же проблемы, что и у любого другого приложения OpenGL ES при смешивании его с представлениями UIKit.

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

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

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

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

К сожалению, Cocos не облегчает нам использование UIKit + Cocos, но с удачей.

Похожие вопросы