Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

cocos2d: playing a video in the background of a menu

I have a a CCLayer with the start menu of my app and I would like to have a short movie playing in the background. I have succeded in playing a movie in the glView but when it plays the menu is not depicted. To handle the movie I instantiate a MPMoviePlayerController and then I add its view to the glView this way:

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

I have seen this question was quite similar

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

but I would like to know if there is a better solution to it, possibly one that would let me still exploit the cocos2d framework entities (and not my own views).

I have tried to send the moviePlayer.view to back this way

[theView sendSubviewToBack:moviePlayer.view];

but the menu is stil hidden by the movie...

(many hours later..)

Ok as you can read in the first comment i have realized that (probably) the only way is exploiting custom views. I did that and it runs in the simulator by adding any views to the glView after the moviePlayer.view. However when i run it on my target IPod touch with a 3.1.3 FW the movie view is always on top. I have therefore realized the MPMoviePlayerController actually creates its own window and its own view. Some post (like this Overlay on top of Streaming MPMoviePlayerController) suggest to intercept the event the new window is loaded and only then adding the subviews.

that is what I tried to do but that event is actually never catched neither on the simulator nor on the target Ipod. I have therefore added a scheduled selector -(void) update which is implemented this way:

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

but the movie still remains on top

please guys any help would very appreciated!

(some days later...) I have also waited for 2 seconds, while the movie is actually running, to add my logo view as a subview of the movieplayer. It works correctly on the simulator but on the Ipod (3.1.3) it turns out a different result. The first time the movie is played the logo is not depicted (movie on top). However, since as soon as the movie finishes the play method is colled, starting from the second time the logo is depicted with the movie on the background (Is i would). Does it make any sense to you?

I really need to understand how to fix this issue it is quite ridiculous I have succeded in developing a game in 2 months and now i am stuck from 2 weeks for the start menu :)

Anyway if I have decided to paste the whole code of the layer I am trying to fix so that you can better figure out what the problem is (or at least that is my hope :) )

+(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];
}
like image 711
Andrea Sindico Avatar asked Dec 15 '10 20:12

Andrea Sindico


People also ask

Is Cocos2d a game engine?

Cocos2d-x. Cocos2d-x is a mature open source cross-platform game development framework that supports 2D and 3D game creation. The engine provides rich functions such as graphics rendering, GUI, audio, network, physics, user input, etc., and is widely used in game development and interactive application construction.

What programming language does Cocos2d use?

Cocos2D suits companies that decide to build games and interactive apps that are 2D, developed with the C++ programming language, JavaScript, C# and Lua, and can be played on both Android and iOS mobile technologies, as well as across all the main operating systems (Windows, Mac, Linux).

Who made Cocos2d?

Cocos2d (Python) February 2008, in the town Los Cocos, near Córdoba, Argentina, Ricardo Quesada, a game developer, and Lucio Torre created a 2D game engine for Python with several of their developer friends.


1 Answers

After spending some time with this I found the answer. (I want to do this too, but later, so I may as well get it going now!)

I used the code and techniques in this link by ascorbin, with help from this link. It is not complete unless you also add the following line to the EAGLView:

glView.opaque = NO;

The movie view is along side of the EAGLView, and pushed to the back to get what you are looking for. You may also have to tweak the transparency of the EAGLView like it mentions in that post. Hope that helps.


The things I needed to modify are listed here.

You need to add apple's mediaPlayer.framework to your project and include the following line in your app delegate .h:

#import <MediaPlayer/MediaPlayer.h>

In CCDirector's setGLDefaultValues method, set glClearColor's alpha to be 0.0f not 1.0f:

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

When creating your EAGLView in applicationDidFinishLaunching: change the following things:

Change the pixelFormat from the old value to be this:

// kEAGLColorFormatRGB565
kEAGLColorFormatRGBA8

Make sure to add the EAGLView as a sub-view (and make it non-opaque) rather than as the main view:

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

Finally, before running your scene you can add your code to play the looping movie. I added a method to the app delegate for this. You could also add a method to stop your movie from playing here in the app delegate as well for when (if?) you need to remove your movie.

[self startMovie];

and the method itself:

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

Note that you do not have to add the observer like is listed in the linked example, nor the function to repeat the movie, this is done automatically with the 'MPMovieRepeatModeOne' option. If you don't want the movie to repeat you can choose the 'MPMovieRepeatModeNone' option here as well.

I should also note that I was unable to get this to work with the old pre-3.2 API (so in your 3.1.3 case it was not working), the video didn't show through the EAGLView. I am not sure what is happening there, but I have seen no specific options on what to do about that.

like image 75
slycrel Avatar answered Nov 14 '22 04:11

slycrel