2010-12-15 24 views
17

Tengo un CCLayer con el menú de inicio de mi aplicación y me gustaría tener una película corta en segundo plano. He tenido éxito al reproducir una película en el glView, pero cuando reproduce el menú no se muestra. Para manejar la película que crear instancias de un MPMoviePlayerController y luego agrego su punto de vista a la glView esta manera:cocos2d: reproducir un video en el fondo de un menú

[[[CCDirector sharedDirector] openGLView] addSubview:moviePlayer.view]; 

he visto esta pregunta fue bastante similar

How to have a menu when a movie is playing-iphone cocos2d

pero me gustaría para saber si hay una mejor solución para ella, posiblemente una que me permita explotar las entidades de marco de trabajo de cocos2d (y no mis propios puntos de vista).

he tratado de enviar el moviePlayer.view para respaldar esta manera

[theView sendSubviewToBack:moviePlayer.view]; 

pero el menú es stil oculta por la película ...

(muchas horas más tarde ..)

Ok, como puedes leer en el primer comentario, me he dado cuenta de que (probablemente) la única forma es explotar las vistas personalizadas. Lo hice y se ejecuta en el simulador agregando cualquier vista al glView después de moviePlayer.view. Sin embargo, cuando lo ejecuto en mi iPod de destino, toque con un 3.1.3 FW, la vista de la película siempre está en la parte superior. Por lo tanto, me he dado cuenta de que MPMoviePlayerController realmente crea su propia ventana y su propia vista. Algunas publicaciones (como esta Overlay on top of Streaming MPMoviePlayerController) sugieren interceptar el evento en el que se carga la nueva ventana y solo luego agregar las subvistas.

eso es lo que traté de hacer pero ese evento en realidad nunca se atrapa ni en el simulador ni en el Ipod de destino. Por tanto, he añadido un selector programada - (void) actualización que se implementa de esta manera:

-(void) update{ 
    NSArray *windows = [[UIApplication sharedApplication] windows]; 
    if ([windows count] > 1) 
    { 
    UIImageView *logo = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"logo.png"]]; 
    UIView *theView = [[CCDirector sharedDirector] openGLView]; 
    [logo setCenter:ccp(240,80)]; 
    [moviePlayer.view addSubview:logo]; 
     [self unscheduleAllSelectors]; 
    } 
} 

pero la película sigue siendo en la parte superior

chicos por favor cualquier ayuda sería muy apreciada!

(algunos días después ...) También he esperado 2 segundos, mientras la película se está ejecutando, para agregar mi vista de logotipo como una subvista del movieplayer. Funciona correctamente en el simulador, pero en el Ipod (3.1.3) resulta un resultado diferente. La primera vez que se reproduce la película, el logotipo no se muestra (película en la parte superior). Sin embargo, desde el momento en que finaliza la película, el método de reproducción se completa, comenzando desde la segunda vez que se muestra el logotipo con la película en el fondo (es decir, lo haría). ¿Tiene algún sentido para ti?

que realmente necesitan entender cómo solucionar este problema que es bastante ridícula que han succeded en el desarrollo de un juego en 2 meses y ahora estoy atascado de 2 semanas para que el menú de inicio :)

De todos modos, si tengo decidió pegar el código completo de la capa que estoy tratando de corregir de manera que es mejor que se puede averiguar cuál es el problema (o al menos esa es mi esperanza :))

+(id) scene 
{ 
    // 'scene' is an autorelease object. 
    CCScene *scene = [CCScene node]; 

    // 'layer' is an autorelease object. 
    StartMenu *layer = [StartMenu node]; 

    // add layer as a child to scene 
    [scene addChild: layer]; 

    // return the scene 
    return scene; 
} 

-(void) update{ 
    timer ++; 
    if (timer==120){ 

    UIImageView *logo = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"stupidLogo.png"]]; 
    UIView *theView = [[CCDirector sharedDirector] openGLView]; 
    [logo setCenter:ccp(240,80)]; 
    //logo.transform = CGAffineTransformMakeRotation(3.14/2); 
    [moviePlayer.view addSubview:logo]; 
     [self unscheduleAllSelectors]; 
    } 
} 
-(id) init{ 
    self = [super init]; 

    [self schedule: @selector(update)]; 
    NSURL *url = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"test_005_conv_06.mp4" ofType:@""]];   
    moviePlayer = [[MPMoviePlayerController alloc] initWithContentURL:url]; 
    // Register to receive a notification when the movie has finished playing. 
    [[NSNotificationCenter defaultCenter] addObserver:self 
              selector:@selector(moviePlayBackDidFinish:) 
               name:MPMoviePlayerPlaybackDidFinishNotification 
               object:moviePlayer]; 

    if ([moviePlayer respondsToSelector:@selector(view)]) { 
     if([MPMoviePlayerController instancesRespondToSelector:@selector(view)]){ 
     // Use the new 3.2 style API 
     moviePlayer.controlStyle = MPMovieControlStyleNone; 
     moviePlayer.shouldAutoplay = FALSE; 
     // This does blows up in cocos2d, so we'll resize manually 
     // [moviePlayer setFullscreen:YES animated:YES]; 
     [moviePlayer.view setTransform:CGAffineTransformMakeRotation((float)M_PI_2)]; 
     CGSize winSize = [[CCDirector sharedDirector] winSize]; 

     moviePlayer.view.frame = CGRectMake(0, 0, winSize.height, winSize.width); // width and height are swapped after rotation 
     [[[CCDirector sharedDirector] openGLView] addSubview:moviePlayer.view]; 
     [moviePlayer play]; 
     } 
    } else { 
     // Use the old 2.0 style API 
     moviePlayer.movieControlMode = MPMovieControlModeHidden; 
     [moviePlayer play]; 
    } 
    return self; 
} 


