How to call CCButton on parent view from the child view - ios

In parent view, there's a CCButton called pausebutton, when click it, a child view will be added to this view
[[CCDirector sharedDirector] pause];
pausebutton.selected = YES;
pauseLayer *pauseLayer = [pauseLayer node];
[self addChild:pauseLayer];
in child view pauseLayer, also has a ccbutton called resumebutton, when click it, this child view will be removed from parent view, and both set the pausebutton's selected is NO.
- (void)backResume:(id)sender
{
[self.parent removeChild:self cleanup:YES];
[[CCDirector sharedDirector] resume];
}
but i can't find a way to call the pausebutton from child view, so can you help me?

On the parent class, add a method to force a pause :
in .h :
-(void) forcePause;
in .m :
-(void) onButton:(id) sender {
[self forcePause];
}
-(void) forcePause {
[[CCDirector sharedDirector] pause];
pauseLayer *pauseLayer = [pauseLayer node];
[self addChild:pauseLayer];
}
and in the child, when the condition to trigger a pause is met
[self.parent forcePause];
just the general idea, there are other ways to make this happen. This example would be for a very simple use-case/game. Alternately, in the parent you could be listening for a #"forcePause" notification and notify in the child.

Related

Cocos2d: How to stop clicking buttons of lower z order layer from upper z order layer?

I am developing a cocos2d game where I have a CCLayer named GamePlaylayer and another CCLayer named ShopLayer. ShopLayer is a fullscreen layer. GamePlayLayer is touchenabled and has multiple buttons (CCMenuItemImage). ShopLayer is accessed from a shop button which has the following #selector.
(void) onClickShop {
ShopLayer * shop = [[ShopLayer alloc] init];
[self addChild:shop z:40]; }
To stop touch propagation I used CCTouchOneByOneDelegate and the following methods in the ShopLayer.
(void) onEnter {
[[[CCDirector sharedDirector] touchDispatcher] addTargetedDelegate:self
priority:0 swallowsTouches:YES];
[super onEnter];
}
(void) onExit {
[[[CCDirector sharedDirector] touchDispatcher] removeDelegate:self];
[super onExit];
}
(BOOL) ccTouchBegan:(UITouch *)touch withEvent:(UIEvent *)event {
return YES;
}
Now it stops ccTouchesBegan of the GamePlayLayer to be called which is fine. But it cannot stop other buttons of the GamePlayLayer to be called. So when I touch at positions where the buttons of GamePlayLayer are placed, they get called even though I can not see them.
So my question is how to stop clicking buttons of lower layer from upper layer?
use kCCMenuHandlerPriority for the touch priority
[[[CCDirector sharedDirector] touchDispatcher] addTargetedDelegate:self priority:kCCMenuHandlerPriority swallowsTouches:YES];
SetTouch priority kCCMenuHandlerPriority of this class.

Can't handle touch on node Cocos2D

I am trying to figure out touch handling on multiple CCNodes .
I have
Main CCLayer
------> z:2 Hud CCNode
On main layer I choose an object, on hud layer I want to control it. I followed this q&a its very helpful Cocos2d handling touch with multiple layers
On Main Layer touch events, below is Hud Node work:
-(void) registerWithTouchDispatcher
{
[[CCDirector sharedDirector].touchDispatcher addTargetedDelegate:self priority:0 swallowsTouches:YES];
}
-(BOOL) ccTouchBegan:(UITouch*)touch withEvent:(UIEvent*)event
{
//detects touched Object and sends it to hud
if (object != nil)
{
//sends it to hud
return true;
}
return false;
}
-(void) ccTouchMoved:(UITouch*)touch withEvent:(UIEvent*)event
-(void) ccTouchEnded:(UITouch*)touch withEvent:(UIEvent*)event
-(void) ccTouchCancelled:(UITouch*)touch withEvent:(UIEvent*)event
On Hud CCNode none of ccTouchBegan/moved/ended methods are fired
-(void) registerWithTouchDispatcher
{
[[CCDirector sharedDirector].touchDispatcher addTargetedDelegate:self priority:0 swallowsTouches:YES];
}
-(BOOL) ccTouchBegan:(UITouch*)touch withEvent:(UIEvent*)event
{
if (object!=nil) {
NSLog(#"Touch began");
return YES;
}
else
return NO;
}
EDIT:
I have a button to set speed of the object on HUD Node , it has nothing to do with object!=nil because when I put breakpoints I see that -(BOOL) ccTouchBegan:(UITouch*)touch withEvent:(UIEvent*)event is never called
-(void)speed1Tapped:(id)sender
{
if (object!=nil) {
NSLog(#"Moving Object is %#:",object!=nil);
}
}
On Log I get:
object is <ObjectATC: 0x13763850>
Why ccTouchBegan/moved/ended methods are not fired in CCNode?
How can I handle touches on multiple CCNodes, CCLayers ?
I guess you dont receive touch method because you did not register the touchDipatcher
either in your CCNodes init method or onEnter method try to register it.
//register touches
- (void)onEnter {
[[[CCDirector sharedDirector] touchDispatcher] addTargetedDelegate:self priority:0 swallowsTouches:YES];
[super onEnter];
}
- (void)onExit {
[[[CCDirector sharedDirector] touchDispatcher]removeDelegate:self];
[super onExit];
}
In your touch methods, you have a conditional that says if (object != nil), but object is not defined anywhere in the code that you have shown. Is it defined elsewhere? Otherwise, this is why it is not firing.

Cocos2D blocked buttons after replceScene and removeAllDelegates

I have a serious problem with Cocos2d.
1) I have one scene with few buttons in it
2) I have another scene in which i use
-(void) onEnter {
[[[CCDirector sharedDirector] touchDispatcher] addTargetedDelegate:self priority:0 swallowTouches:YES];
[super onEnter];
}
and also
-(void) onExit {
[[[CCDirector sharedDirector] touchDispatcher] removeDelegate:self];
[super onExit];
}
3) After replacing 1st scene to the 2nd everything is ok
4) But after returing to 1st scene (by replaceScene) all buttons on 1st scene are blocked. Nothing works
5) If i'm not using "removeDelegate" in "onExit()" buttons on 1st scene work, but touches from the 2nd scene are still active.

