我有一个CCLayer,其中包含了我的应用程序的开始菜单,我希望在背景中播放一个短片。我已经成功在glView中播放了电影,但是当它播放时,菜单没有显示出来。 为了处理电影,我实例化了一个MPMoviePlayerController,然后将其视图添加到glView中,如下所示:
[[[CCDirector sharedDirector] openGLView] addSubview:moviePlayer.view];
我看到这个问题与以下问题非常相似:
但是我想知道是否有更好的解决方案,可能一个能让我仍然可以利用 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];
}