when app back to background i have at the delegate this :
if( [navController_ visibleViewController] == director_ )
[director_ resume];
Now if i was at ccscene 2 when i have entered to background, when i am back, it goes to scene2.
I want to define the home scene, that each time we comes from background we go there from the delegate .
How would i do that ?
Related
Cocos2d-android - I have an animation which has 5 Frames. which will rolling in position. how to make the button rolling like a globe.
I don't know if it can be done like menuitem, but you can make a sprite with forever action(animation of yours 5 frames)and in ccTouchesBegan/ccTouchesEnded you add code to go to another scene or for do an another function after touching on your sprite.
`private CCSprite animatedButton; // Make your sprite visible at begin of your class/layer.`
`animatedButton = CCSprite.sprite("yourImage.png");
CCAnimation buttonAnimation = CCAnimation.animation("", 1f);
buttonAnimation.addFrame("1.png");
buttonAnimation.addFrame("2.png");
addChild(animatedButton, 1);
CCIntervalAction buttonAction = CCAnimate.action(duration, buttonAnimation, false);
animatedButton.runAction(CCRepeatForever.action(buttonAction));
`
Now should be your button(CCSprite) animating. I didnt tried code. And now you just find out in ccTouchesBegan or ccTouchesEnded if your button was touched. If yes, you could do what you want. :)
`if(animatedButton.getBoundingBox.contains(x,y)){
CCScene scene = GameLayer.scene();
CCDirector.sharedDirector().replaceScene(scene);
}`
X and y are coordinates of touch;
You can add animations to menuitem. Like this
CCMenuItem button=CCMenuItemImage.item(image, image, this, "label");
button.setScaleX((winSize.width/8.0f)/image.getTexture().getWidth());
button.setScaleY((winSize.height/8.0f)/image.getTexture().getHeight());
button.setPosition(winSize.width/2,winSize.height+50);
CCAction actionMove42=CCSequence.actions(CCDelayTime.action(0.3f), CCEaseBackOut.action(CCMoveTo.action(1.0f, CGPoint.ccp(0,0))));
button.runAction(actionMove42);
I have my main scene, above it i set a new layer with CCLayer ,this layer has a button.
but when i hit that button (CCMenu), the layer behind it is also get the touches and do stuff.
I want to enable ONLY the upper layer touches, not the one under it .
How can i do that ? (setting touch priority ? how ? )
edit:
my layer is like that :
-(CCLayer*)showHelpLayer
{
self.isTouchEnabled=YES;
[[CCDirector sharedDirector].touchDispatcher addTargetedDelegate:self priority:-256 swallowsTouches:YES];
...
...
[self addChild:menu];
[menu setHandlerPriority:-257];
return self;
}
and i am adding it to the main scene like that :
helpLayer *hlp=[[helpLayer alloc]init];
[hlp showHelpLayer];
[self addChild:hlp z:100];
you could toy with priorities, but it gets nasty. I only do that in very very specific, well contained circumstances. The best approach is to disable input on your "underneath scene(s)" before you push the new layer and control objects.
If you chose to play with priorities, remember that all menus default to this priority (cocos2D 2.xx) :
kCCMenuHandlerPriority = -128,
so if you play with priority, i would put the layer at -256 (swallowing touches) and setHandlerPriority to -257 for your menu. So anything that falls through your menu is caught by the layer and swallowed (ie not passed 'below').
example for priority approach. The fly-through menu is a class that extends CCNode and does this onEnter, after creating all menu objects in the init method :
- (void)onEnter {
[super onEnter];
MPLOGDEBUG(#"");
[[CCDirector sharedDirector].touchDispatcher addTargetedDelegate:self priority:-256 swallowsTouches:YES];
[_backMenu setHandlerPriority:-257];
[_toggleOptionsMenu setHandlerPriority:-257];
[_dialogMenu setHandlerPriority:-257];
[_labelMenu setHandlerPriority:-257];
}
I know how to detect contact on all of my sprites that on screen .
I also know how to run animation forever on a sprite .
But when puting together the code for animation, with sprite sheet- you dont actually add the sprite as a child, but ONLY the sprite-sheet, than the sprite is a child of the sprite-sheet.
[[CCSpriteFrameCache sharedSpriteFrameCache] addSpriteFramesWithFile:#"parrot.plist"];
CCSpriteBatchNode *spriteSheet = [ CCSpriteBatchNode batchNodeWithFile:#"parrot.png"];
fireBall=[CCSprite spriteWithSpriteFrameName:#"parrot1.png"];
fireBall.position=point;
[spriteSheet addChild:fireBall];
[self addChild:spriteSheet];
//here animation action perform on fireBall
In that case when looking for the fireBall for contact detection - you cant find him because he is not added as a child of the scene ,but of the sprite sheet.
How can i detect that sprite later on my code ? or there is another constellation to set the sprite sheet ?
thanks
You can get your fireBall sprite normally, like any other sprite...
There's some ways:
1) Create a property for your fireBall sprite:
#property (nonatomic, retain) CCSprite *fireBall;
And create and use it using self.fireball:
self.fireBall=[CCSprite spriteWithSpriteFrameName:#"parrot1.png"];
...
CGPoint fireBallPosition = self.fireBall.position;
2) Add fireBall as child on spriteSheet using tag, and get it back using the same tag.
[spriteSheet addChild:fireBall z:0 tag:1];
...
theFireBall = [spriteSheet getChildByTag:1];
But keep in mind that the fireBall position is relative of their parent, spriteSheet. So, if you move spriteSheet, you will also move spriteSheet.
-(void) redafter1
{
red = [CCMenuItemImage
itemFromNormalImage:#"red.png" selectedImage:#"redclick.png"];
red.position = ccp(175, 725);
redMenu = [CCMenu menuWithItems:red, nil];
redMenu.position = CGPointZero;
redMenu.scale = .75;
[self addChild:redMenu z:10];
}
How would I go about animating this object to move to another location on the screen? I am very new to this, please be basic in your explanation.
If you want to animate CCNode (this is base class of all cocos2d objects such as layers, sprites, labels, menuitems, etc.), you have to use actions mechanism. To move object, use CCMoveTo, CCMoveBy actions with runAction: method.
id moveAction = [CCMoveTo actionWithDuration: animationDuration position: targetPosition];
[nodeToAnimate runAction: moveAction];
In your case if you will run action on the object right after adding it to the some parent, that is visible (your scene or other visible parent), action will be started right after object appear.
You add [redMenu runAction:[CCMoveTo actionWithDuration:time position:place]]; (you choose time and position) at the end of your redafter1 function so when the parent method is eventually called by a method such as init your menu will move.Remember you cannot move a CCMenuItemImage because it's locked to the CCMenu's position. You have to move the CCMenu itself.Hope this was helpful.
I initialize my CCLayer using the following init code:
- (id)init {
if((self=[super init])) {
UIImagePickerController *picker = [[UIImagePickerController alloc] init];
picker.delegate = self;
picker.sourceType = UIImagePickerControllerSourceTypeCamera;
picker.wantsFullScreenLayout = YES;
picker.allowsEditing = NO;
picker.showsCameraControls = NO;
picker.navigationBarHidden = YES;
picker.toolbarHidden = YES;
picker.cameraViewTransform= CGAffineTransformMakeScale(1.3, 1.33);
[[[CCDirector sharedDirector] openGLView] addSubview:picker.view];
CCSprite *gold = [CCSprite sprite];
gold.position = ccp(150, 150);
[self addChild:gold];
}
return self;
}
The CCSprite was above the camera view before the camera shutter opens, but when the shutter opens, the CCSprite is overlapped by the camera.
Can I rearrange the order of these 2 objects / put the camera view to the back ?
Not without some extra work.
To understand this you have to consider that you're adding the camera view to the openGLView by Cocos2D. This makes the camera view a "child" view of the Cocos2D view. This is similar to adding a child node to a CCScene or CCLayer, and then wanting to have that node drawn behind the scene or layer. You can't do this without changing the way the view hierarchy is setup.
So you will have to modify Cocos2D's startup so that the openGLView is not added to the UIWindow directly, but to another UIView.
UIView* dummyView = [[UIView alloc] initWithFrame:[window bounds]];
[dummyView autorelease];
[dummyView addSubview:[CCDirector sharedDirector].openGLView];
rootViewController.view = dummyView;
You can then add the camera view to the dummyView (not the openGLView or you'll have the same problem as before) and perform sendSubviewToBack on it so that it is in the background.
You will also have to initialize the OpenGL view of Cocos2D with kEAGLColorFormatRGBA8 pixelFormat in order to provide an alpha channel.
EAGLView* glView = [EAGLView viewWithFrame:[window bounds]
pixelFormat:kEAGLColorFormatRGBA8
depthFormat:0
preserveBackbuffer:NO
sharegroup:nil
multiSampling:NO
numberOfSamples:0];
You also need to make the openGLView transparent:
[CCDirector sharedDirector].openGLView.opaque = NO;
Of course this only works if you don't render anything fullscreen on the cocos2d view. For example, if you provide a fullscreen background image for your Cocos2D view, nothing will show up because the background image is rendered on top of the camera view.
You can find a more detailed explanation in the second edition of my book. You can also download the book's source code from that link and see the examples of chapter 15. Or download Kobold2D and use the provided Cocos2D-With-UIKit-Views template project.