Cocos2d increases the touch zone from the button

I have radio beads, but toucharea is small. Touch depends on image size. Is there an elegant way to expand the touch zone with cocos2d without using a larger image or create your own touch areas with cgrect? setContentSize to do what I want. Unfortunately, the image moves to the lower left corner of the content. Set the anchor point by moving the contents, but the image remains in the lower left corner.

CCMenuItem* pickEasy = [CCMenuItemImage itemFromNormalImage:@"radiobutton_off.png" selectedImage:@"radiobutton_on.png" target:self selector:@selector(pickEasyTapped:)]; pickEasy.position = ccp(ss.width * 0.40, ss.height * 0.78); [pickEasy setContentSize:CGSizeMake(50, 50)]; 

Thanks in advance.

+7
source share
4 answers

You need to override the rectInPixels method

 - (CGRect)rectInPixels { CGSize s = [self contentSize]; return CGRectMake(0, 0, s.width, s.height); } - (BOOL)containsTouchLocation:(UITouch *)touch { CGPoint p = [self convertTouchToNodeSpace:touch]; CGRect r = [self rectInPixels]; return CGRectContainsPoint(r, p); } - (BOOL)ccTouchBegan:(UITouch *)touch withEvent:(UIEvent *)event { NSSet *allTouches = [event allTouches]; for (UITouch *aTouch in allTouches) { if ( ![self containsTouchLocation:aTouch] ) return NO; } return YES; } 

It just tells the sprite to verify that the touch keys in your modified CGRect

Edit to show CCSprite subclass ---

 - (void)onEnter { [[CCTouchDispatcher sharedDispatcher] addTargetedDelegate:self priority:0 swallowsTouches:YES]; [super onEnter]; } - (void)onExit { [[CCTouchDispatcher sharedDispatcher] removeDelegate:self]; [super onExit]; } 
+2
source

Taking response source code ...

 CCMenuItem* pickEasy = [CCMenuItemImage itemFromNormalImage:@"radiobutton_off.png" selectedImage:@"radiobutton_on.png" target:self selector:@selector(pickEasyTapped:)]; pickEasy.position = ccp(ss.width * 0.40, ss.height * 0.78); [pickEasy setContentSize:CGSizeMake(50, 50)]; 

... you only need to set the image in the correct position ...

 [[[pickEasy children] objectAtIndex:0] setAnchorPoint:ccp(0.5,0.5)]; [[[pickEasy children] objectAtIndex:1] setAnchorPoint:ccp(0.5,0.5)]; [[[pickEasy children] objectAtIndex:0] setPosition:ccp(pickEasy.contentSize.width/2,pickEasy.contentSize.height/2)]; [[[pickEasy children] objectAtIndex:1] setPosition:ccp(pickEasy.contentSize.width/2,pickEasy.contentSize.height/2)]; 

... with only 4 lines of code! Enjoy!

+11
source

Alternatively, you can change the activeArea CCMenuItem property. (cocos2d 2.x)

 CGRect active = [someMenuItem activeArea]; [someMenuItem setActiveArea:CGRectMake(active.origin.x - active.size.width * 2.f, active.origin.y - active.size.height * 2.5f, active.size.width * 2.f, active.size.height * 2.f)]; [someMenu addChild:someMenuItem]; 
+4
source

I made a workaround by overriding -(CCMenuItem*) itemForTouch:(UITouch *)touch from CCMenu.

  - (CCMenuItem *) itemForTouch: (UITouch *) touch
 {
     CGPoint touchLocation = [touch locationInView: [touch view]];
     touchLocation = [[CCDirector sharedDirector] convertToGL: touchLocation];
     CCMenuItem * item;
     CCARRAY_FOREACH (children_, item) 
     {
         if ([item visible] && [item isEnabled]) {
             CGPoint local = [item convertToNodeSpace: touchLocation];
             CGRect r = [item rect];
             r.origin = CGPointZero;
             // increase rect by * 2
             // a rect at bottom left of the image
             CGRect bigR = CGRectMake (r.origin.x - r.size.width, r.origin.y - r.size.height, r.size.width * 2, r.size.width * 2);
             // a rect at top right of the image
             CGRect bigR2 = CGRectMake (0, 0, r.size.width * 2, r.size.width * 2);
             if (CGRectContainsPoint (bigR, local) || CGRectContainsPoint (bigR2, local)) {
                 return item;
             }
         }
     }
     return nil;
 }

Center the rectangle in the middle of the image did not work

+2
source

All Articles