user2380984
user2380984

Reputation: 17

CCMenuItem independent from gesture recognicers view cocos 2D

I have a CClayer class, called GridLayer I add the gesture recognizers (Pan ,Pinch and Rotate) to the view and it works fine, but if i add a CCMenuItem is paste to the view so is affected by the rotate and pinch gestures , my question is who implement a independent CCMenuitem from the View Size ,Scale and position.

//Adding Rotation Recognicer onEnter Method
    self.rotationRecognicer =[[[UIRotationGestureRecognizer alloc]initWithTarget:self
                                                                          action:@selector(rotate:)]autorelease];
        [[[CCDirector sharedDirector] view] addGestureRecognizer:_rotationRecognicer];

//Adding CCMenuItem On Init Method  
        CCMenuItem *starMenuItem = [CCMenuItemImage
                                        itemWithNormalImage:@"ButtonStar.png"
                                        selectedImage:@"ButtonStarSel.png"
                                        target:self
                                    selector:@selector(starButtonTapped:)];

    starMenuItem.position = ccp(60, 60);
    CCMenu *starMenu = [CCMenu menuWithItems:starMenuItem, nil];
    starMenu.position = CGPointZero;
    [self addChild:starMenu];



//Rotation Method
- (void)rotate:(UIRotationGestureRecognizer *)gestureRecognizer
{

    [self adjustAnchorPointForGestureRecognizer:gestureRecognizer];

    if ([gestureRecognizer state] == UIGestureRecognizerStateBegan || [gestureRecognizer state] == UIGestureRecognizerStateChanged) {
        [gestureRecognizer view].transform = CGAffineTransformRotate([[gestureRecognizer view] transform], [gestureRecognizer rotation]);
        [gestureRecognizer setRotation:0];
    }


}

Upvotes: 1

Views: 214

Answers (2)

user2380984
user2380984

Reputation: 17

This approximation is based on the following example

http://www.raywenderlich.com/4817/how-to-integrate-cocos2d-and-uikit

Creating a UIViewController called RootViewControler that contain all the controls needed and adding like subview the [[CCDirector sharedDirector] view] with the gridLayer

//RootViewcontroler viewDidLoad Method:
    [self.view insertSubview:[[CCDirector sharedDirector] view] atIndex:0];
    CCScene *scene = [GridLayer scene];
    [[CCDirector sharedDirector ]runWithScene: scene];

In the Appdelegate add the RootViewControler instance to the Navigation Controler

RootViewControler *rootViewcontroler =[[[RootViewControler alloc] initWithNibName:nil bundle:nil] autorelease];

// Create a Navigation Controller 
    navController_ = [[UINavigationController alloc] initWithRootViewController:rootViewcontroler];

Sure is not the unique posible solution, but for me works.

Upvotes: 0

Paul Renton
Paul Renton

Reputation: 2670

Your GUI controls need to exist on their own independent layer.

To accomplish this, you should add two separate layers to your CCScene container, or whatever is the parent node of your layer. This may look something like the following

@implementation SceneNode

@synthesize actionLayer;

-(id)init {

    self = [super init];

    if (self != nil) {

        UILayer * uiLayer = [UILayer node];

        self.actionLayer = [[ActionLayer alloc] initWithSceneUILayer:uiLayer];

        [self addChild:uiLayer z:UI_LAYER_Z_VALUE];
        [self addChild:actionLayer z:ACTION_LAYER_Z_VALUE];

    } // end if

    return self;


} // end init

@end

The tricky part is getting them to communicate without creating a tight coupling between the classes. It is likely you will want the action layer (your grid layer) to be informed when a control is interacted with on your GUI layer. This is where you will want to implement either the Command Design Pattern and or use Objective-C protocols with a delegate.

If you decide to use a protocol and delegate, it may look like the following

// In a header file
@protocol ControlsProtocols

-(void)fireButtonEvent;

-(void)angleSelectionEvent;

-(void)powerSelectionEvent:(int)powerRec;

@end

Create a delegate member data variable in the UILayer class

@interface ILayer : CCLayer {

    CCMenu * ControlsMenu;
    id <ControlsProtocols> delegate;

} // end ivar

@property (nonatomic, strong) id <ControlsProtocols> delegate;

@end

In your action layer (Grid Layer), which initializes with a pointer to the UILayer, assign itself as the delegate for the UILayer.

-(id)initWithSceneUILayer:(UILayer *)uiLayer {

    self = [super init];

    if (self != nil) {

        // Store reference to UILayer and set UILayer delegate to self
        UILayer = uiLayer;
        uiLayer.delegate = self;

        // More logic here

    } // end if 

    return self;

} // end init

Lastly, be sure to implement the protocol methods in the Action Layer (grid layer) class and move the gesture recognition to this layer. My guess is that you only want the action layer to be manipulated when certain gestures occur, not the view which houses your scene and layers. Add logic to capture the gestures in your Action Layer and only manipulate this layer's appearance instead of the entire view.

Upvotes: 0

Related Questions