Seguing from inside cocos2d programmatically

I'm a beginner at cocos2d, and I'm trying to perform a segue from inside cocos2d.
Currently I set up the following function:
-(void) return_mm {
NSLog(#"returned to main menu");
UIViewController * con = self.controller;
[con performSegueWithIdentifier:#"Game2MenuSegue" sender:con];
}
to ran whenever a CCMenuItem is pressed. This actually does indeed work once. However, when I segue back into the game scene, the menu button stops working.
To be more specific, the segue is called, and the preparetosegue function is ran, but no transition happens. The other view's viewWillAppear function never runs.
I'm probably doing something stupid, so if anyone has suggestions on doing this, it would be greatly appreciated.
This is what I currently have in the game view controller's willDidAppear function.
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
if ([[CCDirector sharedDirector] isPaused]) {
[[CCDirector sharedDirector] resume];
[mainView addSubview:[[CCDirector sharedDirector] openGLView]];
return;
}
EAGLView *glview = [EAGLView viewWithFrame:self.view.bounds
pixelFormat:kEAGLColorFormatRGB565 // kEAGLColorFormatRGBA8
depthFormat:0 // GL_DEPTH_COMPONENT16_OES
];
CCDirector *director = [CCDirector sharedDirector];
//[director setDisplayStats:kCCDirectorStatsFPS];
// Enables High Res mode (Retina Display) on iPhone 4 and maintains low res on all other devices
if( ! [director enableRetinaDisplay:YES] )
CCLOG(#"Retina Display Not supported");
[window makeKeyAndVisible];
[mainView addSubview:glview];
[director setOpenGLView:glview];
CCScene *scene = [CCScene node];
GameScene * gs =[GameScene sceneWithController:self];
[gs returnFromMenu];
[scene addChild:gs];
if (director.runningScene) {
[director replaceScene:scene];
} else {
[director runWithScene:scene];
}
}
I found the problem. I saved the controller on creation, but didn't update it when it segues back into the game view. The controller was outdated so the segue didn't do anything.
I just had to add
gs.controller = self
below the call to super

Where should I go from here? (Cocos2D+UIKit)

Currently I have this code in my UIViewController:
//Cocos2D methods
-(id) init {
if((self=[super init]))
{
CCScene *scene = [CCScene node];
CCLayer *layer = [CCLayer node];
[scene addChild:layer];
[[CCDirector sharedDirector] runWithScene:scene];
[[CCDirector sharedDirector] setDisplayFPS:NO];
[self performSelector:#selector(cocosgameLoop:) withObject:nil afterDelay:1/60.0f];
}
return self;
}
- (void)cocosgameLoop:(ccTime)dT {
//Check for collisions here and add gravity, etc....
}
- (void)viewDidUnload {
[super viewDidUnload];
[[CCDirector sharedDirector] end];
}
//
My view controller is somewhat Objective-C code, but I want to add Cocos2D to the UIView. I think the code above is initializing it, but I am not sure. Also should the CCScene have its own class dedicated to everything that goes on in the scene? if so how would I do that?
I know these are a lot of questions, but my game is very similar to Doodle Jump and I need to know where to go from the current state I am in.
Does anyone have any ideas/tips?
Thanks!
performSelector will call the cocosgameLoop only once. You will want to call CCDirector startAnimation, and then schedule updates in your cocos2d nodes.
My Learn Cocos2D book (2nd Edition) explains how to add and setup Cocos2D in a UIKit view (regular iPhone) app.

Resources