- (void)moviePlayBackDidFinish:(NSNotification*)notification { 
    MPMoviePlayerController *moviePlayer = [notification object]; 
    [moviePlayer play]; 
} 
+0

He encontrado esto: http://www.cocos2d-iphone.org/forum/topic/61 es uno de sus comentarios dice: "no funciona porque el imageView se agrega a la OpenGLView. Parece que podría cocos2d no dibujar en el objeto UI. La única forma de hacerlo es usar el método UI estándar, pero no es conveniente como cocos2d cuando se trata de animación ". ¿Es posible? eso podría bu fea ... – Sindico

Respuesta

19

Después de pasar algún tiempo con esto encontró la respuesta. (Quiero hacer esto también, pero luego, ¡así que puedo hacerlo ahora!)

Utilicé el código y las técnicas en this link por ascorbin, con ayuda de this link. No es completa a menos que también se añade la siguiente línea al EAGLView:

glView.opaque = NO; 

La vista a lo largo de la película es el lado de la EAGLView, y empujó a la parte posterior para conseguir lo que busca. También puede tener que modificar la transparencia de EAGLView como se menciona en esa publicación. Espero que ayude.


Las cosas que necesitaba modificar se enumeran aquí.

es necesario agregar la nuez de mediaPlayer.framework a su proyecto y contener la siguiente línea en su aplicación .h delegado:

#import <MediaPlayer/MediaPlayer.h> 

En el método de CCDirector setGLDefaultValues, ajuste alfa de glClearColor ser 0.0f no 1.0f:

// glClearColor(0.0f, 0.0f, 0.0f, 1.0f); 
    glClearColor(0.0f, 0.0f, 0.0f, 0.0f); 

al crear su EAGLView en applicationDidFinishLaunching: cambio de las siguientes cosas:

cambiar el pixelFor estera del valor mayor para ser la siguiente:

// kEAGLColorFormatRGB565 
kEAGLColorFormatRGBA8 

Asegúrese de añadir el EAGLView como un sub-vista (y hacer que no opaco) y no como la vista principal:

// [viewController setView:glView]; 
    [viewController.view addSubview:glView]; 
    glView.opaque = NO; 

último , antes de ejecutar su escena, puede agregar su código para reproducir la película en bucle. Agregué un método al delegado de la aplicación para esto. También puede agregar un método para evitar que su película se reproduzca aquí en el delegado de la aplicación y para cuándo (si es así) debe eliminar la película.

[self startMovie]; 

y el propio método:

- (void) startMovie 
{ 
    NSURL *url = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"test" ofType:@"m4v"]]; 
    moviePlayer = [[MPMoviePlayerController alloc] initWithContentURL:url]; 

    if ([moviePlayer respondsToSelector:@selector(setFullscreen:animated:)]) { 
     // Use the new 3.2 style API 
     moviePlayer.controlStyle = MPMovieControlStyleNone; 
     moviePlayer.shouldAutoplay = YES; 
     moviePlayer.repeatMode = MPMovieRepeatModeOne; 
     CGRect win = [[UIScreen mainScreen] bounds]; 

     moviePlayer.view.frame = CGRectMake(0, 0, win.size.height, win.size.width); 
     [viewController.view addSubview:moviePlayer.view]; 
     [viewController.view sendSubviewToBack:moviePlayer.view]; 
    } 
    else 
    { 
     // Use the old 2.0 style API 
     moviePlayer.movieControlMode = MPMovieControlModeHidden; 
     [moviePlayer play]; 
    } 
} 

Tenga en cuenta que no tiene que añadir el observador, como se muestra en el ejemplo enlazado, ni la función para repetir la película, esto se hace de forma automática con la opción 'MPMovieRepeatModeOne'. Si no desea que la película se repita, puede elegir la opción 'MPMovieRepeatModeNone' aquí también.

También debería tener en cuenta que no pude hacer que esto funcione con la anterior API anterior a 3.2 (por lo que en el caso de 3.1.3 no funcionaba), el video no se mostró a través de EAGLView. No estoy seguro de lo que está sucediendo allí, pero no he visto opciones específicas sobre qué hacer al respecto.

+0

+1 para una respuesta excelente. –

Cuestiones relacionadas