cocos2d and MPMoviePlayerController crash - cocos2d-iphone

I try to show an intro and replaceScene when the intro has finished. But, when the movie finish, app is crashing on [[CCDirector sharedDirector] replaceScene:[CCFadeTransition transitionWithDuration:0.5f scene:[MenuScene scene]]];.
code is;
- (void) moviePlayBackDidFinish {
[self.moviePlayer stop];
[[CCDirector sharedDirector] replaceScene:[CCFadeTransition transitionWithDuration:0.5f scene:[MenuScene scene]]];
}
-(id) init
{
// always call "super" init
// Apple recommends to re-assign "self" with the "super" return value
if( (self=[super init] )) {
//pencere boyutu elde ediliyor
NSURL *url = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:#"intro" ofType:#"mp4"]];
self.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:self.moviePlayer];
if ([self.moviePlayer respondsToSelector:#selector(setFullscreen:animated:)]) {
// Use the new 3.2 style API
self.moviePlayer.controlStyle = MPMovieControlStyleNone;
self.moviePlayer.shouldAutoplay = YES;
// This does blows up in cocos2d, so we'll resize manually
// [moviePlayer setFullscreen:YES animated:YES];
[self.moviePlayer.view setTransform:CGAffineTransformMakeRotation((float)M_PI_2)];
CGSize winSize = [[CCDirector sharedDirector] winSize];
self.moviePlayer.view.frame = CGRectMake(0, 0, winSize.height, winSize.width);// width and height are swapped after rotation
[[[CCDirector sharedDirector] openGLView] addSubview:self.moviePlayer.view];
} else {
// Use the old 2.0 style API
self.moviePlayer.movieControlMode = MPMovieControlModeHidden;
[self.moviePlayer play];
}
}
return self;
}

This line:
selector:#selector(moviePlayBackDidFinish:)
should be:
selector:#selector(moviePlayBackDidFinish)

CCScene* scene = [AboutLayer scene];
CCTransitionFade* transitionScene = [CCTransitionFade transitionWithDuration:0.1 scene:scene withColor:ccWHITE];
[[CCDirector sharedDirector] pushScene:transitionScene];

Related

Disable iAds on Different Scene Cocos2d 3.0

