2010-12-15 13 views
17

Ich habe einen CCLayer mit dem Startmenü meiner App und ich hätte gerne einen kurzen Film im Hintergrund. Es ist mir gelungen, einen Film in der glView zu spielen, aber wenn es spielt, wird das Menü nicht dargestellt. den Film zu handhaben ich instanziiert ein MPMoviePlayerController und dann füge ich seinen Blick auf die GLview auf diese Weise:cocos2d: ein Video im Hintergrund eines Menüs abspielen

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

ich diese Frage gesehen habe, war sehr ähnlich

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

aber ich möchte zu wissen, ob es eine bessere Lösung gibt, möglicherweise eine, die mich noch die cocos2d-Framework-Entitäten ausnutzen würde (und nicht meine eigenen Ansichten).

Ich habe versucht, die moviePlayer.view senden diese Weise durch den Film

[theView sendSubviewToBack:moviePlayer.view]; 

aber das Menü Stil versteckt nach hinten ...

(viele Stunden später ..)

Ok, wie Sie im ersten Kommentar lesen können, habe ich festgestellt, dass (wahrscheinlich) die einzige Möglichkeit ist, benutzerdefinierte Ansichten zu nutzen. Ich habe das gemacht und es läuft im Simulator, indem ich nach dem moviePlayer.view irgendwelche Ansichten zum glView hinzufüge. Allerdings, wenn ich es auf meinem Ziel IPod Touch mit einer 3.1.3 FW die Filmansicht ist immer oben. Ich habe daher erkannt, dass der MPMoviePlayerController tatsächlich ein eigenes Fenster und seine eigene Ansicht erstellt. Einige Posts (wie diese Overlay on top of Streaming MPMoviePlayerController) schlagen vor, das Ereignis, das das neue Fenster geladen wird, abzufangen und erst dann die Unteransichten hinzuzufügen.

das habe ich versucht, aber dieses Ereignis wird weder im Simulator noch auf dem Ziel-Ipod tatsächlich eingefangen. ich haben aus diesem Grund eine geplante Selektor - (void) Update, das auf diese Weise durchgeführt wird:

-(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]; 
    } 
} 

aber der Film bleibt nach wie vor an der Spitze

bitte Jungs jede mögliche Hilfe wäre sehr geschätzt!

(einige Tage später ...) Ich habe auch 2 Sekunden gewartet, während der Film läuft, um meine Logoansicht als Unteransicht des Movieplayers hinzuzufügen. Es funktioniert korrekt auf dem Simulator, aber auf dem iPod (3.1.3) ergibt sich ein anderes Ergebnis. Beim ersten Abspielen des Films wird das Logo nicht dargestellt (Film oben). Aber sobald der Film fertig ist, wird die Spielmethode gecollt, ab dem zweiten Mal wird das Logo mit dem Film auf dem Hintergrund dargestellt (Is i was). Macht es dir einen Sinn?

Ich muss wirklich verstehen, wie dieses Problem zu beheben es ziemlich lächerlich ist ich bei der Entwicklung eines Spiels in 2 Monaten succeded haben und jetzt bin ich von 2 Wochen für das Startmenü stecken :)

Wie auch immer, wenn ich einzufügen beschlossen, den gesamten Code der Schicht versuche ich so zu fixieren, dass Sie besser herausfinden, was das Problem ist (oder zumindest das ist meine Hoffnung :))

+(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

Ich habe das gefunden: http://www.cocos2d-iphone.org/forum/topic/61 es einer seiner Kommentare sagt: "Es funktioniert nicht, weil das ImageView der openGLView hinzugefügt wird. Scheint, dass cocos2d könnte nicht auf dem UI-Objekt zeichnen. Die einzige Möglichkeit, dies zu tun, ist die Verwendung der Standard-UI-Methode, aber es ist keine Bequemlichkeit wie cocos2d, wenn Animation beteiligt ist ". Ist es möglich? das könnte hässlich sein ... – Sindico

Antwort

19

einige Zeit mit diesem I Nachdem er fand die Antwort. (Ich möchte das auch tun, aber später, also kann ich es jetzt gleich loslegen!)

Ich habe den Code und die Techniken in this link von Ascorbin, mit Hilfe von this link. Es ist nicht vollständig, wenn Sie auch die folgende Zeile zur EAGLView hinzufügen:

glView.opaque = NO; 

Der Film Ansicht entlang der Seite des EAGLView ist, und schob nach hinten zu bekommen, was Sie suchen. Sie müssen möglicherweise auch die Transparenz des EAGLView optimieren, wie es in diesem Beitrag erwähnt wird. Ich hoffe, das hilft.


Die Dinge, die ich ändern musste, sind hier aufgelistet.

Sie müssen mediaPlayer.framework zu einem Projekt Apfel hinzufügen und die folgende Zeile in AppDelegate .h:

#import <MediaPlayer/MediaPlayer.h> 

In CCDirector der setGLDefaultValues Methode gesetzt glClearColor Alpha 0.0f sein nicht 1.0f:

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

Wenn Ihr EAGLView in applicationDidFinishLaunching: ändern folgende Dinge zu schaffen:

die pixelFor

ändern

// kEAGLColorFormatRGB565 
kEAGLColorFormatRGBA8 

Achten Sie auf die EAGLView als Teilansicht hinzuzufügen (und macht es nicht opak) und nicht als die Hauptansicht:

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

Schließlich Matte aus dem alten Wert, dies zu sein , bevor Sie Ihre Szene starten, können Sie Ihren Code hinzufügen, um den Loop-Film abzuspielen. Ich habe dem App-Delegierten eine Methode hinzugefügt. Sie können auch eine Methode hinzufügen, um zu verhindern, dass Ihr Film hier im App-Delegaten abgespielt wird, und auch, wann (wenn?) Sie Ihren Film entfernen müssen.

[self startMovie]; 

und das Verfahren selbst:

- (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]; 
    } 
} 

Beachten Sie, dass Sie müssen den Betrachter nicht stimmen, wie in dem verknüpften Beispiel aufgeführt ist, noch die Funktion, den Film zu wiederholen, wird dies automatisch mit die Option "MPMovieRepeatModeOne". Wenn der Film nicht wiederholt werden soll, können Sie auch hier die Option "MPMovieRepeatModeNone" wählen.

Ich sollte auch beachten, dass ich nicht konnte, dass dies mit der alten API vor 3.2 funktioniert (so in Ihrem 3.1.3 Fall es nicht funktionierte), das Video wurde nicht durch die EAGLView angezeigt. Ich bin mir nicht sicher, was dort passiert, aber ich habe keine konkreten Möglichkeiten gesehen, was ich dagegen tun kann.

+0

+1 für eine ausgezeichnete Antwort. –

Verwandte Themen