cocos2d: воспроизведение видео на фоне меню
У меня есть CCLayer с меню "Пуск" моего приложения, и я хотел бы, чтобы на заднем плане воспроизводился короткий фильм. Мне удалось воспроизвести фильм в glView, но когда он воспроизводится, меню не отображается. Для обработки фильма я создаю экземпляр MPMoviePlayerController, а затем добавляю его представление в glView следующим образом:
[[[CCDirector sharedDirector] openGLView] addSubview:moviePlayer.view];
Я видел, что этот вопрос был очень похож
Как иметь меню при воспроизведении фильма-iphone cocos2d
но я хотел бы знать, есть ли лучшее решение для этого, возможно, такое, которое позволило бы мне все еще использовать объекты каркаса cocos2d (а не мои собственные взгляды).
Я попытался отправить moviePlayer.view обратно таким образом
[theView sendSubviewToBack:moviePlayer.view];
но меню все еще скрыто фильмом...
(много часов спустя..)
Хорошо, как вы можете прочитать в первом комментарии, я понял, что (возможно) единственный способ - использовать пользовательские представления. Я сделал это, и он запускается в симуляторе, добавляя любые виды в glView после moviePlayer.view. Однако, когда я запускаю его на своем IPod touch с 3.1.3 FW, просмотр фильма всегда на высоте. Поэтому я понял, что MPMoviePlayerController фактически создает свое собственное окно и свое собственное представление. В некоторых публикациях (например, это наложение поверх потокового 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];
}
1 ответ
Потратив некоторое время с этим, я нашел ответ. (Я тоже хочу сделать это, но позже, так что я могу с этим начать!)
Я использовал код и методы в этой ссылке от ascorbin, с помощью этой ссылки. Это не завершено, если вы также не добавите следующую строку в EAGLView:
glView.opaque = NO;
Вид фильма расположен вдоль стороны EAGLView и отодвинут назад, чтобы получить то, что вы ищете. Возможно, вам также придется настроить прозрачность EAGLView, как это упоминается в этом посте. Надеюсь, это поможет.
Вещи, которые мне нужно было изменить, перечислены здесь.
Вам нужно добавить яблоко mediaPlayer.framework
к вашему проекту и включите следующую строку в ваш делегат приложения.h:
#import <MediaPlayer/MediaPlayer.h>
В CCDirector's setGLDefaultValues
метод, установите альфа glClearColor равным 0.0f, а не 1.0f:
// glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
При создании вашего EAGLView в applicationDidFinishLaunching:
изменить следующие вещи:
Измените pixelFormat со старого значения на следующее:
// 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".
Я также должен отметить, что мне не удалось заставить это работать со старым API до 3.2 (так что в вашем случае 3.1.3 он не работал), видео не показывалось через EAGLView. Я не уверен, что там происходит, но я не видел конкретных вариантов того, что с этим делать.