I want to add a 'ready-go!' animation before game, as well as during game (need to pause the game)
i tried to use [CCDirector sharedDirector] pushScene: [Anim scene]], but although the background of Anim scene is smaller than window size, the transparent area is black instead of see through the scene below.
how can i implement it? (or i don't have to use pushScene at all? )
here is the code for GameScene, onEnter i schedule the 'count' (timer), onExit i unschedule it.
-(void) onEnter {
GameManager* sharedManager = [GameManager sharedManager];
[[CCScheduler sharedScheduler] scheduleSelector:#selector(count) forTarget:sharedManager interval:1.0f paused:NO];
[super onEnter];
}
- (void)onExit {
GameManager* sharedManager = [GameManager sharedManager];
[[CCScheduler sharedScheduler] unscheduleSelector:#selector(count) forTarget:sharedManager];
[super onExit];
}
problem solved. I just create a scene specifically for the 'ready-set-go' animation, pass the necessary parameters to the AnimationScene, then launch the game from the AnimationScene using scheduler.
The result is not as good as 'ready-go' sign on top of GameScene since i am not able to make the transparent effect, but i tried to mimic the background of game scene, and it turns out quite well.
- (void)pauseButtonTapped {
[[CCDirector sharedDirector] pause];
[self pauseSchedulerAndActions];
}
- (void)playButtonTapped {
[[CCDirector sharedDirector] resume];
[self resumeSchedulerAndActions];
}
CCSequence. Before enabling AI timers or whatever runs your game objects, run a CCSequence action.
Related
I'm trying to implement some logic in my application delegate methods. It would be really helpful to know which kind of scene is currently running.
[[CCDirector sharedDirector] runningScene] returns the scene currently running.
Is there some sort of comparison or function to check if it is an instance of my [MainMenuLayer scene] or [gameScene scene] or something like that?
I'm not quite sure to how to use isKindOfClass or isEqual, or if they are applicable in this case. Thanks
As you assumed, you have to use isKindOfClass.
if ([[[CCDirector sharedDirector] runningScene] isKindOfClass:[MySceneClass class]]) {
// Running is scene is of type MySceneClass
}
Been stumped on this for longer than anyone should.
This returns a CCScene:
[[[CCDirector sharedDirector] runningScene]
You want the Instance of that scene which is of type MySceneClass (MenuScene for me), but the easiest way to get that is to tag it:
// 'scene' is an autorelease object.
CCScene *scene = [CCScene node];
// 'layer' is an autorelease object.
MenuScene *layer = [MenuScene node];
layer.tag = kTagGameLayer;
// add layer as a child to scene
[scene addChild: layer];
// return the scene
return scene;
Then adjust your statement to use getChildByTag:
if([[[[CCDirector sharedDirector] runningScene] getChildByTag:kTagGameLayer] isKindOfClass:[MenuScene class]]) {
NSLog(#"current is MenuScene");
}
I am using cocos2d on my app. I am doing a transition to another scene using
[[CCDirector sharedDirector] replaceScene:
[CCTransitionFadeDown transitionWithDuration:0.5f scene:otherScene]];
On the init part of this other scene, a menu is being built, using CCMenu. This is a full screen menu.
My problem is this: the transition happens to a black screen and then the menu appears. In other words, the transition is being done before the menu is rendered, so, I see an ugly black screen for 0.5 seconds and then, after the transition is done, I see the menu.
To make things clear imagine the first scene has a picture of a boat and the second scene a picture of a car. What I have now is the boat transitioning to black and then the car pops. I need the boat transition to the car.
how do I do that? thanks.
NOTE: I have found this guy with the same problem, but I have tried that solution without success.
This is worth a try, if you are not already using it; it removes black flickers during scene loads. Run the following method before you switch scenes, in case it affects your issue (un-comment these lines and call the method directly):
- (void) removeStartupFlicker
{
//
// THIS CODE REMOVES THE STARTUP FLICKER
//
// Uncomment the following code if you Application only supports landscape mode
//
// CC_ENABLE_DEFAULT_GL_STATES();
// CCDirector *director = [CCDirector sharedDirector];
// CGSize size = [director winSize];
// CCSprite *sprite = [CCSprite spriteWithFile:#"Default.png"];
// sprite.position = ccp(size.width/2, size.height/2);
// sprite.rotation = -90;
// [sprite visit];
// [[director openGLView] swapBuffers];
// CC_ENABLE_DEFAULT_GL_STATES();
}
I have implemented a transition in my menu (same problem), call it 'fadeInView' by adding a black layer on top of everything in the init, with an opacity of 255, and in onEnter I run an action to fade the opacity to 0. as follows:
-(id) init {
self=[super init];
if(self){
// do your stuff
blackShroudLayer_=[CCLayerColor layerWithColor:ccc4(0, 0, 0, 255) width:K_SCREEN_WIDTH height:K_SCREEN_HEIGHT];
[self addChild:blackShroudLayer_ z:500];
}
return self;
}
-(void) onEnter{
// need to [super onEnter] first to that we are running
[super onEnter];
id sh = [CCFadeTo actionWithDuration:K_FADE_TIME opacity:0];
id seq = [CCSequence actions:sh,[CCCallFunc actionWithTarget:self selector:#selector(onUnshroudComplete)], nil];
[blackShroudLayer_ runAction:seq];
}
-(void) onUnshroudComplete{
[blackShroudLayer_ removeFromParentAndCleanup:YES];
}
the constants and blackShroudLayer_ are defined in the class .h file.
I have a CCSprite and a CCParticleSystemQuad that are both children of the CCLayer. In my update method, I set the emitter's position to that of the sprite, so it tracks the sprite around. The smoke puff fall out the bottom of the sprite like you'd expect and even though you move the sprite around, the smoke appears to be part of the background layer.
The problem come if I match up their rotations. Now, for example if my sprite is rocking back and forth, the puffs of smoke swing in an arc and appear attached to the sprite.
How can I make the puffs of smoke continue along the parent layer in a straight line and not rotate with the sprite? They don't translate with the sprite when I move it, so why do they rotate with it?
EDIT: adding code...
- (id)init
{
if (!(self = [super init])) return nil;
self.isTouchEnabled = YES;
CGSize screenSize = [[CCDirector sharedDirector] winSize];
sprite = [CCSprite spriteWithFile:#"Icon.png"]; // declared in the header
[sprite setPosition:ccp(screenSize.width/2, screenSize.height/2)];
[self addChild:sprite];
id repeatAction = [CCRepeatForever actionWithAction:
[CCSequence actions:
[CCRotateTo actionWithDuration:0.3f angle:-45.0f],
[CCRotateTo actionWithDuration:0.6f angle:45.0f],
[CCRotateTo actionWithDuration:0.3f angle:0.0f],
nil]];
[sprite runAction:repeatAction];
emitter = [[CCParticleSystemQuad particleWithFile:#"jetpack_smoke.plist"] retain]; // declared in the header - the particle was made in Particle Designer
[emitter setPosition:sprite.position];
[emitter setPositionType:kCCPositionTypeFree]; // ...Free and ...Relative seem to behave the same.
[emitter stopSystem];
[self addChild:emitter];
[self scheduleUpdate];
return self;
}
- (void)update:(ccTime)dt
{
[emitter setPosition:ccp(sprite.position.x, sprite.position.y-sprite.contentSize.height/2)];
[emitter setRotation:[sprite rotation]]; // if you comment this out, it works as expected.
}
// there are touches methods to just move the sprite to where the touch is, and to start the emitter when touches began and to stop it when touches end.
I found the answer on a different site - www.raywenderlich.com
I don't know why this is true, but it seems that CCParticleSystems don't like to be rotated while you move them around. They don't mind changing their angle property. Actually, there may be cases where you want that behavior.
Anyway I made a method that adjusts the emitter's angle property and it works fine. It takes your touch location and scales the y component to be the angle.
- (void)updateAngle:(CGPoint)location
{
float width = [[CCDirector sharedDirector] winSize].width;
float angle = location.x / width * 360.0f;
CCLOG(#"angle = %1.1f", angle);
[smoke_emitter setAngle:angle]; // I added both smoke and fire!
[fire_emitter setAngle:angle];
// [emitter setRotation:angle]; // this doesn't work
}
CCSprite's anchorPoint is {0.5f, 0.5f), while the emitter descends directly from CCNode, which has an anchorPoint of {0.0f, 0.0f}. Try setting the emitter's anchorPoint to match the CCSprite's.
i have game with cocos2d and method dealloc
i use this to change scene.
CGSize size = [[CCDirector sharedDirector] winSize];
CCMoveTo* move = [CCMoveTo actionWithDuration:1.0f position:CGPointMake(-(size.width), 0)];
CCEaseBackInOut* ease = [CCEaseBackInOut actionWithAction:move];
CCCallFunc* func = [CCCallFunc actionWithTarget:self selector:#selector(changeScene:)];
CCSequence* sequence = [CCSequence actions:ease, func, nil];
[self runAction:sequence];
or this in another scene.
CCScene* scene = [levelScene scene];
[userName removeFromSuperview];
CCTransitionFlipAngular *transitionScene=[CCTransitionFlipAngular transitionWithDuration:1 scene:scene];
[[CCDirector sharedDirector] replaceScene:transitionScene];
whene i changing scene the dealloc method doesn't do anything and onExit method too.
where i can releas my pointers ?or i have and constants wnat to equal to 0 when change scene.
whene i can do it?or why i can use dealloc.
dealloc is only called on an object when the memory management system determines that the object is no longer in use, when the retain count goes to zero. What are you doing to cause that to happen? I don't see any release or autorelease methods in your code samples.
You're going to have to be more specific about what you're doing to change scenes for a better answer.
I am doing as follows
-(void)Play {
[CCDirector setDirectorType:kCCDirectorTypeDisplayLink];
CCDirector *director = [CCDirector sharedDirector];
//[director setDeviceOrientation:kCCDeviceOrientationLandscapeLeft];
[director setAnimationInterval:1.0/60];
[director setDisplayFPS:NO];
CGRect rect = CGRectMake(0, 0, 320, 480);
EAGLView *glView = [EAGLView viewWithFrame:rect
pixelFormat:kEAGLColorFormatRGB565 // kEAGLColorFormatRGBA8
depthFormat:0 // GL_DEPTH_COMPONENT16_OES
];
[director setOpenGLView:glView];
[window addSubview:glView];
[window makeKeyAndVisible];
[director setDisplayFPS:YES];
[CCTexture2D setDefaultAlphaPixelFormat:kCCTexture2DPixelFormat_RGBA8888];
CCScene *scene = [CCScene node];
CCLayer *layer = [PongLayer node];
[scene addChild :layer];
[[CCDirector sharedDirector] runWithScene: scene];
}
After adding layer to scene, I can go and see screen of PongLayer, but now how to destroy its object when you come back on the main screen from where you start game
I did change layers, but previous layer is working on back end, like if I do put some NSLog that I can see that log yet in running conditions, so what to do?
because when I again call play method, then I don't want to refresh all my array and all data for new scene.
Cocos2d objects such as CCLayer and CCSprite are coded to be auto release objects.
You'll see that the 'node' method alloc's inits and autoreleases an object when it's created.
Methods such as 'spriteWithFile:' and 'layerWithColor:' also are coded with autoreleased.
When you add an object as a child to a Layer or any other node for that matter, it creates a pointer to the object, retaining it. When the object is removed as a child, it deallocates itself.
So, when you move from Scene to Scene, the scene that is removed, deallocates it's children (layers) and they in turn their children (sprites).
http://www.cocos2d-iphone.org/wiki/doku.php/start
The only exception is when you create a sprite like this..
CCSprite *mySprite = [CCSprite alloc] init];
You have personally allocated and initialized this sprite, you must release it.
If you have CCLog turned on, it logs out when CCSprites are deallocated.
Another small thing worth mentioning, Scene's won't deallocate themselves if you 'push' the scene, only popping and replacing scene's cause 1 to deallocate.