I finally have iAds working, how would I make is so the ads dont show up on my game scene?
This is my iAds code
- (id)init
{
{
if ([ADBannerView instancesRespondToSelector:#selector(initWithAdType:)]) {
_adView = [[ADBannerView alloc] initWithAdType:ADAdTypeBanner];
} else {
_adView = [[ADBannerView alloc] init];
}
_adView.requiredContentSizeIdentifiers = [NSSet setWithObject:ADBannerContentSizeIdentifierPortrait];
_adView.currentContentSizeIdentifier = ADBannerContentSizeIdentifierPortrait;
[[[CCDirector sharedDirector]view]addSubview:_adView];
[_adView setBackgroundColor:[UIColor clearColor]];
[[[CCDirector sharedDirector]view]addSubview:_adView];
_adView.delegate = self;
}
return self;
}
To stop the iAd from staying even though a scene has been changed add
[_adView removeFromSuperview]
To where the Scene is being changes so it look like this
- (void)onscoreButtonClicked:(id)sender
{
// start spinning scene with transition
[[CCDirector sharedDirector] replaceScene:[HighScoreScene scene]
withTransition:[CCTransition transitionPushWithDirection:CCTransitionDirectionUp duration:1.0f]];
[_adView removeFromSuperview];
}
Thank you to LearnCocos2d

Cocos2d: How to play a video in the background of a CCLayer

I want the video play in the background, and the text label in the front, run the following code, video is playing, but text label does not show!
-(id) init {
if(!(self=[super init])) {
return nil;
}
CGSize size = [[CCDirector sharedDirector] winSize];
// MP4
NSURL *url = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:#"test" ofType:#"m4v"]];
moviePlayer = [[MPMoviePlayerController alloc] initWithContentURL:url];
[moviePlayer respondsToSelector:#selector(setFullscreen:animated:)];
moviePlayer.controlStyle = MPMovieControlStyleNone;
moviePlayer.shouldAutoplay = YES;
moviePlayer.repeatMode = MPMovieRepeatModeOne;
moviePlayer.view.frame = CGRectMake(0, 0, size.height, size.width);
[viewController.view addSubview:moviePlayer.view];
[viewController.view sendSubviewToBack:moviePlayer.view];
// create and initialize a Label
CCLabelTTF *label = [CCLabelTTF labelWithString:#"Hello World" fontName:#"Marker Felt" fontSize:64];
label.position = ccp( size.width /2 , size.height/2 );
[self addChild: label];
return self;
}
I found the answer:
First in AppDelegate.m replace kEAGLColorFormatRGB565 with kEAGLColorFormatRGBA8, Second, as the following code, the last 4 lines is important:
NSURL *url = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:#"video" ofType:#"mp4"]];
_moviePlayer = [[MPMoviePlayerController alloc] initWithContentURL:url];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(moviePlayBackDidFinish)
name:MPMoviePlayerPlaybackDidFinishNotification
object:_moviePlayer];
[_moviePlayer respondsToSelector:#selector(setFullscreen:animated:)];
_moviePlayer.controlStyle = MPMovieControlStyleNone;
_moviePlayer.shouldAutoplay = YES;
_moviePlayer.repeatMode = MPMovieRepeatModeOne;
_moviePlayer.view.frame = CGRectMake(0, 0, 300, 300);
UIView* glView = [CCDirector sharedDirector].openGLView; // attention
[glView.superview insertSubview:_moviePlayer.view atIndex:0]; // attention
glView.opaque = NO; // attention
glClearColor(0.0f, 0.0f, 0.0f, 0.0f); // attention
CCVideo player in one of the best options to play video in cocos2D project
[CCVideoPlayer setDelegate: self];
[CCVideoPlayer playMovieWithFile: #"bait.m4v"];

- (BOOL)ccTouchBegan responds on simulator but not on device

I am working on a Pause screen menu for a game. After displaying the pause screen, I have the user touch the screen to hide the pause screen and resume the game. This works perfect on the simulator but doesn't work when I test on an actual device. It seems that the device doesn't respond to touches specifically for the pause menu. Every other part of the game works fine on both the simulator and device. It's weird how it does work on the simulator but not on the device. This is the code I have for the pause screen:
- (id)init {
if ((self = [super init])) {
CGSize windowSize = [[CCDirector sharedDirector] winSize];
//windowSize.height = 768.0;
//windowSize.width = 1024.0;
CCSprite *whiteScreen = [CCSprite spriteWithFile:#"OutOfTime.png"];
whiteScreen.position = ccp(windowSize.width / 2, windowSize.height / 2);
[self addChild:whiteScreen];
CCLabelTTF *touchToDismiss = [CCLabelTTF labelWithString:#"Touch screen to continue" fontName:#"Marker Felt" fontSize:30];
touchToDismiss.color = ccBLACK;
touchToDismiss.position = ccp(windowSize.width / 2, 20);
[self addChild:touchToDismiss];
}
return self;
}
- (void)onEnter {
[super onEnter];
[[CCTouchDispatcher sharedDispatcher] addTargetedDelegate:self priority:0 swallowsTouches:NO];
}
- (void)gameOverWithScore:(NSInteger)score {
CGSize windowSize = [[CCDirector sharedDirector] winSize];
//windowSize.height = 768.0;
//windowSize.width = 1024.0;
CCLabelTTF *touchToDismiss = [CCLabelTTF labelWithString:#"Game Over" fontName:#"Marker Felt" fontSize:75];
touchToDismiss.color = ccBLACK;
touchToDismiss.position = ccp(windowSize.width / 2, windowSize.height / 2 + 40);
[self addChild:touchToDismiss];
NSString *scoreString = [NSString stringWithFormat:#"Final Score: %d", score];
CCLabelTTF *scoreLabel = [CCLabelTTF labelWithString:scoreString fontName:#"Marker Felt" fontSize:60];
scoreLabel.color = ccBLACK;
scoreLabel.position = ccp(windowSize.width / 2, (windowSize.height / 2) - 40);
[self addChild:scoreLabel];
}
- (void)setMessage:(NSString *)message {
}
- (void)dealloc {
[super dealloc];
}
- (BOOL)ccTouchBegan:(NSSet *)touches withEvent:(UIEvent *)event {
NSLog(#"haha");
return YES;
}
You probably should add the following line on your init
self.isTouchEnabled = YES;
You have to do this for every CCLayer you have that has touch events.
EDIT: just noticed that your ccTouchBegan only prints a Log.
This log is easily viewed in the debug window of XCode, but in the device it is hidden from the user.
Try doing something else.

cocos2d start / stop running Scene

I'm trying to load one scene. This runs fine the first time, but when I try to reload again appears a white square where the animation is placed.
This is the code to start and stop the scene. What I'm missing?
thanks.
-(void)runScene:(OTAnimationCC2d *)animation
{
scene = [CCScene node];
[scene addChild:animation];
if ([[[CCDirector sharedDirector] runningScene] isRunning])
{
[[CCDirector sharedDirector] replaceScene:scene];
}
else
{
[[CCDirector sharedDirector] runWithScene:scene];
}
}
-(void)stopScene
{
[[[CCDirector sharedDirector] runningScene] stopAllActions];
[[[CCDirector sharedDirector] runningScene] removeAllChildrenWithCleanup:YES];
[[CCDirector sharedDirector] pushScene:scene];
}
Why not just call [self runScene] at the end of stopScene rather than [[CCDirector sharedDirector] pushScene:scene]? It sounds like you want the scene to reload fresh, which your runScene already does when it calls replaceScene.
Either way you should be creating a new scene node and using replaceScene (which is being done in runScene and is why I recommend just calling that).

Cocos2D: SneakyJoystick + Touch Events, problem

im having some trouble using SneakyJoystick and ccTouchEnded stuff.
What is my goal, use the joystick to walk around and the touches to interact with the surrounding area.
I have two layers,ControlLayer (z:2) and GamePlayLayer (z:1)
Im Using TiledMap for my ground and map.
The Joystick by it self works fine, it is attached to the ControlLayer. I can walk, colide and stuff.
When i add the Touch events to the GamePlayLayer, the touch works, i can click on something on the "ground" and interact with it. BUT my joystick dosent work then, if i run using the touch the joystick just sit there not responsive.
Here is some of my code, if u guys need more, just ask.
Touch methods in the GameplayLayer
-(void) registerWithTouchDispatcher
{
[[CCTouchDispatcher sharedDispatcher] addTargetedDelegate:self
priority:0 swallowsTouches:YES];
}
-(BOOL) ccTouchBegan:(UITouch *)touch withEvent:(UIEvent *)event
{
return YES;
}
-(void) ccTouchEnded:(UITouch *)touch withEvent:(UIEvent *)event
{
CGPoint touchLocation = [touch locationInView: [touch view]];
touchLocation = [[CCDirector sharedDirector] convertToGL: touchLocation];
touchLocation = [self convertToNodeSpace:touchLocation];
CGPoint tileCoord = [self tileCoordForPosition:touchLocation];
int tileGid = [meta tileGIDAt:tileCoord];
if (tileGid) {
NSDictionary *properties = [tileMap propertiesForGID:tileGid];
if (properties) {
NSString *collectable = [properties valueForKey:#"Collectable"];
if (collectable && [collectable compare:#"True"] == NSOrderedSame) {
[meta removeTileAt:tileCoord];
[foreground removeTileAt:tileCoord];
}
}
}
}
And how my scene is arranged:
#implementation SandBoxScene
-(id)init {
self = [super init];
if (self!=nil) {
//Control Layer
controlLayer = [GameControlLayer node];
[self addChild:controlLayer z:2 tag:2];
//GamePlayLayer
GameplayLayer *gameplayLayer = [GameplayLayer node];
[gameplayLayer connectControlsWithJoystick:[controlLayer leftJoyStick]
andJumpButton:[controlLayer jumpButton]
andAttackButton:[controlLayer attackButton]];
[self addChild:gameplayLayer z:1 tag:1];
}
return self;
}
#end
Thanks for the help!
The problem is that your code does not account for multiple touches. Using -(BOOL) ccTouchBegan:(UITouch *)touch.. or -(void) ccTouchEnded:(UITouch *)touch.. will only take one touch... instead you need to use ccTouchesEnded:.. your method should look something like this:
-(void)ccTouchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
//get your touch from the set of UITouches
UITouch *myTouch = [touches anyObject];
//the rest below is the same from your method
CGPoint touchLocation = [myTouch locationInView: [myTouch view]];
touchLocation = [[CCDirector sharedDirector] convertToGL: touchLocation];
touchLocation = [self convertToNodeSpace:touchLocation];
CGPoint tileCoord = [self tileCoordForPosition:touchLocation];
int tileGid = [meta tileGIDAt:tileCoord];
if (tileGid) {
NSDictionary *properties = [tileMap propertiesForGID:tileGid];
if (properties) {
NSString *collectable = [properties valueForKey:#"Collectable"];
if (collectable && [collectable compare:#"True"] == NSOrderedSame) {
[meta removeTileAt:tileCoord];
[foreground removeTileAt:tileCoord];
}
}
}
}
You also need to add [glView setMultipleTouchEnabled:YES]; to your appDelegate. I am not entirely sure that the method above works. This question deals with implementing multitouch with cocos2d. Hope this helps
Sorry thats was not the solution, i do want to handle just one touch, the problem was in the priority, i was giving priority 0 to my gameplayLayer, and swalloing every time, so i didnt give chance to the controlayer that had priority 1 to get the touch and act upon my joystick.
The solution that i found was changing the priority from 0 to 2 then, the (controlLayer) joystick would act and pass the touch to the priority 2, that was my gameplayLayer
but thanks anyway :)