我有一个CCLayer,我的应用程序的开始菜单,我想在后台播放一部短片。 我已经成功地在glView中播放了一部电影,但是当它播放时,菜单没有被描绘出来。 为了处理电影,我实例化了一个MPMoviePlayerController 然后我以这种方式将其视图添加到glView:
[[[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];
但菜单仍被电影隐藏......
(许多小时后......)
好的,你可以在第一条评论中看到我已经意识到(可能)唯一的方法是利用自定义视图。我这样做了,它通过在moviePlayer.view之后向glView添加任何视图在模拟器中运行。然而,当我在3.1.3 FW的目标IPod触摸上运行它时,电影视图始终位于顶部。 因此我意识到MPMoviePlayerController实际上创建了自己的窗口和自己的视图。一些帖子(如此Overlay on top of Streaming MPMoviePlayerController)建议拦截加载新窗口的事件,然后才添加子视图。
这就是我试图做的事情,但该事件实际上从未在模拟器上或在目标Ipod上捕获。 因此,我添加了一个预定的选择器 - (void)更新,它以这种方式实现:
-(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个月内成功开发游戏是非常荒谬的,现在我在开始菜单的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 :(得分:19)
花了一些时间后,我找到了答案。 (我也想这样做,但是后来,所以我现在可以开始吧!)
我在this link的帮助下,使用了ascorbin在this link中的代码和技巧。除非您还将以下行添加到EAGLView:
,否则它不完整glView.opaque = NO;
电影视图位于EAGLView的旁边,然后推到后面以获取您要查找的内容。您可能还需要像在该帖子中提到的那样调整EAGLView的透明度。希望有所帮助。
这里列出了我需要修改的内容。
您需要将Apple的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时,请更改以下内容:
将pixelFormat从旧值更改为:
// kEAGLColorFormatRGB565
kEAGLColorFormatRGBA8
确保将EAGLView添加为子视图(并使其不透明)而不是作为主视图:
// [viewController setView:glView];
[viewController.view addSubview:glView];
glView.opaque = NO;
最后,在运行场景之前,您可以添加代码来播放循环影片。为此,我向app delegate添加了一个方法。您还可以添加一种方法来阻止您的电影在应用代理中播放,以及何时(如果?)您需要删除电影。
[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显示。我不确定那里发生了什么,但我没有看到有关该怎么做的具体选择。