2010-12-15 14 views
17

我有一個CCLayer與我的應用程序的開始菜單,我想在後臺播放短片。 我已經成功地在glView中播放電影,但播放菜單時沒有描述。 要處理的電影我實例化的MPMoviePlayerController 然後我添加視圖到glView這樣:cocos2d:在菜單背景中播放視頻

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

我已經看到了這個問題頗爲相似

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

但我想知道是否有更好的解決方案,可能會讓我仍然利用cocos2d框架實體(而不是我自己的視圖)。

我試圖發送moviePlayer.view來支持這一方式

[theView sendSubviewToBack:moviePlayer.view]; 

但菜單STIL由電影隱藏...

(多小時後..)

好吧,你可以在第一個評論中看到我已經意識到(可能)唯一的方法是利用自定義視圖。我做到了,它通過在moviePlayer.view之後向glView中添加任何視圖來在模擬器中運行。但是,當我在3.1.3 FW的目標IPod touch上運行它時,電影視圖總是處於頂部。 因此,我已經意識到MPMoviePlayerController實際上創建了自己的窗口和它自己的視圖。有些帖子(如Overlay on top of Streaming MPMoviePlayerController)建議攔截新窗口加載的事件,然後添加子視圖。

這就是我試圖做的事情,但事實上從來沒有在模擬器上或目標Ipod上捕捉到。 因此,我已加入計劃的選擇 - 這是實現這種方式(空)更新:

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

但電影仍然在上面

請你們任何幫助將非常感謝!

(幾天後...) 我也等了2秒,而電影實際上正在運行,以添加我的標識視圖作爲電影播放器​​的子視圖。它可以在模擬器上正常工作,但是在Ipod(3.1.3)上它會產生不同的結果。電影第一次播放時,徽標沒有被描繪(電影在最上面)。然而,因爲一旦電影完成播放方法被冷卻,從第二次開始,標誌被描述爲背景上的電影(我是否會)。這對你有意義嗎?

我真的需要了解如何解決這個問題,這是挺可笑的我在發展中2個月的比賽已經succeded,現在我2周卡住開始菜單:)

反正如果我有決定貼,我想解決,這樣就可以更好地找出問題所在層的整個代碼(或至少這是我的希望:))

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

我發現這個:http://www.cocos2d-iphone.org/forum/topic/61它的一個評論說:「它不工作,因爲imageView被添加到openGLView。似乎cocos2d可以不要使用UI對象,唯一的方法就是使用標準的UI方法,但是當涉及動畫時,它不像cocos2d那樣方便「。可能嗎?那可能不好... – Sindico 2010-12-16 20:16:33

回答

19

花一些時間與此我後找到答案。 (我也想這樣做,但後來,所以我不妨現在就開始吧!)

我使用了ascorbin在this link中的代碼和技術,在this link的幫助下。這是不完整的,除非你也以下行添加到EAGLView:

glView.opaque = NO; 

這部電影的看法是沿EAGLView的一側,並推到後面讓你在找什麼。您可能還需要調整EAGLView的透明度,就像它在該帖子中提到的那樣。希望有所幫助。


我需要修改的東西在這裏列出。

您需要蘋果的mediaPlayer.framework添加到您的項目,並在您的應用程序代理的.h以下行:

#import <MediaPlayer/MediaPlayer.h> 

在CCDirector的setGLDefaultValues方法,設置glClearColor的阿爾法是0.0F不1.0F:

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

applicationDidFinishLaunching:變化創建EAGLView以下的事情:

更改pixelFor從舊的價值墊是這樣的:

// kEAGLColorFormatRGB565 
kEAGLColorFormatRGBA8 

確保將EAGLView添加爲子視圖(並使其不不透明),而不是作爲主要的觀點:

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

最後,在運行你的場景之前,你可以添加你的代碼來播放循環電影。我爲此應用程序委託添加了一個方法。您還可以添加一種方法來停止在應用程序委託中播放電影,以及何時(如果?)您需要刪除電影。

[self startMovie]; 

和方法本身:

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

注意,您不必添加像在鏈接的示例中列出的觀察者,也沒有功能重複的電影,這是自動完成的'MPMovieRepeatModeOne'選項。如果你不想讓電影重複播放,你也可以在這裏選擇'MPMovieRepeatModeNone'選項。

我還應該注意到,我無法使用舊的3.2之前的API(因此在你的3.1.3的情況下它不工作),視頻沒有通過EAGLView顯示。我不確定那裏發生了什麼,但我沒有看到如何處理這個問題。

+0

+1爲優秀的答案。 – 2013-05-26 04:03:52