cocos2d:在菜单背景中播放视频

17

我有一个CCLayer,其中包含了我的应用程序的开始菜单,我希望在背景中播放一个短片。我已经成功在glView中播放了电影,但是当它播放时,菜单没有显示出来。 为了处理电影,我实例化了一个MPMoviePlayerController,然后将其视图添加到glView中,如下所示:

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

我看到这个问题与以下问题非常相似:

如何在播放 iPhone Cocos2d 视频时显示菜单

但是我想知道是否有更好的解决方案,可能一个能让我仍然可以利用 cocos2d 框架实体(而非自己的视图)的方案。

我尝试过将 moviePlayer.view 发送到后面,代码如下:

[theView sendSubviewToBack:moviePlayer.view];

但是菜单仍然被电影隐藏...

(几个小时后...)

好的,正如你可以在第一条评论中读到的那样,我已经意识到(可能)唯一的方法是利用自定义视图。我这样做了,在模拟器上运行良好,只需要在moviePlayer.view之后添加任何视图到glView中。然而,当我在我的目标iPod touch上使用3.1.3 FW运行它时,电影视图总是在最上面。 因此,我已经意识到MPMoviePlayerController实际上创建了它自己的窗口和视图。一些帖子(比如这篇Overlay on top of Streaming MPMoviePlayerController)建议截取新窗口加载的事件,然后再添加子视图。

我试图这样做,但实际上从未捕获到这个事件,无论是在模拟器上还是在目标iPod上。因此,我添加了一个定期的选择器-(void)update,它的实现方式如下:

-(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秒钟,当电影实际播放时,将我的标志视图作为movieplayer的子视图添加。在模拟器上它可以正确工作,但在iPod(3.1.3)上会得到不同的结果。第一次播放电影时,标志没有显示出来(电影在上方)。但是,自从电影完成播放方法被调用以来,从第二次开始,标志就和电影背景一起显示了(如果我这么说的话)。你能理解吗?

我真的需要知道如何解决这个问题,这相当荒谬,我已经成功地在两个月内开发了一个游戏,现在却被启动菜单卡住了两个星期:)

无论如何,如果我决定粘贴我试图修复的整个层的代码,以便您更好地了解问题是什么(或者至少这是我的希望:))

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

我发现了这个链接:http://www.cocos2d-iphone.org/forum/topic/61 里面的一个评论说:“它不能工作,因为imageView添加到了openGLView上。似乎cocos2d不能在UI对象上绘制。唯一的方法是使用标准的UI方法,但当涉及动画时,它并不方便。”这可能吗?那可能会很难看... - Andrea Sindico
1个回答

19

在花费一些时间后,我找到了答案。(我也想做这个,但是稍后再做,所以我最好现在就开始!)

我使用了 ascorbin 在 这个链接 中的代码和技巧,并得到了 这个链接 的帮助。除非您还向 EAGLView 添加以下行,否则它不完整:

glView.opaque = NO;

电影视图位于EAGLView旁边,并被推到后面以获得您想要的效果。您可能还需要像那篇帖子中提到的那样调整EAGLView的透明度。希望这可以帮助。


我需要修改的内容在此列出。

您需要将苹果的mediaPlayer.framework添加到您的项目中,并在您的应用程序委托.h文件中包含以下行:

#import <MediaPlayer/MediaPlayer.h>

在CCDirector的setGLDefaultValues方法中,将glClearColor的alpha值设为0.0f而不是1.0f:

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

applicationDidFinishLaunching:中创建EAGLView时,请更改以下内容:

将像素格式从旧值更改为以下内容:

// 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中。我不确定发生了什么,但我没有看到有关如何解决此问题的具体选项。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接