cocos2d start / stop running Scene - cocos2d-iphone

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).

Related

Cocos2d restart current scene

I've got an end of level layer added to game, each level has its own scene. I want to be able to restart the current scene. Obviously the scene will change but the layer will remain the same. How is this done. I've tried-
CCScene *currentScene = [[CCDirector sharedDirector]runningScene];
[[CCDirector sharedDirector]replaceScene:currentScene];
Thanks
This does not work because you can't replace the same scene object with itself:
CCScene *currentScene = [[CCDirector sharedDirector]runningScene];
[[CCDirector sharedDirector]replaceScene:currentScene];
Instead you have to create a new instance of your scene, like so:
[[CCDirector sharedDirector] replaceScene:[YourSceneClass scene]];
If you don't know what the current scene class is, then this ought to work:
CCScene *currentScene = [CCDirector sharedDirector].runningScene;
CCScene *newScene = [[[currentScene class] alloc] init];
[[CCDirector sharedDirector] replaceScene:newScene];
Assuming you're using ARC as everyone should these days. Otherwise add an autorelease.
I ran into the same problem. I tried this
CCScene *currentScene = [CCDirector sharedDirector].runningScene;
CCScene *newScene = [[[currentScene class] alloc] init];
[[CCDirector sharedDirector] replaceScene:newScene];
and it gave me a blank screen.
The problem is this line
CCScene *newScene = [[[currentScene class] alloc] init];
[currentScene class] actually returns CCScene..
Hence
[CCScene alloc] init] gives us a blank screen.
The way how I got around this problem was by setting tag for each of my scene class.
For example:
+(CCScene *) scene
{
// 'scene' is an autorelease object.
CCScene *scene = [CCScene node];
scene.tag = 1;
// 'layer' is an autorelease object.
GameOneLayer * layer = [[[GameOneLayer alloc] init];
// add layer as a child to scene
[scene addChild: layer];
// return the scene
return scene;
}
Hope this helps.

Resume game loop in cocos2d

I have a game with animation. In game scene, I use the method below to pause my game (it works perfectly, because the game is paused when the users taps on any point of the iOS device):
-(void)ccTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch=[touches anyObject];
CGPoint locationOfTouch=[self convertTouchToNodeSpace: touch];
CGRect rectOfScreen=CGRectMake(0, 0, screenSize.width, screenSize.height);
if (CGRectContainsPoint(rectOfScreen, locationOfTouch))
{
[[CCDirector sharedDirector] replaceScene:[PauseScene scene]];
[self unschedule:#selector(spawnEnemies:)];
[self unschedule:#selector(checkCollisionOfEnemyWithBullet:)];
[self unschedule:#selector(update:)];
[self unschedule:#selector(isJoystickActivated:)];
[self unschedule:#selector(checkHasGameEnded:)];
[[CCDirector sharedDirector] pause];
}
}
To implement resume action, I'v created PauseLayer:CCLayer, where I've implemented the following method to resume the game:
-(void) continueGame:(id)sender
{
[[CCDirector sharedDirector] resume];
[[CCDirector sharedDirector] replaceScene:[GameSceneLayer scene]];
//[self resumeSchedulerAndActions];
}
Here is the code, how I envoke the method above:
CCMenuItemFont* continue_game=[CCMenuItemFont itemWithString:#"continue game" target:self selector:#selector(continueGame:)];
But, when I select continue game, the game start from the blank point: every game state, every game character will be new. How can I resume my game from the intial point where it was paused by user? Thank you!
You can use these two cocos2D function to pause and resume:
[self pauseSchedulerAndActions]; //pause
[self resumeSchedulerAndActions];//resume
Also maintain one bool variable, and check that whenever u need.
bool mISGamePaused;

How do I get the center of the screen in cocos2d?

How do I get the world space coordinate of point that is in the center of the screen, in Cocos2d-iPhone?
Simple, just take the height and width and divide it by 2
CGSize winSize = [[CCDirector sharedDirector] winSize];
CGPoint point = ccp(winSize.width/2, winSize.height/2);
Here is a somewhat more advanced way to do it.
This will also work if you have called setPosition on the parent of the sprite (=self in this example)
CGSize winSize = [[CCDirector sharedDirector] winSize];
CCSprite* centerSprite = [CCSprite spriteWithFile:#"sprite"];
CGPoint centerPoint = ccpSub(ccp(winSize.width/2, winSize.height/2), [self position]);
[centerSprite setPosition:centerPoint];
[self addChild: centerSprite];
You can get the exact center of the screen no matter what framework you are using, Cocos or not, and also even if Cocos is not set to use the entire screen (such is the case sometimes if you crop Cocos to make room for ads) by doing something like this:
int width=[[UIScreen mainScreen] bounds].size.width
int height=[[UIScreen mainScreen] bounds].size.height
CGPoint center=ccp(width/2,height/2);
Note the ccp macro works in Cocos only; otherwise, use CGPointMake

Switching scenes with inputs

Here's the code I know to change scenes with cocos2d:
[[CCDirector sharedDirector] replaceScene:[HelloWorld scene]];
But I wonder if it's possible I can switch the scenes with some parameters.
I tried this method:
HelloWorld *scene = [HelloWorld scene];
[scene initWithInput:0];
[[CCDirector sharedDirector] replaceScene:scene];
-(void)initWithInput:(int)input is what I wrote for test in HelloWorld class.
And it does't work, does any one know how to do it?
Try overriding the scene method. Something like
+(id) sceneWithInput:(int) i
{
// 'scene' is an autorelease object.
CCScene *scene = [CCScene node];
// 'layer' is an autorelease object.
HelloWorld *layer = [HelloWorld nodeWithInput:i];
// add layer as a child to scene
[scene addChild: layer];
// return the scene
return scene;
}
Then you would call
[[CCDirector sharedDirector] replaceScene:[HelloWorld sceneWithInput:0]];

cocos2d and MPMoviePlayerController crash

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