2011-04-11 3 views
7

У меня есть радиоклюбы, но прикосновение к малым. Прикосновение зависит от размера изображения. Есть ли элегантный способ расширить зону касания с помощью cocos2d без использования большего изображения или создать собственные сенсорные области с помощью cgrect? комплектContentSize делаю, что я хочу. К сожалению, изображение перемещается в левый нижний угол содержимого. Установите опорную точку для перемещения содержимого, но изображение остается в левом нижнем углу.cocos2d удлиняет зону касания от кнопки

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)]; 

Заранее спасибо.

ответ

2

Вам необходимо переопределить метод rectInPixels

- (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; 
} 

Это просто говорит спрайт, чтобы проверить, что сенсорные щелок в вашей измененном CGRect

Редактировать, чтобы показать CCSprite подкласс ---

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

- (void)onExit 
{ 
[[CCTouchDispatcher sharedDispatcher] removeDelegate:self]; 
[super onExit]; 
} 
+0

Спасибо за ваш ответ. Я не знаю, где переопределить rectInPixels. После использования ccnode, ccsprite, ccmenu, ccmenuitem и моего собственного класса, я нашел обходное решение, которое работает для меня. – zeiteisen

+0

его простой ccsprite переопределить, но вы должны добавить класс в CCTouchDispatcher. См. Мой отредактированный ответ – Bongeh

2

Я сделал обходное решение, переопределив -(CCMenuItem*) itemForTouch:(UITouch *)touch от 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; 
} 

Центр Прямоугольник в середине изображения работала техника его подводит

11

Принимая исходный код ответа ...

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)]; 

... вы только установить изображение в правильном положение ...

[[[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)]; 

... только с 4 строками кода! Повеселись!

+0

Genius! Это работало идеально для меня. Я не мог заставить подклассы работать правильно, так что это хороший хак. Благодаря тонну. – Arbel

+0

Гений не оправдывает это, на мой взгляд, идеальное решение. +1 спасибо за обмен. –

4

Кроме того, вы можете изменить свойство activeArea CCMenuItem. (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]; 
+0

Поскольку «activeArea» является стандартным, я думаю, что это решение правильно. Если вы используете старые версии, см. Сообщение Sébastien Dabet (http://2sa-studio.blogspot.kr/2013/01/custom-touch-area-for-ccmenuitem-in.html) и исправить ваш cocos2d вручную. – Dalinaum

+0

Хорошо, я решаю ту же проблему, что и ваш вышеприведенный код. –

+0

Возможно ли это в Cocos2dx? Не удалось его найти. – Anil